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.

michael@0 1 /*
michael@0 2 * ====================================================================
michael@0 3 * Licensed to the Apache Software Foundation (ASF) under one
michael@0 4 * or more contributor license agreements. See the NOTICE file
michael@0 5 * distributed with this work for additional information
michael@0 6 * regarding copyright ownership. The ASF licenses this file
michael@0 7 * to you under the Apache License, Version 2.0 (the
michael@0 8 * "License"); you may not use this file except in compliance
michael@0 9 * with the License. You may obtain a copy of the License at
michael@0 10 *
michael@0 11 * http://www.apache.org/licenses/LICENSE-2.0
michael@0 12 *
michael@0 13 * Unless required by applicable law or agreed to in writing,
michael@0 14 * software distributed under the License is distributed on an
michael@0 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
michael@0 16 * KIND, either express or implied. See the License for the
michael@0 17 * specific language governing permissions and limitations
michael@0 18 * under the License.
michael@0 19 * ====================================================================
michael@0 20 *
michael@0 21 * This software consists of voluntary contributions made by many
michael@0 22 * individuals on behalf of the Apache Software Foundation. For more
michael@0 23 * information on the Apache Software Foundation, please see
michael@0 24 * <http://www.apache.org/>.
michael@0 25 *
michael@0 26 */
michael@0 27
michael@0 28 package ch.boye.httpclientandroidlib.impl.entity;
michael@0 29
michael@0 30 import ch.boye.httpclientandroidlib.Header;
michael@0 31 import ch.boye.httpclientandroidlib.HeaderElement;
michael@0 32 import ch.boye.httpclientandroidlib.HttpException;
michael@0 33 import ch.boye.httpclientandroidlib.HttpMessage;
michael@0 34 import ch.boye.httpclientandroidlib.ParseException;
michael@0 35 import ch.boye.httpclientandroidlib.ProtocolException;
michael@0 36 import ch.boye.httpclientandroidlib.entity.ContentLengthStrategy;
michael@0 37 import ch.boye.httpclientandroidlib.params.HttpParams;
michael@0 38 import ch.boye.httpclientandroidlib.params.CoreProtocolPNames;
michael@0 39 import ch.boye.httpclientandroidlib.protocol.HTTP;
michael@0 40
michael@0 41 /**
michael@0 42 * The lax implementation of the content length strategy. This class will ignore
michael@0 43 * unrecognized transfer encodings and malformed <code>Content-Length</code>
michael@0 44 * header values if the {@link CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
michael@0 45 * parameter of the given message is not set or set to <code>false</code>.
michael@0 46 * <p>
michael@0 47 * This class recognizes "chunked" and "identitiy" transfer-coding only.
michael@0 48 * <p>
michael@0 49 * The following parameters can be used to customize the behavior of this class:
michael@0 50 * <ul>
michael@0 51 * <li>{@link ch.boye.httpclientandroidlib.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}</li>
michael@0 52 * </ul>
michael@0 53 *
michael@0 54 * @since 4.0
michael@0 55 */
michael@0 56 public class LaxContentLengthStrategy implements ContentLengthStrategy {
michael@0 57
michael@0 58 public LaxContentLengthStrategy() {
michael@0 59 super();
michael@0 60 }
michael@0 61
michael@0 62 public long determineLength(final HttpMessage message) throws HttpException {
michael@0 63 if (message == null) {
michael@0 64 throw new IllegalArgumentException("HTTP message may not be null");
michael@0 65 }
michael@0 66
michael@0 67 HttpParams params = message.getParams();
michael@0 68 boolean strict = params.isParameterTrue(CoreProtocolPNames.STRICT_TRANSFER_ENCODING);
michael@0 69
michael@0 70 Header transferEncodingHeader = message.getFirstHeader(HTTP.TRANSFER_ENCODING);
michael@0 71 Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN);
michael@0 72 // We use Transfer-Encoding if present and ignore Content-Length.
michael@0 73 // RFC2616, 4.4 item number 3
michael@0 74 if (transferEncodingHeader != null) {
michael@0 75 HeaderElement[] encodings = null;
michael@0 76 try {
michael@0 77 encodings = transferEncodingHeader.getElements();
michael@0 78 } catch (ParseException px) {
michael@0 79 throw new ProtocolException
michael@0 80 ("Invalid Transfer-Encoding header value: " +
michael@0 81 transferEncodingHeader, px);
michael@0 82 }
michael@0 83 if (strict) {
michael@0 84 // Currently only chunk and identity are supported
michael@0 85 for (int i = 0; i < encodings.length; i++) {
michael@0 86 String encoding = encodings[i].getName();
michael@0 87 if (encoding != null && encoding.length() > 0
michael@0 88 && !encoding.equalsIgnoreCase(HTTP.CHUNK_CODING)
michael@0 89 && !encoding.equalsIgnoreCase(HTTP.IDENTITY_CODING)) {
michael@0 90 throw new ProtocolException("Unsupported transfer encoding: " + encoding);
michael@0 91 }
michael@0 92 }
michael@0 93 }
michael@0 94 // The chunked encoding must be the last one applied RFC2616, 14.41
michael@0 95 int len = encodings.length;
michael@0 96 if (HTTP.IDENTITY_CODING.equalsIgnoreCase(transferEncodingHeader.getValue())) {
michael@0 97 return IDENTITY;
michael@0 98 } else if ((len > 0) && (HTTP.CHUNK_CODING.equalsIgnoreCase(
michael@0 99 encodings[len - 1].getName()))) {
michael@0 100 return CHUNKED;
michael@0 101 } else {
michael@0 102 if (strict) {
michael@0 103 throw new ProtocolException("Chunk-encoding must be the last one applied");
michael@0 104 }
michael@0 105 return IDENTITY;
michael@0 106 }
michael@0 107 } else if (contentLengthHeader != null) {
michael@0 108 long contentlen = -1;
michael@0 109 Header[] headers = message.getHeaders(HTTP.CONTENT_LEN);
michael@0 110 if (strict && headers.length > 1) {
michael@0 111 throw new ProtocolException("Multiple content length headers");
michael@0 112 }
michael@0 113 for (int i = headers.length - 1; i >= 0; i--) {
michael@0 114 Header header = headers[i];
michael@0 115 try {
michael@0 116 contentlen = Long.parseLong(header.getValue());
michael@0 117 break;
michael@0 118 } catch (NumberFormatException e) {
michael@0 119 if (strict) {
michael@0 120 throw new ProtocolException("Invalid content length: " + header.getValue());
michael@0 121 }
michael@0 122 }
michael@0 123 // See if we can have better luck with another header, if present
michael@0 124 }
michael@0 125 if (contentlen >= 0) {
michael@0 126 return contentlen;
michael@0 127 } else {
michael@0 128 return IDENTITY;
michael@0 129 }
michael@0 130 } else {
michael@0 131 return IDENTITY;
michael@0 132 }
michael@0 133 }
michael@0 134
michael@0 135 }

mercurial