001/*
002 * ====================================================================
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 * ====================================================================
020 *
021 * This software consists of voluntary contributions made by many
022 * individuals on behalf of the Apache Software Foundation.  For more
023 * information on the Apache Software Foundation, please see
024 * <http://www.apache.org/>.
025 *
026 */
027
028package org.apache.http.impl.client;
029
030import java.io.IOException;
031import java.util.concurrent.TimeUnit;
032
033import org.apache.http.HttpException;
034import org.apache.http.HttpHost;
035import org.apache.http.HttpRequest;
036import org.apache.http.annotation.Contract;
037import org.apache.http.annotation.ThreadingBehavior;
038import org.apache.http.client.ClientProtocolException;
039import org.apache.http.client.config.RequestConfig;
040import org.apache.http.client.methods.CloseableHttpResponse;
041import org.apache.http.client.methods.Configurable;
042import org.apache.http.client.methods.HttpExecutionAware;
043import org.apache.http.client.methods.HttpRequestWrapper;
044import org.apache.http.client.protocol.HttpClientContext;
045import org.apache.http.conn.ClientConnectionManager;
046import org.apache.http.conn.ClientConnectionRequest;
047import org.apache.http.conn.HttpClientConnectionManager;
048import org.apache.http.conn.ManagedClientConnection;
049import org.apache.http.conn.routing.HttpRoute;
050import org.apache.http.conn.scheme.SchemeRegistry;
051import org.apache.http.impl.DefaultConnectionReuseStrategy;
052import org.apache.http.impl.execchain.MinimalClientExec;
053import org.apache.http.params.BasicHttpParams;
054import org.apache.http.params.HttpParams;
055import org.apache.http.protocol.BasicHttpContext;
056import org.apache.http.protocol.HttpContext;
057import org.apache.http.protocol.HttpRequestExecutor;
058import org.apache.http.util.Args;
059
060/**
061 * Internal class.
062 *
063 * @since 4.3
064 */
065@Contract(threading = ThreadingBehavior.SAFE_CONDITIONAL)
066@SuppressWarnings("deprecation")
067class MinimalHttpClient extends CloseableHttpClient {
068
069    private final HttpClientConnectionManager connManager;
070    private final MinimalClientExec requestExecutor;
071    private final HttpParams params;
072
073    public MinimalHttpClient(
074            final HttpClientConnectionManager connManager) {
075        super();
076        this.connManager = Args.notNull(connManager, "HTTP connection manager");
077        this.requestExecutor = new MinimalClientExec(
078                new HttpRequestExecutor(),
079                connManager,
080                DefaultConnectionReuseStrategy.INSTANCE,
081                DefaultConnectionKeepAliveStrategy.INSTANCE);
082        this.params = new BasicHttpParams();
083    }
084
085    @Override
086    protected CloseableHttpResponse doExecute(
087            final HttpHost target,
088            final HttpRequest request,
089            final HttpContext context) throws IOException, ClientProtocolException {
090        Args.notNull(target, "Target host");
091        Args.notNull(request, "HTTP request");
092        HttpExecutionAware execAware = null;
093        if (request instanceof HttpExecutionAware) {
094            execAware = (HttpExecutionAware) request;
095        }
096        try {
097            final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(request);
098            final HttpClientContext localcontext = HttpClientContext.adapt(
099                context != null ? context : new BasicHttpContext());
100            final HttpRoute route = new HttpRoute(target);
101            RequestConfig config = null;
102            if (request instanceof Configurable) {
103                config = ((Configurable) request).getConfig();
104            }
105            if (config != null) {
106                localcontext.setRequestConfig(config);
107            }
108            return this.requestExecutor.execute(route, wrapper, localcontext, execAware);
109        } catch (final HttpException httpException) {
110            throw new ClientProtocolException(httpException);
111        }
112    }
113
114    @Override
115    public HttpParams getParams() {
116        return this.params;
117    }
118
119    @Override
120    public void close() {
121        this.connManager.shutdown();
122    }
123
124    @Override
125    public ClientConnectionManager getConnectionManager() {
126
127        return new ClientConnectionManager() {
128
129            @Override
130            public void shutdown() {
131                connManager.shutdown();
132            }
133
134            @Override
135            public ClientConnectionRequest requestConnection(
136                    final HttpRoute route, final Object state) {
137                throw new UnsupportedOperationException();
138            }
139
140            @Override
141            public void releaseConnection(
142                    final ManagedClientConnection conn,
143                    final long validDuration, final TimeUnit timeUnit) {
144                throw new UnsupportedOperationException();
145            }
146
147            @Override
148            public SchemeRegistry getSchemeRegistry() {
149                throw new UnsupportedOperationException();
150            }
151
152            @Override
153            public void closeIdleConnections(final long idletime, final TimeUnit tunit) {
154                connManager.closeIdleConnections(idletime, tunit);
155            }
156
157            @Override
158            public void closeExpiredConnections() {
159                connManager.closeExpiredConnections();
160            }
161
162        };
163
164    }
165
166}