Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2012 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 package com.android.tradefed.util.net;
     17 
     18 import com.android.tradefed.util.StreamUtil;
     19 import com.android.tradefed.util.net.IHttpHelper.DataSizeException;
     20 
     21 import java.io.File;
     22 import java.io.FileInputStream;
     23 import java.io.IOException;
     24 import java.io.InputStream;
     25 
     26 /**
     27  * Helper class for making multipart HTTP post requests. This class is used to upload files
     28  * using multipart HTTP post (RFC 2388).
     29  *
     30  * To send multipart posts create this object passing it the url to send the requests to.
     31  * Then set necessary parameters using the addParameter method and specify a file to upload
     32  * using addFile method. After everything is set, send the request using the send method.
     33  *
     34  * Currently the implementation only supports 'text/plain' content types.
     35  */
     36 public class HttpMultipartPost {
     37 
     38     private static final String CONTENT_TYPE = "text/plain";
     39     private static final String BOUNDARY = "xXxXx";
     40     private static final String HYPHENS = "--";
     41     private static final String CRLF = "\r\n";
     42 
     43     private StringBuilder mBuilder;
     44     private String mUrl;
     45     private IHttpHelper mHelper;
     46 
     47     public HttpMultipartPost(String url, IHttpHelper httpHelper) {
     48         mBuilder = new StringBuilder();
     49         mUrl = url;
     50         mHelper = httpHelper;
     51     }
     52 
     53     public HttpMultipartPost(String url) {
     54         this(url, new HttpHelper());
     55     }
     56 
     57     /**
     58      * Adds a string parameter to the request.
     59      * @param name name of the parameter.
     60      * @param value value of the parameter.
     61      * @throws IOException
     62      */
     63     public void addParameter(String name, String value) throws IOException {
     64         mBuilder.append(HYPHENS + BOUNDARY + CRLF);
     65         mBuilder.append(String.format(
     66                 "Content-Disposition: form-data; name=\"%s\"%s%s", name, CRLF,
     67                 CRLF));
     68         mBuilder.append(value);
     69         mBuilder.append(CRLF);
     70     }
     71 
     72     /**
     73      * Add a file parameter to the request. Opens the file, reads its contents
     74      * and sends them as part of the request. Currently the implementation
     75      * only supports 'text/plain' content type.
     76      * @param name name of the parameter.
     77      * @param file file whose contents will be uploaded as part of the request.
     78      * @throws IOException
     79      */
     80     public void addTextFile(String name, File file) throws IOException {
     81         FileInputStream in = new FileInputStream(file);
     82         String fileName = file.getAbsolutePath();
     83 
     84         addTextFile(name, fileName, in);
     85 
     86         in.close();
     87     }
     88 
     89     /**
     90      * Add a file parameter to the request. The contents of the file to upload
     91      * will come from reading the input stream. Currently the implementation only
     92      * supports 'text/plain' content type.
     93      * @param name name of the parameter.
     94      * @param fileName file name to report for the data in the stream.
     95      * @param in stream whose contents are being uploaded.
     96      * @throws IOException
     97      */
     98     public void addTextFile(String name, String fileName, InputStream in)
     99             throws IOException {
    100 
    101         mBuilder.append(HYPHENS + BOUNDARY + CRLF);
    102         mBuilder.append(String.format(
    103                 "Content-Disposition: form-data; name=\"%s\";filename=\"%s\"%s",
    104                 name, fileName, CRLF));
    105         mBuilder.append(String.format("Content-Type: %s%s", CONTENT_TYPE, CRLF));
    106         mBuilder.append(CRLF);
    107 
    108         mBuilder.append(StreamUtil.getStringFromStream(in));
    109 
    110         mBuilder.append(CRLF);
    111     }
    112 
    113     /**
    114      * Sends the request to the server.
    115      * @throws IOException
    116      * @throws DataSizeException
    117      */
    118     public void send() throws IOException, DataSizeException {
    119         mBuilder.append(HYPHENS + BOUNDARY + HYPHENS);
    120         mBuilder.append(CRLF + CRLF);
    121         mHelper.doPostWithRetry(mUrl, mBuilder.toString(),
    122                 "multipart/form-data;boundary=" + BOUNDARY);
    123     }
    124 }
    125