• 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