mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/LaxContentLengthStrategy.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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  */
    28 package ch.boye.httpclientandroidlib.impl.entity;
    30 import ch.boye.httpclientandroidlib.Header;
    31 import ch.boye.httpclientandroidlib.HeaderElement;
    32 import ch.boye.httpclientandroidlib.HttpException;
    33 import ch.boye.httpclientandroidlib.HttpMessage;
    34 import ch.boye.httpclientandroidlib.ParseException;
    35 import ch.boye.httpclientandroidlib.ProtocolException;
    36 import ch.boye.httpclientandroidlib.entity.ContentLengthStrategy;
    37 import ch.boye.httpclientandroidlib.params.HttpParams;
    38 import ch.boye.httpclientandroidlib.params.CoreProtocolPNames;
    39 import ch.boye.httpclientandroidlib.protocol.HTTP;
    41 /**
    42  * The lax implementation of the content length strategy. This class will ignore
    43  * unrecognized transfer encodings and malformed <code>Content-Length</code>
    44  * header values if the {@link CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
    45  * parameter of the given message is not set or set to <code>false</code>.
    46  * <p>
    47  * This class recognizes "chunked" and "identitiy" transfer-coding only.
    48  * <p>
    49  * The following parameters can be used to customize the behavior of this class:
    50  * <ul>
    51  *  <li>{@link ch.boye.httpclientandroidlib.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}</li>
    52  * </ul>
    53  *
    54  * @since 4.0
    55  */
    56 public class LaxContentLengthStrategy implements ContentLengthStrategy {
    58     public LaxContentLengthStrategy() {
    59         super();
    60     }
    62     public long determineLength(final HttpMessage message) throws HttpException {
    63         if (message == null) {
    64             throw new IllegalArgumentException("HTTP message may not be null");
    65         }
    67         HttpParams params = message.getParams();
    68         boolean strict = params.isParameterTrue(CoreProtocolPNames.STRICT_TRANSFER_ENCODING);
    70         Header transferEncodingHeader = message.getFirstHeader(HTTP.TRANSFER_ENCODING);
    71         Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN);
    72         // We use Transfer-Encoding if present and ignore Content-Length.
    73         // RFC2616, 4.4 item number 3
    74         if (transferEncodingHeader != null) {
    75             HeaderElement[] encodings = null;
    76             try {
    77                 encodings = transferEncodingHeader.getElements();
    78             } catch (ParseException px) {
    79                 throw new ProtocolException
    80                     ("Invalid Transfer-Encoding header value: " +
    81                      transferEncodingHeader, px);
    82             }
    83             if (strict) {
    84                 // Currently only chunk and identity are supported
    85                 for (int i = 0; i < encodings.length; i++) {
    86                     String encoding = encodings[i].getName();
    87                     if (encoding != null && encoding.length() > 0
    88                         && !encoding.equalsIgnoreCase(HTTP.CHUNK_CODING)
    89                         && !encoding.equalsIgnoreCase(HTTP.IDENTITY_CODING)) {
    90                         throw new ProtocolException("Unsupported transfer encoding: " + encoding);
    91                     }
    92                 }
    93             }
    94             // The chunked encoding must be the last one applied RFC2616, 14.41
    95             int len = encodings.length;
    96             if (HTTP.IDENTITY_CODING.equalsIgnoreCase(transferEncodingHeader.getValue())) {
    97                 return IDENTITY;
    98             } else if ((len > 0) && (HTTP.CHUNK_CODING.equalsIgnoreCase(
    99                     encodings[len - 1].getName()))) {
   100                 return CHUNKED;
   101             } else {
   102                 if (strict) {
   103                     throw new ProtocolException("Chunk-encoding must be the last one applied");
   104                 }
   105                 return IDENTITY;
   106             }
   107         } else if (contentLengthHeader != null) {
   108             long contentlen = -1;
   109             Header[] headers = message.getHeaders(HTTP.CONTENT_LEN);
   110             if (strict && headers.length > 1) {
   111                 throw new ProtocolException("Multiple content length headers");
   112             }
   113             for (int i = headers.length - 1; i >= 0; i--) {
   114                 Header header = headers[i];
   115                 try {
   116                     contentlen = Long.parseLong(header.getValue());
   117                     break;
   118                 } catch (NumberFormatException e) {
   119                     if (strict) {
   120                         throw new ProtocolException("Invalid content length: " + header.getValue());
   121                     }
   122                 }
   123                 // See if we can have better luck with another header, if present
   124             }
   125             if (contentlen >= 0) {
   126                 return contentlen;
   127             } else {
   128                 return IDENTITY;
   129             }
   130         } else {
   131             return IDENTITY;
   132         }
   133     }
   135 }

mercurial