Home | History | Annotate | Download | only in httpclient4
      1 /*
      2  * Copyright 2008 Sean Sullivan
      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 net.oauth.client.httpclient4;
     18 
     19 import java.io.IOException;
     20 import java.io.InputStream;
     21 import java.net.URL;
     22 import java.util.Map;
     23 import net.oauth.client.ExcerptInputStream;
     24 import net.oauth.http.HttpMessage;
     25 import net.oauth.http.HttpResponseMessage;
     26 import org.apache.http.HttpResponse;
     27 import org.apache.http.client.HttpClient;
     28 import org.apache.http.client.methods.HttpDelete;
     29 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
     30 import org.apache.http.client.methods.HttpGet;
     31 import org.apache.http.client.methods.HttpPost;
     32 import org.apache.http.client.methods.HttpPut;
     33 import org.apache.http.client.methods.HttpRequestBase;
     34 import org.apache.http.client.params.ClientPNames;
     35 import org.apache.http.conn.ClientConnectionManager;
     36 import org.apache.http.entity.InputStreamEntity;
     37 import org.apache.http.impl.client.DefaultHttpClient;
     38 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
     39 import org.apache.http.params.HttpParams;
     40 
     41 /**
     42  * Utility methods for an OAuth client based on the <a
     43  * href="http://hc.apache.org">Apache HttpClient</a>.
     44  *
     45  * @author Sean Sullivan
     46  * @hide
     47  */
     48 public class HttpClient4 implements net.oauth.http.HttpClient {
     49 
     50     public HttpClient4() {
     51         this(SHARED_CLIENT);
     52     }
     53 
     54     public HttpClient4(HttpClientPool clientPool) {
     55         this.clientPool = clientPool;
     56     }
     57 
     58     private final HttpClientPool clientPool;
     59 
     60     public HttpResponseMessage execute(HttpMessage request) throws IOException {
     61         final String method = request.method;
     62         final String url = request.url.toExternalForm();
     63         final InputStream body = request.getBody();
     64         final boolean isDelete = DELETE.equalsIgnoreCase(method);
     65         final boolean isPost = POST.equalsIgnoreCase(method);
     66         final boolean isPut = PUT.equalsIgnoreCase(method);
     67         byte[] excerpt = null;
     68         HttpRequestBase httpRequest;
     69         if (isPost || isPut) {
     70             HttpEntityEnclosingRequestBase entityEnclosingMethod =
     71                 isPost ? new HttpPost(url) : new HttpPut(url);
     72             if (body != null) {
     73                 ExcerptInputStream e = new ExcerptInputStream(body);
     74                 excerpt = e.getExcerpt();
     75                 String length = request.removeHeaders(HttpMessage.CONTENT_LENGTH);
     76                 entityEnclosingMethod.setEntity(new InputStreamEntity(e,
     77                         (length == null) ? -1 : Long.parseLong(length)));
     78             }
     79             httpRequest = entityEnclosingMethod;
     80         } else if (isDelete) {
     81             httpRequest = new HttpDelete(url);
     82         } else {
     83             httpRequest = new HttpGet(url);
     84         }
     85         for (Map.Entry<String, String> header : request.headers) {
     86             httpRequest.addHeader(header.getKey(), header.getValue());
     87         }
     88         HttpClient client = clientPool.getHttpClient(new URL(httpRequest.getURI().toString()));
     89         client.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
     90         HttpResponse httpResponse = client.execute(httpRequest);
     91         return new HttpMethodResponse(httpRequest, httpResponse, excerpt, request.getContentCharset());
     92     }
     93 
     94     private static final HttpClientPool SHARED_CLIENT = new SingleClient();
     95 
     96     /**
     97      * A pool that simply shares a single HttpClient. An HttpClient owns a pool
     98      * of TCP connections. So, callers that share an HttpClient will share
     99      * connections. Sharing improves performance (by avoiding the overhead of
    100      * creating connections) and uses fewer resources in the client and its
    101      * servers.
    102      */
    103     private static class SingleClient implements HttpClientPool
    104     {
    105         SingleClient()
    106         {
    107             HttpClient client = new DefaultHttpClient();
    108             ClientConnectionManager mgr = client.getConnectionManager();
    109             if (!(mgr instanceof ThreadSafeClientConnManager)) {
    110                 HttpParams params = client.getParams();
    111                 client = new DefaultHttpClient(new ThreadSafeClientConnManager(params,
    112                         mgr.getSchemeRegistry()), params);
    113             }
    114             this.client = client;
    115         }
    116 
    117         private final HttpClient client;
    118 
    119         public HttpClient getHttpClient(URL server)
    120         {
    121             return client;
    122         }
    123     }
    124 
    125 }
    126