Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2010 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.quicksearchbox.util;
     18 
     19 import android.os.Build;
     20 import android.util.Log;
     21 
     22 import java.io.BufferedReader;
     23 import java.io.IOException;
     24 import java.io.InputStreamReader;
     25 import java.io.OutputStreamWriter;
     26 import java.net.HttpURLConnection;
     27 import java.net.URL;
     28 import java.util.HashMap;
     29 import java.util.Map;
     30 
     31 /**
     32  * Simple HTTP client API.
     33  */
     34 public class JavaNetHttpHelper implements HttpHelper {
     35     private static final String TAG = "QSB.JavaNetHttpHelper";
     36     private static final boolean DBG = false;
     37 
     38     private static final int BUFFER_SIZE = 1024 * 4;
     39     private static final String USER_AGENT_HEADER = "User-Agent";
     40     private static final String DEFAULT_CHARSET = "UTF-8";
     41 
     42     private int mConnectTimeout;
     43     private int mReadTimeout;
     44     private final String mUserAgent;
     45     private final HttpHelper.UrlRewriter mRewriter;
     46 
     47     /**
     48      * Creates a new HTTP helper.
     49      *
     50      * @param rewriter URI rewriter
     51      * @param userAgent User agent string, e.g. "MyApp/1.0".
     52      */
     53     public JavaNetHttpHelper(UrlRewriter rewriter, String userAgent) {
     54         mUserAgent = userAgent + " (" + Build.DEVICE + " " + Build.ID + ")";
     55         mRewriter = rewriter;
     56     }
     57 
     58     /**
     59      * Executes a GET request and returns the response content.
     60      *
     61      * @param request Request.
     62      * @return The response content. This is the empty string if the response
     63      *         contained no content.
     64      * @throws IOException If an IO error occurs.
     65      * @throws HttpException If the response has a status code other than 200.
     66      */
     67     public String get(GetRequest request) throws IOException, HttpException {
     68         return get(request.getUrl(), request.getHeaders());
     69     }
     70 
     71     /**
     72      * Executes a GET request and returns the response content.
     73      *
     74      * @param url Request URI.
     75      * @param requestHeaders Request headers.
     76      * @return The response content. This is the empty string if the response
     77      *         contained no content.
     78      * @throws IOException If an IO error occurs.
     79      * @throws HttpException If the response has a status code other than 200.
     80      */
     81     public String get(String url, Map<String,String> requestHeaders)
     82             throws IOException, HttpException {
     83         HttpURLConnection c = null;
     84         try {
     85             c = createConnection(url, requestHeaders);
     86             c.setRequestMethod("GET");
     87             c.connect();
     88             return getResponseFrom(c);
     89         } finally {
     90             if (c != null) {
     91                 c.disconnect();
     92             }
     93         }
     94     }
     95 
     96     @Override
     97     public String post(PostRequest request) throws IOException, HttpException {
     98         return post(request.getUrl(), request.getHeaders(), request.getContent());
     99     }
    100 
    101     public String post(String url, Map<String,String> requestHeaders, String content)
    102             throws IOException, HttpException {
    103         HttpURLConnection c = null;
    104         try {
    105             if (requestHeaders == null) {
    106                 requestHeaders = new HashMap<String, String>();
    107             }
    108             requestHeaders.put("Content-Length",
    109                     Integer.toString(content == null ? 0 : content.length()));
    110             c = createConnection(url, requestHeaders);
    111             c.setDoOutput(content != null);
    112             c.setRequestMethod("POST");
    113             c.connect();
    114             if (content != null) {
    115                 OutputStreamWriter writer = new OutputStreamWriter(c.getOutputStream());
    116                 writer.write(content);
    117                 writer.close();
    118             }
    119             return getResponseFrom(c);
    120         } finally {
    121             if (c != null) {
    122                 c.disconnect();
    123             }
    124         }
    125     }
    126 
    127     private HttpURLConnection createConnection(String url, Map<String, String> headers)
    128             throws IOException, HttpException {
    129         URL u = new URL(mRewriter.rewrite(url));
    130         if (DBG) Log.d(TAG, "URL=" + url + " rewritten='" + u + "'");
    131         HttpURLConnection c = (HttpURLConnection) u.openConnection();
    132         if (headers != null) {
    133             for (Map.Entry<String,String> e : headers.entrySet()) {
    134                 String name = e.getKey();
    135                 String value = e.getValue();
    136                 if (DBG) Log.d(TAG, "  " + name + ": " + value);
    137                 c.addRequestProperty(name, value);
    138             }
    139         }
    140         c.addRequestProperty(USER_AGENT_HEADER, mUserAgent);
    141         if (mConnectTimeout != 0) {
    142             c.setConnectTimeout(mConnectTimeout);
    143         }
    144         if (mReadTimeout != 0) {
    145             c.setReadTimeout(mReadTimeout);
    146         }
    147         return c;
    148     }
    149 
    150     private String getResponseFrom(HttpURLConnection c) throws IOException, HttpException {
    151         if (c.getResponseCode() != HttpURLConnection.HTTP_OK) {
    152             throw new HttpException(c.getResponseCode(), c.getResponseMessage());
    153         }
    154         if (DBG) {
    155             Log.d(TAG, "Content-Type: " + c.getContentType() + " (assuming " +
    156                     DEFAULT_CHARSET + ")");
    157         }
    158         BufferedReader reader = new BufferedReader(
    159                 new InputStreamReader(c.getInputStream(), DEFAULT_CHARSET));
    160         StringBuilder string = new StringBuilder();
    161         char[] chars = new char[BUFFER_SIZE];
    162         int bytes;
    163         while ((bytes = reader.read(chars)) != -1) {
    164             string.append(chars, 0, bytes);
    165         }
    166         return string.toString();
    167     }
    168 
    169     public void setConnectTimeout(int timeoutMillis) {
    170         mConnectTimeout = timeoutMillis;
    171     }
    172 
    173     public void setReadTimeout(int timeoutMillis) {
    174         mReadTimeout = timeoutMillis;
    175     }
    176 
    177     /**
    178      * A Url rewriter that does nothing, i.e., returns the
    179      * url that is passed to it.
    180      */
    181     public static class PassThroughRewriter implements UrlRewriter {
    182         @Override
    183         public String rewrite(String url) {
    184             return url;
    185         }
    186     }
    187 }
    188