View Javadoc

1   /*
2    * ====================================================================
3    *
4    *  Licensed to the Apache Software Foundation (ASF) under one or more
5    *  contributor license agreements.  See the NOTICE file distributed with
6    *  this work for additional information regarding copyright ownership.
7    *  The ASF licenses this file to You under the Apache License, Version 2.0
8    *  (the "License"); you may not use this file except in compliance with
9    *  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, software
14   *  distributed under the License is distributed on an "AS IS" BASIS,
15   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   *  See the License for the specific language governing permissions and
17   *  limitations under the License.
18   * ====================================================================
19   *
20   * This software consists of voluntary contributions made by many
21   * individuals on behalf of the Apache Software Foundation.  For more
22   * information on the Apache Software Foundation, please see
23   * <http://www.apache.org/>.
24   *
25   */
26  
27  package org.apache.http.client.protocol;
28  
29  import java.io.IOException;
30  import java.util.Locale;
31  
32  import org.apache.http.Header;
33  import org.apache.http.HeaderElement;
34  import org.apache.http.HttpEntity;
35  import org.apache.http.HttpException;
36  import org.apache.http.HttpResponse;
37  import org.apache.http.HttpResponseInterceptor;
38  import org.apache.http.annotation.Immutable;
39  import org.apache.http.client.entity.DeflateDecompressingEntity;
40  import org.apache.http.client.entity.GzipDecompressingEntity;
41  import org.apache.http.protocol.HttpContext;
42  
43  /**
44   * {@link HttpResponseInterceptor} responsible for processing Content-Encoding
45   * responses.
46   * <p>
47   * Instances of this class are stateless and immutable, therefore threadsafe.
48   *
49   * @since 4.1
50   *
51   */
52  @Immutable
53  public class ResponseContentEncoding implements HttpResponseInterceptor {
54  
55      public static final String UNCOMPRESSED = "http.client.response.uncompressed"; 
56      
57      /**
58       * Handles the following {@code Content-Encoding}s by
59       * using the appropriate decompressor to wrap the response Entity:
60       * <ul>
61       * <li>gzip - see {@link GzipDecompressingEntity}</li>
62       * <li>deflate - see {@link DeflateDecompressingEntity}</li>
63       * <li>identity - no action needed</li>
64       * </ul>
65       *
66       * @param response the response which contains the entity
67       * @param  context not currently used
68       *
69       * @throws HttpException if the {@code Content-Encoding} is none of the above
70       */
71      public void process(
72              final HttpResponse response,
73              final HttpContext context) throws HttpException, IOException {
74          HttpEntity entity = response.getEntity();
75  
76          // entity can be null in case of 304 Not Modified, 204 No Content or similar
77          // check for zero length entity.
78          if (entity != null && entity.getContentLength() != 0) {
79              Header ceheader = entity.getContentEncoding();
80              if (ceheader != null) {
81                  HeaderElement[] codecs = ceheader.getElements();
82                  for (HeaderElement codec : codecs) {
83                      String codecname = codec.getName().toLowerCase(Locale.US);
84                      if ("gzip".equals(codecname) || "x-gzip".equals(codecname)) {
85                          response.setEntity(new GzipDecompressingEntity(response.getEntity()));
86                          if (context != null) context.setAttribute(UNCOMPRESSED, true);  
87                          return;
88                      } else if ("deflate".equals(codecname)) {
89                          response.setEntity(new DeflateDecompressingEntity(response.getEntity()));
90                          if (context != null) context.setAttribute(UNCOMPRESSED, true);
91                          return;
92                      } else if ("identity".equals(codecname)) {
93  
94                          /* Don't need to transform the content - no-op */
95                          return;
96                      } else {
97                          throw new HttpException("Unsupported Content-Coding: " + codec.getName());
98                      }
99                  }
100             }
101         }
102     }
103 
104 }