2
* $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0.1/httpcore/src/main/java/org/apache/http/impl/entity/LaxContentLengthStrategy.java $
4
* $Date: 2009-02-14 18:04:18 +0100 (Sat, 14 Feb 2009) $
6
* ====================================================================
7
* Licensed to the Apache Software Foundation (ASF) under one
8
* or more contributor license agreements. See the NOTICE file
9
* distributed with this work for additional information
10
* regarding copyright ownership. The ASF licenses this file
11
* to you under the Apache License, Version 2.0 (the
12
* "License"); you may not use this file except in compliance
13
* with the License. You may obtain a copy of the License at
15
* http://www.apache.org/licenses/LICENSE-2.0
17
* Unless required by applicable law or agreed to in writing,
18
* software distributed under the License is distributed on an
19
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20
* KIND, either express or implied. See the License for the
21
* specific language governing permissions and limitations
23
* ====================================================================
25
* This software consists of voluntary contributions made by many
26
* individuals on behalf of the Apache Software Foundation. For more
27
* information on the Apache Software Foundation, please see
28
* <http://www.apache.org/>.
32
package org.apache.http.impl.entity;
34
import org.apache.http.Header;
35
import org.apache.http.HeaderElement;
36
import org.apache.http.HttpException;
37
import org.apache.http.HttpMessage;
38
import org.apache.http.ParseException;
39
import org.apache.http.ProtocolException;
40
import org.apache.http.entity.ContentLengthStrategy;
41
import org.apache.http.params.HttpParams;
42
import org.apache.http.params.CoreProtocolPNames;
43
import org.apache.http.protocol.HTTP;
46
* The lax implementation of the content length strategy. This class will ignore
47
* unrecognized transfer encodings and malformed <code>Content-Length</code>
48
* header values if the {@link CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
49
* parameter of the given message is not set or set to <code>false</code>.
51
* This class recognizes "chunked" and "identitiy" transfer-coding only.
54
* @version $Revision: 744526 $
58
public class LaxContentLengthStrategy implements ContentLengthStrategy {
60
public LaxContentLengthStrategy() {
64
public long determineLength(final HttpMessage message) throws HttpException {
65
if (message == null) {
66
throw new IllegalArgumentException("HTTP message may not be null");
69
HttpParams params = message.getParams();
70
boolean strict = params.isParameterTrue(CoreProtocolPNames.STRICT_TRANSFER_ENCODING);
72
Header transferEncodingHeader = message.getFirstHeader(HTTP.TRANSFER_ENCODING);
73
Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN);
74
// We use Transfer-Encoding if present and ignore Content-Length.
75
// RFC2616, 4.4 item number 3
76
if (transferEncodingHeader != null) {
77
HeaderElement[] encodings = null;
79
encodings = transferEncodingHeader.getElements();
80
} catch (ParseException px) {
81
throw new ProtocolException
82
("Invalid Transfer-Encoding header value: " +
83
transferEncodingHeader, px);
86
// Currently only chunk and identity are supported
87
for (int i = 0; i < encodings.length; i++) {
88
String encoding = encodings[i].getName();
89
if (encoding != null && encoding.length() > 0
90
&& !encoding.equalsIgnoreCase(HTTP.CHUNK_CODING)
91
&& !encoding.equalsIgnoreCase(HTTP.IDENTITY_CODING)) {
92
throw new ProtocolException("Unsupported transfer encoding: " + encoding);
96
// The chunked encoding must be the last one applied RFC2616, 14.41
97
int len = encodings.length;
98
if (HTTP.IDENTITY_CODING.equalsIgnoreCase(transferEncodingHeader.getValue())) {
100
} else if ((len > 0) && (HTTP.CHUNK_CODING.equalsIgnoreCase(
101
encodings[len - 1].getName()))) {
105
throw new ProtocolException("Chunk-encoding must be the last one applied");
109
} else if (contentLengthHeader != null) {
110
long contentlen = -1;
111
Header[] headers = message.getHeaders(HTTP.CONTENT_LEN);
112
if (strict && headers.length > 1) {
113
throw new ProtocolException("Multiple content length headers");
115
for (int i = headers.length - 1; i >= 0; i--) {
116
Header header = headers[i];
118
contentlen = Long.parseLong(header.getValue());
120
} catch (NumberFormatException e) {
122
throw new ProtocolException("Invalid content length: " + header.getValue());
125
// See if we can have better luck with another header, if present
127
if (contentlen >= 0) {