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 17package net.oauth.client.httpclient4; 18 19import java.io.IOException; 20import java.io.InputStream; 21import java.net.URL; 22import java.util.Map; 23import net.oauth.client.ExcerptInputStream; 24import net.oauth.http.HttpMessage; 25import net.oauth.http.HttpResponseMessage; 26import org.apache.http.HttpResponse; 27import org.apache.http.client.HttpClient; 28import org.apache.http.client.methods.HttpDelete; 29import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; 30import org.apache.http.client.methods.HttpGet; 31import org.apache.http.client.methods.HttpPost; 32import org.apache.http.client.methods.HttpPut; 33import org.apache.http.client.methods.HttpRequestBase; 34import org.apache.http.client.params.ClientPNames; 35import org.apache.http.conn.ClientConnectionManager; 36import org.apache.http.entity.InputStreamEntity; 37import org.apache.http.impl.client.DefaultHttpClient; 38import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; 39import 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 */ 48public 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