diff options
Diffstat (limited to 'mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity')
6 files changed, 600 insertions, 0 deletions
diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/DisallowIdentityContentLengthStrategy.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/DisallowIdentityContentLengthStrategy.java new file mode 100644 index 000000000..93556d22b --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/DisallowIdentityContentLengthStrategy.java @@ -0,0 +1,63 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.entity; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpMessage; +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.entity.ContentLengthStrategy; + +/** + * Decorator for {@link ContentLengthStrategy} implementations that disallows the use of + * identity transfer encoding. + * + * @since 4.2 + */ +@Immutable +public class DisallowIdentityContentLengthStrategy implements ContentLengthStrategy { + + public static final DisallowIdentityContentLengthStrategy INSTANCE = + new DisallowIdentityContentLengthStrategy(new LaxContentLengthStrategy(0)); + + private final ContentLengthStrategy contentLengthStrategy; + + public DisallowIdentityContentLengthStrategy(final ContentLengthStrategy contentLengthStrategy) { + super(); + this.contentLengthStrategy = contentLengthStrategy; + } + + public long determineLength(final HttpMessage message) throws HttpException { + final long result = this.contentLengthStrategy.determineLength(message); + if (result == ContentLengthStrategy.IDENTITY) { + throw new ProtocolException("Identity transfer encoding cannot be used"); + } + return result; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/EntityDeserializer.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/EntityDeserializer.java new file mode 100644 index 000000000..5eba3638c --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/EntityDeserializer.java @@ -0,0 +1,143 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.entity; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpMessage; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.entity.BasicHttpEntity; +import ch.boye.httpclientandroidlib.entity.ContentLengthStrategy; +import ch.boye.httpclientandroidlib.impl.io.ChunkedInputStream; +import ch.boye.httpclientandroidlib.impl.io.ContentLengthInputStream; +import ch.boye.httpclientandroidlib.impl.io.IdentityInputStream; +import ch.boye.httpclientandroidlib.io.SessionInputBuffer; +import ch.boye.httpclientandroidlib.protocol.HTTP; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * HTTP entity deserializer. + * <p> + * This entity deserializer supports "chunked" and "identitiy" transfer-coding + * and content length delimited content. + * <p> + * This class relies on a specific implementation of + * {@link ContentLengthStrategy} to determine the content length or transfer + * encoding of the entity. + * <p> + * This class generates an instance of {@link HttpEntity} based on + * properties of the message. The content of the entity will be decoded + * transparently for the consumer. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link ch.boye.httpclientandroidlib.impl.BHttpConnectionBase} + */ +@Immutable // assuming injected dependencies are immutable +@Deprecated +public class EntityDeserializer { + + private final ContentLengthStrategy lenStrategy; + + public EntityDeserializer(final ContentLengthStrategy lenStrategy) { + super(); + this.lenStrategy = Args.notNull(lenStrategy, "Content length strategy"); + } + + /** + * Creates a {@link BasicHttpEntity} based on properties of the given + * message. The content of the entity is created by wrapping + * {@link SessionInputBuffer} with a content decoder depending on the + * transfer mechanism used by the message. + * <p> + * This method is called by the public + * {@link #deserialize(SessionInputBuffer, HttpMessage)}. + * + * @param inbuffer the session input buffer. + * @param message the message. + * @return HTTP entity. + * @throws HttpException in case of HTTP protocol violation. + * @throws IOException in case of an I/O error. + */ + protected BasicHttpEntity doDeserialize( + final SessionInputBuffer inbuffer, + final HttpMessage message) throws HttpException, IOException { + final BasicHttpEntity entity = new BasicHttpEntity(); + + final long len = this.lenStrategy.determineLength(message); + if (len == ContentLengthStrategy.CHUNKED) { + entity.setChunked(true); + entity.setContentLength(-1); + entity.setContent(new ChunkedInputStream(inbuffer)); + } else if (len == ContentLengthStrategy.IDENTITY) { + entity.setChunked(false); + entity.setContentLength(-1); + entity.setContent(new IdentityInputStream(inbuffer)); + } else { + entity.setChunked(false); + entity.setContentLength(len); + entity.setContent(new ContentLengthInputStream(inbuffer, len)); + } + + final Header contentTypeHeader = message.getFirstHeader(HTTP.CONTENT_TYPE); + if (contentTypeHeader != null) { + entity.setContentType(contentTypeHeader); + } + final Header contentEncodingHeader = message.getFirstHeader(HTTP.CONTENT_ENCODING); + if (contentEncodingHeader != null) { + entity.setContentEncoding(contentEncodingHeader); + } + return entity; + } + + /** + * Creates an {@link HttpEntity} based on properties of the given message. + * The content of the entity is created by wrapping + * {@link SessionInputBuffer} with a content decoder depending on the + * transfer mechanism used by the message. + * <p> + * The content of the entity is NOT retrieved by this method. + * + * @param inbuffer the session input buffer. + * @param message the message. + * @return HTTP entity. + * @throws HttpException in case of HTTP protocol violation. + * @throws IOException in case of an I/O error. + */ + public HttpEntity deserialize( + final SessionInputBuffer inbuffer, + final HttpMessage message) throws HttpException, IOException { + Args.notNull(inbuffer, "Session input buffer"); + Args.notNull(message, "HTTP message"); + return doDeserialize(inbuffer, message); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/EntitySerializer.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/EntitySerializer.java new file mode 100644 index 000000000..f25115cef --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/EntitySerializer.java @@ -0,0 +1,121 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.entity; + +import java.io.IOException; +import java.io.OutputStream; + +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpMessage; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.entity.ContentLengthStrategy; +import ch.boye.httpclientandroidlib.impl.io.ChunkedOutputStream; +import ch.boye.httpclientandroidlib.impl.io.ContentLengthOutputStream; +import ch.boye.httpclientandroidlib.impl.io.IdentityOutputStream; +import ch.boye.httpclientandroidlib.io.SessionOutputBuffer; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * HTTP entity serializer. + * <p> + * This entity serializer currently supports "chunked" and "identitiy" + * transfer-coding and content length delimited content. + * <p> + * This class relies on a specific implementation of + * {@link ContentLengthStrategy} to determine the content length or transfer + * encoding of the entity. + * <p> + * This class writes out the content of {@link HttpEntity} to the data stream + * using a transfer coding based on properties on the HTTP message. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link ch.boye.httpclientandroidlib.impl.BHttpConnectionBase} + */ +@Immutable // assuming injected dependencies are immutable +@Deprecated +public class EntitySerializer { + + private final ContentLengthStrategy lenStrategy; + + public EntitySerializer(final ContentLengthStrategy lenStrategy) { + super(); + this.lenStrategy = Args.notNull(lenStrategy, "Content length strategy"); + } + + /** + * Creates a transfer codec based on properties of the given HTTP message + * and returns {@link OutputStream} instance that transparently encodes + * output data as it is being written out to the output stream. + * <p> + * This method is called by the public + * {@link #serialize(SessionOutputBuffer, HttpMessage, HttpEntity)}. + * + * @param outbuffer the session output buffer. + * @param message the HTTP message. + * @return output stream. + * @throws HttpException in case of HTTP protocol violation. + * @throws IOException in case of an I/O error. + */ + protected OutputStream doSerialize( + final SessionOutputBuffer outbuffer, + final HttpMessage message) throws HttpException, IOException { + final long len = this.lenStrategy.determineLength(message); + if (len == ContentLengthStrategy.CHUNKED) { + return new ChunkedOutputStream(outbuffer); + } else if (len == ContentLengthStrategy.IDENTITY) { + return new IdentityOutputStream(outbuffer); + } else { + return new ContentLengthOutputStream(outbuffer, len); + } + } + + /** + * Writes out the content of the given HTTP entity to the session output + * buffer based on properties of the given HTTP message. + * + * @param outbuffer the output session buffer. + * @param message the HTTP message. + * @param entity the HTTP entity to be written out. + * @throws HttpException in case of HTTP protocol violation. + * @throws IOException in case of an I/O error. + */ + public void serialize( + final SessionOutputBuffer outbuffer, + final HttpMessage message, + final HttpEntity entity) throws HttpException, IOException { + Args.notNull(outbuffer, "Session output buffer"); + Args.notNull(message, "HTTP message"); + Args.notNull(entity, "HTTP entity"); + final OutputStream outstream = doSerialize(outbuffer, message); + entity.writeTo(outstream); + outstream.close(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/LaxContentLengthStrategy.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/LaxContentLengthStrategy.java new file mode 100644 index 000000000..0f0dbaf15 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/LaxContentLengthStrategy.java @@ -0,0 +1,126 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.entity; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HeaderElement; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpMessage; +import ch.boye.httpclientandroidlib.ParseException; +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.entity.ContentLengthStrategy; +import ch.boye.httpclientandroidlib.protocol.HTTP; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * The lax implementation of the content length strategy. This class will ignore + * unrecognized transfer encodings and malformed <code>Content-Length</code> + * header values. + * <p/> + * This class recognizes "chunked" and "identitiy" transfer-coding only. + * + * @since 4.0 + */ +@Immutable +public class LaxContentLengthStrategy implements ContentLengthStrategy { + + public static final LaxContentLengthStrategy INSTANCE = new LaxContentLengthStrategy(); + + private final int implicitLen; + + /** + * Creates <tt>LaxContentLengthStrategy</tt> instance with the given length used per default + * when content length is not explicitly specified in the message. + * + * @param implicitLen implicit content length. + * + * @since 4.2 + */ + public LaxContentLengthStrategy(final int implicitLen) { + super(); + this.implicitLen = implicitLen; + } + + /** + * Creates <tt>LaxContentLengthStrategy</tt> instance. {@link ContentLengthStrategy#IDENTITY} + * is used per default when content length is not explicitly specified in the message. + */ + public LaxContentLengthStrategy() { + this(IDENTITY); + } + + public long determineLength(final HttpMessage message) throws HttpException { + Args.notNull(message, "HTTP message"); + + final Header transferEncodingHeader = message.getFirstHeader(HTTP.TRANSFER_ENCODING); + // We use Transfer-Encoding if present and ignore Content-Length. + // RFC2616, 4.4 item number 3 + if (transferEncodingHeader != null) { + final HeaderElement[] encodings; + try { + encodings = transferEncodingHeader.getElements(); + } catch (final ParseException px) { + throw new ProtocolException + ("Invalid Transfer-Encoding header value: " + + transferEncodingHeader, px); + } + // The chunked encoding must be the last one applied RFC2616, 14.41 + final int len = encodings.length; + if (HTTP.IDENTITY_CODING.equalsIgnoreCase(transferEncodingHeader.getValue())) { + return IDENTITY; + } else if ((len > 0) && (HTTP.CHUNK_CODING.equalsIgnoreCase( + encodings[len - 1].getName()))) { + return CHUNKED; + } else { + return IDENTITY; + } + } + final Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN); + if (contentLengthHeader != null) { + long contentlen = -1; + final Header[] headers = message.getHeaders(HTTP.CONTENT_LEN); + for (int i = headers.length - 1; i >= 0; i--) { + final Header header = headers[i]; + try { + contentlen = Long.parseLong(header.getValue()); + break; + } catch (final NumberFormatException ignore) { + } + // See if we can have better luck with another header, if present + } + if (contentlen >= 0) { + return contentlen; + } else { + return IDENTITY; + } + } + return this.implicitLen; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/StrictContentLengthStrategy.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/StrictContentLengthStrategy.java new file mode 100644 index 000000000..1693c3111 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/StrictContentLengthStrategy.java @@ -0,0 +1,116 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package ch.boye.httpclientandroidlib.impl.entity; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpMessage; +import ch.boye.httpclientandroidlib.HttpVersion; +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.entity.ContentLengthStrategy; +import ch.boye.httpclientandroidlib.protocol.HTTP; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * The strict implementation of the content length strategy. This class + * will throw {@link ProtocolException} if it encounters an unsupported + * transfer encoding or a malformed <code>Content-Length</code> header + * value. + * <p> + * This class recognizes "chunked" and "identitiy" transfer-coding only. + * + * @since 4.0 + */ +@Immutable +public class StrictContentLengthStrategy implements ContentLengthStrategy { + + public static final StrictContentLengthStrategy INSTANCE = new StrictContentLengthStrategy(); + + private final int implicitLen; + + /** + * Creates <tt>StrictContentLengthStrategy</tt> instance with the given length used per default + * when content length is not explicitly specified in the message. + * + * @param implicitLen implicit content length. + * + * @since 4.2 + */ + public StrictContentLengthStrategy(final int implicitLen) { + super(); + this.implicitLen = implicitLen; + } + + /** + * Creates <tt>StrictContentLengthStrategy</tt> instance. {@link ContentLengthStrategy#IDENTITY} + * is used per default when content length is not explicitly specified in the message. + */ + public StrictContentLengthStrategy() { + this(IDENTITY); + } + + public long determineLength(final HttpMessage message) throws HttpException { + Args.notNull(message, "HTTP message"); + // Although Transfer-Encoding is specified as a list, in practice + // it is either missing or has the single value "chunked". So we + // treat it as a single-valued header here. + final Header transferEncodingHeader = message.getFirstHeader(HTTP.TRANSFER_ENCODING); + if (transferEncodingHeader != null) { + final String s = transferEncodingHeader.getValue(); + if (HTTP.CHUNK_CODING.equalsIgnoreCase(s)) { + if (message.getProtocolVersion().lessEquals(HttpVersion.HTTP_1_0)) { + throw new ProtocolException( + "Chunked transfer encoding not allowed for " + + message.getProtocolVersion()); + } + return CHUNKED; + } else if (HTTP.IDENTITY_CODING.equalsIgnoreCase(s)) { + return IDENTITY; + } else { + throw new ProtocolException( + "Unsupported transfer encoding: " + s); + } + } + final Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN); + if (contentLengthHeader != null) { + final String s = contentLengthHeader.getValue(); + try { + final long len = Long.parseLong(s); + if (len < 0) { + throw new ProtocolException("Negative content length: " + s); + } + return len; + } catch (final NumberFormatException e) { + throw new ProtocolException("Invalid content length: " + s); + } + } + return this.implicitLen; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/package-info.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/package-info.java new file mode 100644 index 000000000..7566c4570 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/entity/package-info.java @@ -0,0 +1,31 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +/** + * Default implementations of entity content strategies. + */ +package ch.boye.httpclientandroidlib.impl.entity; |