Home | History | Annotate | Download | only in toolbox
      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.volley.toolbox;
     18 
     19 import com.android.volley.AuthFailureError;
     20 import com.android.volley.Request;
     21 import com.android.volley.Request.Method;
     22 import java.io.IOException;
     23 import java.net.URI;
     24 import java.util.ArrayList;
     25 import java.util.List;
     26 import java.util.Map;
     27 import org.apache.http.HttpEntity;
     28 import org.apache.http.HttpResponse;
     29 import org.apache.http.NameValuePair;
     30 import org.apache.http.client.HttpClient;
     31 import org.apache.http.client.methods.HttpDelete;
     32 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
     33 import org.apache.http.client.methods.HttpGet;
     34 import org.apache.http.client.methods.HttpHead;
     35 import org.apache.http.client.methods.HttpOptions;
     36 import org.apache.http.client.methods.HttpPost;
     37 import org.apache.http.client.methods.HttpPut;
     38 import org.apache.http.client.methods.HttpTrace;
     39 import org.apache.http.client.methods.HttpUriRequest;
     40 import org.apache.http.entity.ByteArrayEntity;
     41 import org.apache.http.message.BasicNameValuePair;
     42 import org.apache.http.params.HttpConnectionParams;
     43 import org.apache.http.params.HttpParams;
     44 
     45 /**
     46  * An HttpStack that performs request over an {@link HttpClient}.
     47  *
     48  * @deprecated The Apache HTTP library on Android is deprecated. Use {@link HurlStack} or another
     49  *     {@link BaseHttpStack} implementation.
     50  */
     51 @Deprecated
     52 public class HttpClientStack implements HttpStack {
     53     protected final HttpClient mClient;
     54 
     55     private static final String HEADER_CONTENT_TYPE = "Content-Type";
     56 
     57     public HttpClientStack(HttpClient client) {
     58         mClient = client;
     59     }
     60 
     61     private static void setHeaders(HttpUriRequest httpRequest, Map<String, String> headers) {
     62         for (String key : headers.keySet()) {
     63             httpRequest.setHeader(key, headers.get(key));
     64         }
     65     }
     66 
     67     @SuppressWarnings("unused")
     68     private static List<NameValuePair> getPostParameterPairs(Map<String, String> postParams) {
     69         List<NameValuePair> result = new ArrayList<>(postParams.size());
     70         for (String key : postParams.keySet()) {
     71             result.add(new BasicNameValuePair(key, postParams.get(key)));
     72         }
     73         return result;
     74     }
     75 
     76     @Override
     77     public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
     78             throws IOException, AuthFailureError {
     79         HttpUriRequest httpRequest = createHttpRequest(request, additionalHeaders);
     80         setHeaders(httpRequest, additionalHeaders);
     81         // Request.getHeaders() takes precedence over the given additional (cache) headers) and any
     82         // headers set by createHttpRequest (like the Content-Type header).
     83         setHeaders(httpRequest, request.getHeaders());
     84         onPrepareRequest(httpRequest);
     85         HttpParams httpParams = httpRequest.getParams();
     86         int timeoutMs = request.getTimeoutMs();
     87         // TODO: Reevaluate this connection timeout based on more wide-scale
     88         // data collection and possibly different for wifi vs. 3G.
     89         HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
     90         HttpConnectionParams.setSoTimeout(httpParams, timeoutMs);
     91         return mClient.execute(httpRequest);
     92     }
     93 
     94     /** Creates the appropriate subclass of HttpUriRequest for passed in request. */
     95     @SuppressWarnings("deprecation")
     96     /* protected */ static HttpUriRequest createHttpRequest(
     97             Request<?> request, Map<String, String> additionalHeaders) throws AuthFailureError {
     98         switch (request.getMethod()) {
     99             case Method.DEPRECATED_GET_OR_POST:
    100                 {
    101                     // This is the deprecated way that needs to be handled for backwards
    102                     // compatibility.
    103                     // If the request's post body is null, then the assumption is that the request
    104                     // is
    105                     // GET.  Otherwise, it is assumed that the request is a POST.
    106                     byte[] postBody = request.getPostBody();
    107                     if (postBody != null) {
    108                         HttpPost postRequest = new HttpPost(request.getUrl());
    109                         postRequest.addHeader(
    110                                 HEADER_CONTENT_TYPE, request.getPostBodyContentType());
    111                         HttpEntity entity;
    112                         entity = new ByteArrayEntity(postBody);
    113                         postRequest.setEntity(entity);
    114                         return postRequest;
    115                     } else {
    116                         return new HttpGet(request.getUrl());
    117                     }
    118                 }
    119             case Method.GET:
    120                 return new HttpGet(request.getUrl());
    121             case Method.DELETE:
    122                 return new HttpDelete(request.getUrl());
    123             case Method.POST:
    124                 {
    125                     HttpPost postRequest = new HttpPost(request.getUrl());
    126                     postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
    127                     setEntityIfNonEmptyBody(postRequest, request);
    128                     return postRequest;
    129                 }
    130             case Method.PUT:
    131                 {
    132                     HttpPut putRequest = new HttpPut(request.getUrl());
    133                     putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
    134                     setEntityIfNonEmptyBody(putRequest, request);
    135                     return putRequest;
    136                 }
    137             case Method.HEAD:
    138                 return new HttpHead(request.getUrl());
    139             case Method.OPTIONS:
    140                 return new HttpOptions(request.getUrl());
    141             case Method.TRACE:
    142                 return new HttpTrace(request.getUrl());
    143             case Method.PATCH:
    144                 {
    145                     HttpPatch patchRequest = new HttpPatch(request.getUrl());
    146                     patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
    147                     setEntityIfNonEmptyBody(patchRequest, request);
    148                     return patchRequest;
    149                 }
    150             default:
    151                 throw new IllegalStateException("Unknown request method.");
    152         }
    153     }
    154 
    155     private static void setEntityIfNonEmptyBody(
    156             HttpEntityEnclosingRequestBase httpRequest, Request<?> request)
    157             throws AuthFailureError {
    158         byte[] body = request.getBody();
    159         if (body != null) {
    160             HttpEntity entity = new ByteArrayEntity(body);
    161             httpRequest.setEntity(entity);
    162         }
    163     }
    164 
    165     /**
    166      * Called before the request is executed using the underlying HttpClient.
    167      *
    168      * <p>Overwrite in subclasses to augment the request.
    169      */
    170     protected void onPrepareRequest(HttpUriRequest request) throws IOException {
    171         // Nothing.
    172     }
    173 
    174     /**
    175      * The HttpPatch class does not exist in the Android framework, so this has been defined here.
    176      */
    177     public static final class HttpPatch extends HttpEntityEnclosingRequestBase {
    178 
    179         public static final String METHOD_NAME = "PATCH";
    180 
    181         public HttpPatch() {
    182             super();
    183         }
    184 
    185         public HttpPatch(final URI uri) {
    186             super();
    187             setURI(uri);
    188         }
    189 
    190         /** @throws IllegalArgumentException if the uri is invalid. */
    191         public HttpPatch(final String uri) {
    192             super();
    193             setURI(URI.create(uri));
    194         }
    195 
    196         @Override
    197         public String getMethod() {
    198             return METHOD_NAME;
    199         }
    200     }
    201 }
    202