1/*
2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultHttpClient.java $
3 * $Revision: 677250 $
4 * $Date: 2008-07-16 04:45:47 -0700 (Wed, 16 Jul 2008) $
5 *
6 * ====================================================================
7 * Licensed to the Apache Software Foundation (ASF) under one
8 * or more contributor license agreements.  See the NOTICE file
9 * distributed with this work for additional information
10 * regarding copyright ownership.  The ASF licenses this file
11 * to you under the Apache License, Version 2.0 (the
12 * "License"); you may not use this file except in compliance
13 * with the License.  You may obtain a copy of the License at
14 *
15 *   http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing,
18 * software distributed under the License is distributed on an
19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20 * KIND, either express or implied.  See the License for the
21 * specific language governing permissions and limitations
22 * under the License.
23 * ====================================================================
24 *
25 * This software consists of voluntary contributions made by many
26 * individuals on behalf of the Apache Software Foundation.  For more
27 * information on the Apache Software Foundation, please see
28 * <http://www.apache.org/>.
29 *
30 */
31
32package org.apache.http.impl.client;
33
34import org.apache.http.ConnectionReuseStrategy;
35import org.apache.http.HttpVersion;
36import org.apache.http.auth.AuthSchemeRegistry;
37import org.apache.http.client.AuthenticationHandler;
38import org.apache.http.client.CookieStore;
39import org.apache.http.client.CredentialsProvider;
40import org.apache.http.client.HttpRequestRetryHandler;
41import org.apache.http.client.RedirectHandler;
42import org.apache.http.client.UserTokenHandler;
43import org.apache.http.client.params.AuthPolicy;
44import org.apache.http.client.params.ClientPNames;
45import org.apache.http.client.params.CookiePolicy;
46import org.apache.http.client.protocol.ClientContext;
47import org.apache.http.client.protocol.RequestAddCookies;
48import org.apache.http.client.protocol.RequestDefaultHeaders;
49import org.apache.http.client.protocol.RequestProxyAuthentication;
50import org.apache.http.client.protocol.RequestTargetAuthentication;
51import org.apache.http.client.protocol.ResponseProcessCookies;
52import org.apache.http.conn.ClientConnectionManager;
53import org.apache.http.conn.ClientConnectionManagerFactory;
54import org.apache.http.conn.ConnectionKeepAliveStrategy;
55import org.apache.http.conn.routing.HttpRoutePlanner;
56import org.apache.http.conn.scheme.PlainSocketFactory;
57import org.apache.http.conn.scheme.Scheme;
58import org.apache.http.conn.scheme.SchemeRegistry;
59import org.apache.http.conn.ssl.SSLSocketFactory;
60import org.apache.http.cookie.CookieSpecRegistry;
61import org.apache.http.impl.DefaultConnectionReuseStrategy;
62import org.apache.http.impl.auth.BasicSchemeFactory;
63import org.apache.http.impl.auth.DigestSchemeFactory;
64import org.apache.http.impl.conn.ProxySelectorRoutePlanner;
65import org.apache.http.impl.conn.SingleClientConnManager;
66import org.apache.http.impl.cookie.BestMatchSpecFactory;
67import org.apache.http.impl.cookie.BrowserCompatSpecFactory;
68import org.apache.http.impl.cookie.NetscapeDraftSpecFactory;
69import org.apache.http.impl.cookie.RFC2109SpecFactory;
70import org.apache.http.impl.cookie.RFC2965SpecFactory;
71import org.apache.http.params.BasicHttpParams;
72import org.apache.http.params.HttpParams;
73import org.apache.http.params.HttpProtocolParams;
74import org.apache.http.protocol.BasicHttpContext;
75import org.apache.http.protocol.BasicHttpProcessor;
76import org.apache.http.protocol.HTTP;
77import org.apache.http.protocol.HttpContext;
78import org.apache.http.protocol.HttpRequestExecutor;
79import org.apache.http.protocol.RequestConnControl;
80import org.apache.http.protocol.RequestContent;
81import org.apache.http.protocol.RequestExpectContinue;
82import org.apache.http.protocol.RequestTargetHost;
83import org.apache.http.protocol.RequestUserAgent;
84import org.apache.http.util.VersionInfo;
85
86
87
88/**
89 * Default implementation of an HTTP client.
90 *
91 * <h3>Prefer HttpURLConnection for new code</h3>
92 * Android includes two HTTP clients: {@code HttpURLConnection} and Apache HTTP
93 * Client. Both support HTTPS, streaming uploads and downloads, configurable
94 * timeouts, IPv6 and connection pooling. Apache HTTP client has fewer bugs in
95 * Android 2.2 (Froyo) and earlier releases. For Android 2.3 (Gingerbread) and
96 * later, {@link java.net.HttpURLConnection HttpURLConnection} is the best
97 * choice. Its simple API and small size makes it great fit for Android.
98 * Transparent compression and response caching reduce network use, improve
99 * speed and save battery. See the <a
100 * href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">Android
101 * Developers Blog</a> for a comparison of the two HTTP clients.
102 *
103 * @author <a href="mailto:rolandw at apache.org">Roland Weber</a>
104 * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
105 *
106 * <!-- empty lines to avoid svn diff problems -->
107 * @version   $Revision: 677250 $
108 *
109 * @since 4.0
110 */
111public class DefaultHttpClient extends AbstractHttpClient {
112
113
114    /**
115     * Creates a new HTTP client from parameters and a connection manager.
116     *
117     * @param params    the parameters
118     * @param conman    the connection manager
119     */
120    public DefaultHttpClient(
121            final ClientConnectionManager conman,
122            final HttpParams params) {
123        super(conman, params);
124    }
125
126
127    public DefaultHttpClient(final HttpParams params) {
128        super(null, params);
129    }
130
131
132    public DefaultHttpClient() {
133        super(null, null);
134    }
135
136
137    @Override
138    protected HttpParams createHttpParams() {
139        HttpParams params = new BasicHttpParams();
140        HttpProtocolParams.setVersion(params,
141                HttpVersion.HTTP_1_1);
142        HttpProtocolParams.setContentCharset(params,
143                HTTP.DEFAULT_CONTENT_CHARSET);
144
145        /*
146         * Android note: Send each request body without first asking the server
147         * whether it will be accepted. Asking first slows down the common case
148         * and results in "417 expectation failed" errors when a HTTP/1.0 server
149         * is behind a proxy. http://b/2471595
150         */
151        HttpProtocolParams.setUseExpectContinue(params,
152                false); // android-changed
153
154        // determine the release version from packaged version info
155        final VersionInfo vi = VersionInfo.loadVersionInfo
156            ("org.apache.http.client", getClass().getClassLoader());
157        final String release = (vi != null) ?
158            vi.getRelease() : VersionInfo.UNAVAILABLE;
159        HttpProtocolParams.setUserAgent(params,
160                "Apache-HttpClient/" + release + " (java 1.4)");
161
162        return params;
163    }
164
165
166    @Override
167    protected HttpRequestExecutor createRequestExecutor() {
168        return new HttpRequestExecutor();
169    }
170
171
172    @Override
173    protected ClientConnectionManager createClientConnectionManager() {
174        SchemeRegistry registry = new SchemeRegistry();
175        registry.register(
176                new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
177        registry.register(
178                new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
179
180        ClientConnectionManager connManager = null;
181        HttpParams params = getParams();
182
183        ClientConnectionManagerFactory factory = null;
184
185        // Try first getting the factory directly as an object.
186        factory = (ClientConnectionManagerFactory) params
187                .getParameter(ClientPNames.CONNECTION_MANAGER_FACTORY);
188        if (factory == null) { // then try getting its class name.
189            String className = (String) params.getParameter(
190                    ClientPNames.CONNECTION_MANAGER_FACTORY_CLASS_NAME);
191            if (className != null) {
192                try {
193                    Class<?> clazz = Class.forName(className);
194                    factory = (ClientConnectionManagerFactory) clazz.newInstance();
195                } catch (ClassNotFoundException ex) {
196                    throw new IllegalStateException("Invalid class name: " + className);
197                } catch (IllegalAccessException ex) {
198                    throw new IllegalAccessError(ex.getMessage());
199                } catch (InstantiationException ex) {
200                    throw new InstantiationError(ex.getMessage());
201                }
202            }
203        }
204
205        if(factory != null) {
206            connManager = factory.newInstance(params, registry);
207        } else {
208            connManager = new SingleClientConnManager(getParams(), registry);
209        }
210
211        return connManager;
212    }
213
214
215    @Override
216    protected HttpContext createHttpContext() {
217        HttpContext context = new BasicHttpContext();
218        context.setAttribute(
219                ClientContext.AUTHSCHEME_REGISTRY,
220                getAuthSchemes());
221        context.setAttribute(
222                ClientContext.COOKIESPEC_REGISTRY,
223                getCookieSpecs());
224        context.setAttribute(
225                ClientContext.COOKIE_STORE,
226                getCookieStore());
227        context.setAttribute(
228                ClientContext.CREDS_PROVIDER,
229                getCredentialsProvider());
230        return context;
231    }
232
233
234    @Override
235    protected ConnectionReuseStrategy createConnectionReuseStrategy() {
236        return new DefaultConnectionReuseStrategy();
237    }
238
239    @Override
240    protected ConnectionKeepAliveStrategy createConnectionKeepAliveStrategy() {
241        return new DefaultConnectionKeepAliveStrategy();
242    }
243
244
245    @Override
246    protected AuthSchemeRegistry createAuthSchemeRegistry() {
247        AuthSchemeRegistry registry = new AuthSchemeRegistry();
248        registry.register(
249                AuthPolicy.BASIC,
250                new BasicSchemeFactory());
251        registry.register(
252                AuthPolicy.DIGEST,
253                new DigestSchemeFactory());
254        return registry;
255    }
256
257
258    @Override
259    protected CookieSpecRegistry createCookieSpecRegistry() {
260        CookieSpecRegistry registry = new CookieSpecRegistry();
261        registry.register(
262                CookiePolicy.BEST_MATCH,
263                new BestMatchSpecFactory());
264        registry.register(
265                CookiePolicy.BROWSER_COMPATIBILITY,
266                new BrowserCompatSpecFactory());
267        registry.register(
268                CookiePolicy.NETSCAPE,
269                new NetscapeDraftSpecFactory());
270        registry.register(
271                CookiePolicy.RFC_2109,
272                new RFC2109SpecFactory());
273        registry.register(
274                CookiePolicy.RFC_2965,
275                new RFC2965SpecFactory());
276        return registry;
277    }
278
279
280    @Override
281    protected BasicHttpProcessor createHttpProcessor() {
282        BasicHttpProcessor httpproc = new BasicHttpProcessor();
283        httpproc.addInterceptor(new RequestDefaultHeaders());
284        // Required protocol interceptors
285        httpproc.addInterceptor(new RequestContent());
286        httpproc.addInterceptor(new RequestTargetHost());
287        // Recommended protocol interceptors
288        httpproc.addInterceptor(new RequestConnControl());
289        httpproc.addInterceptor(new RequestUserAgent());
290        httpproc.addInterceptor(new RequestExpectContinue());
291        // HTTP state management interceptors
292        httpproc.addInterceptor(new RequestAddCookies());
293        httpproc.addInterceptor(new ResponseProcessCookies());
294        // HTTP authentication interceptors
295        httpproc.addInterceptor(new RequestTargetAuthentication());
296        httpproc.addInterceptor(new RequestProxyAuthentication());
297        return httpproc;
298    }
299
300
301    @Override
302    protected HttpRequestRetryHandler createHttpRequestRetryHandler() {
303        return new DefaultHttpRequestRetryHandler();
304    }
305
306
307    @Override
308    protected RedirectHandler createRedirectHandler() {
309        return new DefaultRedirectHandler();
310    }
311
312
313    @Override
314    protected AuthenticationHandler createTargetAuthenticationHandler() {
315        return new DefaultTargetAuthenticationHandler();
316    }
317
318
319    @Override
320    protected AuthenticationHandler createProxyAuthenticationHandler() {
321        return new DefaultProxyAuthenticationHandler();
322    }
323
324
325    @Override
326    protected CookieStore createCookieStore() {
327        return new BasicCookieStore();
328    }
329
330
331    @Override
332    protected CredentialsProvider createCredentialsProvider() {
333        return new BasicCredentialsProvider();
334    }
335
336
337    @Override
338    protected HttpRoutePlanner createHttpRoutePlanner() {
339        // BEGIN android-changed
340        //     Use the proxy specified by system properties
341        return new ProxySelectorRoutePlanner(getConnectionManager().getSchemeRegistry(), null);
342        // END android-changed
343    }
344
345
346    @Override
347    protected UserTokenHandler createUserTokenHandler() {
348        return new DefaultUserTokenHandler();
349    }
350
351} // class DefaultHttpClient
352