View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.client;
28  
29  import java.io.IOException;
30  import java.net.URI;
31  
32  import org.apache.http.HttpEntity;
33  import org.apache.http.HttpEntityEnclosingRequest;
34  import org.apache.http.HttpException;
35  import org.apache.http.HttpHost;
36  import org.apache.http.HttpRequest;
37  import org.apache.http.HttpRequestInterceptor;
38  import org.apache.http.HttpResponse;
39  import org.apache.http.HttpResponseInterceptor;
40  import org.apache.http.client.ClientProtocolException;
41  import org.apache.http.client.HttpClient;
42  import org.apache.http.client.ResponseHandler;
43  import org.apache.http.client.methods.HttpUriRequest;
44  import org.apache.http.client.protocol.RequestAcceptEncoding;
45  import org.apache.http.client.protocol.ResponseContentEncoding;
46  import org.apache.http.client.utils.URIUtils;
47  import org.apache.http.conn.ClientConnectionManager;
48  import org.apache.http.params.HttpParams;
49  import org.apache.http.protocol.BasicHttpContext;
50  import org.apache.http.protocol.HttpContext;
51  import org.apache.http.util.EntityUtils;
52  
53  /**
54   * <p>Decorator adding support for compressed responses. This class sets
55   * the <code>Accept-Encoding</code> header on requests to indicate
56   * support for the <code>gzip</code> and <code>deflate</code>
57   * compression schemes; it then checks the <code>Content-Encoding</code>
58   * header on the response to uncompress any compressed response bodies.
59   * The {@link java.io.InputStream} of the entity will contain the uncompressed
60   * content.</p>
61   *
62   * <p><b>N.B.</b> Any upstream clients of this class need to be aware that
63   * this effectively obscures visibility into the length of a server
64   * response body, since the <code>Content-Length</code> header will
65   * correspond to the compressed entity length received from the server,
66   * but the content length experienced by reading the response body may
67   * be different (hopefully higher!).</p>
68   *
69   * <p>That said, this decorator is compatible with the
70   * <code>CachingHttpClient</code> in that the two decorators can be added
71   * in either order and still have cacheable responses be cached.</p>
72   *
73   * @since 4.2
74   *
75   * @deprecated (4.3) use {@link HttpClientBuilder}
76   */
77  @Deprecated
78  public class DecompressingHttpClient implements HttpClient {
79  
80      private final HttpClient backend;
81      private final HttpRequestInterceptor acceptEncodingInterceptor;
82      private final HttpResponseInterceptor contentEncodingInterceptor;
83  
84      /**
85       * Constructs a decorator to ask for and handle compressed
86       * entities on the fly.
87       */
88      public DecompressingHttpClient() {
89          this(new DefaultHttpClient());
90      }
91  
92      /**
93       * Constructs a decorator to ask for and handle compressed
94       * entities on the fly.
95       * @param backend the {@link HttpClient} to use for actually
96       *   issuing requests
97       */
98      public DecompressingHttpClient(final HttpClient backend) {
99          this(backend, new RequestAcceptEncoding(), new ResponseContentEncoding());
100     }
101 
102     DecompressingHttpClient(final HttpClient backend,
103             final HttpRequestInterceptor requestInterceptor,
104             final HttpResponseInterceptor responseInterceptor) {
105         this.backend = backend;
106         this.acceptEncodingInterceptor = requestInterceptor;
107         this.contentEncodingInterceptor = responseInterceptor;
108     }
109 
110     public HttpParams getParams() {
111         return backend.getParams();
112     }
113 
114     public ClientConnectionManager getConnectionManager() {
115         return backend.getConnectionManager();
116     }
117 
118     public HttpResponse execute(final HttpUriRequest request) throws IOException,
119             ClientProtocolException {
120         return execute(getHttpHost(request), request, (HttpContext)null);
121     }
122 
123     /**
124      * Gets the HttpClient to issue request.
125      *
126      * @return the HttpClient to issue request
127      */
128     public HttpClient getHttpClient() {
129         return this.backend;
130     }
131 
132     HttpHost getHttpHost(final HttpUriRequest request) {
133         final URI uri = request.getURI();
134         return URIUtils.extractHost(uri);
135     }
136 
137     public HttpResponse execute(final HttpUriRequest request, final HttpContext context)
138             throws IOException, ClientProtocolException {
139         return execute(getHttpHost(request), request, context);
140     }
141 
142     public HttpResponse execute(final HttpHost target, final HttpRequest request)
143             throws IOException, ClientProtocolException {
144         return execute(target, request, (HttpContext)null);
145     }
146 
147     public HttpResponse execute(final HttpHost target, final HttpRequest request,
148             final HttpContext context) throws IOException, ClientProtocolException {
149         try {
150             final HttpContext localContext = context != null ? context : new BasicHttpContext();
151             final HttpRequest wrapped;
152             if (request instanceof HttpEntityEnclosingRequest) {
153                 wrapped = new EntityEnclosingRequestWrapper((HttpEntityEnclosingRequest) request);
154             } else {
155                 wrapped = new RequestWrapper(request);
156             }
157             acceptEncodingInterceptor.process(wrapped, localContext);
158             final HttpResponse response = backend.execute(target, wrapped, localContext);
159             try {
160                 contentEncodingInterceptor.process(response, localContext);
161                 if (Boolean.TRUE.equals(localContext.getAttribute(ResponseContentEncoding.UNCOMPRESSED))) {
162                     response.removeHeaders("Content-Length");
163                     response.removeHeaders("Content-Encoding");
164                     response.removeHeaders("Content-MD5");
165                 }
166                 return response;
167             } catch (final HttpException ex) {
168                 EntityUtils.consume(response.getEntity());
169                 throw ex;
170             } catch (final IOException ex) {
171                 EntityUtils.consume(response.getEntity());
172                 throw ex;
173             } catch (final RuntimeException ex) {
174                 EntityUtils.consume(response.getEntity());
175                 throw ex;
176             }
177         } catch (final HttpException e) {
178             throw new ClientProtocolException(e);
179         }
180     }
181 
182     public <T> T execute(final HttpUriRequest request,
183             final ResponseHandler<? extends T> responseHandler) throws IOException,
184             ClientProtocolException {
185         return execute(getHttpHost(request), request, responseHandler);
186     }
187 
188     public <T> T execute(final HttpUriRequest request,
189             final ResponseHandler<? extends T> responseHandler, final HttpContext context)
190             throws IOException, ClientProtocolException {
191         return execute(getHttpHost(request), request, responseHandler, context);
192     }
193 
194     public <T> T execute(final HttpHost target, final HttpRequest request,
195             final ResponseHandler<? extends T> responseHandler) throws IOException,
196             ClientProtocolException {
197         return execute(target, request, responseHandler, null);
198     }
199 
200     public <T> T execute(final HttpHost target, final HttpRequest request,
201             final ResponseHandler<? extends T> responseHandler, final HttpContext context)
202             throws IOException, ClientProtocolException {
203         final HttpResponse response = execute(target, request, context);
204         try {
205             return responseHandler.handleResponse(response);
206         } finally {
207             final HttpEntity entity = response.getEntity();
208             if (entity != null) {
209                 EntityUtils.consume(entity);
210             }
211         }
212     }
213 
214 }