Home | History | Annotate | Download | only in result
      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 
     43     public MultipartForm(String serverUrl) {
     44         mServerUrl = serverUrl;
     45     }
     46 
     47     public MultipartForm addFormValue(String name, String value) {
     48         mFormValues.put(name, value);
     49         return this;
     50     }
     51 
     52     public MultipartForm addFormFile(String name, String fileName, byte[] data) {
     53         mName = name;
     54         mFileName = fileName;
     55         mData = data;
     56         return this;
     57     }
     58 
     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      */
     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 
    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 
    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 
    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