• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.cts.tradefed.result;
18 
19 import java.io.ByteArrayOutputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.io.OutputStreamWriter;
24 import java.io.PrintWriter;
25 import java.net.HttpURLConnection;
26 import java.net.URL;
27 import java.util.HashMap;
28 import java.util.Map;
29 
30 /** MultipartForm builds a multipart form and submits it. */
31 class MultipartForm {
32 
33     private static final String FORM_DATA_BOUNDARY = "C75I55u3R3p0r73r";
34 
35     private final String mServerUrl;
36 
37     private final Map<String, String> mFormValues = new HashMap<String, String>();
38 
39     private String mName;
40     private String mFileName;
41     private byte[] mData;
42 
MultipartForm(String serverUrl)43     public MultipartForm(String serverUrl) {
44         mServerUrl = serverUrl;
45     }
46 
addFormValue(String name, String value)47     public MultipartForm addFormValue(String name, String value) {
48         mFormValues.put(name, value);
49         return this;
50     }
51 
addFormFile(String name, String fileName, byte[] data)52     public MultipartForm addFormFile(String name, String fileName, byte[] data) {
53         mName = name;
54         mFileName = fileName;
55         mData = data;
56         return this;
57     }
58 
submit()59     public void submit() throws IOException {
60         String redirectUrl = submitForm(mServerUrl);
61         if (redirectUrl != null) {
62             submitForm(redirectUrl);
63         }
64     }
65 
66     /**
67      * @param serverUrl to post the data to
68      * @return a url if the server redirected to another url
69      * @throws IOException
70      */
submitForm(String serverUrl)71     private String submitForm(String serverUrl) throws IOException {
72         HttpURLConnection connection = null;
73         try {
74             URL url = new URL(serverUrl);
75             connection = (HttpURLConnection) url.openConnection();
76             connection.setInstanceFollowRedirects(false);
77             connection.setRequestMethod("POST");
78             connection.setDoOutput(true);
79             connection.setRequestProperty("Content-Type",
80                     "multipart/form-data; boundary=" + FORM_DATA_BOUNDARY);
81 
82             byte[] body = getContentBody();
83             connection.setRequestProperty("Content-Length", Integer.toString(body.length));
84 
85             OutputStream output = connection.getOutputStream();
86             try {
87                 output.write(body);
88             } finally {
89                 output.close();
90             }
91 
92             // Open the stream to get a response. Otherwise request will be cancelled.
93             InputStream input = connection.getInputStream();
94             input.close();
95 
96             if (connection.getResponseCode() == 302) {
97                 return connection.getHeaderField("Location");
98             }
99         } finally {
100             if (connection != null) {
101                 connection.disconnect();
102             }
103         }
104 
105         return null;
106     }
107 
getContentBody()108     private byte[] getContentBody() throws IOException {
109         ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
110         PrintWriter writer = new PrintWriter(new OutputStreamWriter(byteOutput));
111         writer.println();
112 
113         for (Map.Entry<String, String> formValue : mFormValues.entrySet()) {
114             writeFormField(writer, formValue.getKey(), formValue.getValue());
115         }
116 
117         if (mData != null) {
118             writeFormFileHeader(writer, mName, mFileName);
119             writer.flush(); // Must flush here before writing to the byte stream!
120             byteOutput.write(mData);
121             writer.println();
122         }
123         writer.append("--").append(FORM_DATA_BOUNDARY).println("--");
124         writer.flush();
125         writer.close();
126         return byteOutput.toByteArray();
127     }
128 
writeFormField(PrintWriter writer, String name, String value)129     private void writeFormField(PrintWriter writer, String name, String value) {
130         writer.append("--").println(FORM_DATA_BOUNDARY);
131         writer.append("Content-Disposition: form-data; name=\"").append(name).println("\"");
132         writer.println();
133         writer.println(value);
134     }
135 
writeFormFileHeader(PrintWriter writer, String name, String fileName)136     private void writeFormFileHeader(PrintWriter writer, String name, String fileName) {
137         writer.append("--").println(FORM_DATA_BOUNDARY);
138         writer.append("Content-Disposition: form-data; name=\"").append(name);
139         writer.append("\"; filename=\"").append(fileName).println("\"");
140         writer.println("Content-Type: application/x-gzip");
141         writer.println("Content-Transfer-Encoding: binary");
142         writer.println();
143     }
144 }
145