/lib/src/org/apache/http/impl/entity/LaxContentLengthStrategy.java

http://github.com/onedanshow/Screen-Courter · Java · 135 lines · 81 code · 8 blank · 46 comment · 27 complexity · f52c40202a39a4faa347fcce0e541d14 MD5 · raw file

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