diff options
Diffstat (limited to 'mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol')
35 files changed, 4023 insertions, 0 deletions
diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/BasicHttpContext.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/BasicHttpContext.java new file mode 100644 index 000000000..72c247a5e --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/BasicHttpContext.java @@ -0,0 +1,95 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import ch.boye.httpclientandroidlib.annotation.ThreadSafe; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Default implementation of {@link HttpContext}. + * <p> + * Please note instances of this class can be thread unsafe if the + * parent context is not thread safe. + * + * @since 4.0 + */ +@ThreadSafe +public class BasicHttpContext implements HttpContext { + + private final HttpContext parentContext; + private final Map<String, Object> map; + + public BasicHttpContext() { + this(null); + } + + public BasicHttpContext(final HttpContext parentContext) { + super(); + this.map = new ConcurrentHashMap<String, Object>(); + this.parentContext = parentContext; + } + + public Object getAttribute(final String id) { + Args.notNull(id, "Id"); + Object obj = this.map.get(id); + if (obj == null && this.parentContext != null) { + obj = this.parentContext.getAttribute(id); + } + return obj; + } + + public void setAttribute(final String id, final Object obj) { + Args.notNull(id, "Id"); + if (obj != null) { + this.map.put(id, obj); + } else { + this.map.remove(id); + } + } + + public Object removeAttribute(final String id) { + Args.notNull(id, "Id"); + return this.map.remove(id); + } + + /** + * @since 4.2 + */ + public void clear() { + this.map.clear(); + } + + @Override + public String toString() { + return this.map.toString(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/BasicHttpProcessor.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/BasicHttpProcessor.java new file mode 100644 index 000000000..1fa203cef --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/BasicHttpProcessor.java @@ -0,0 +1,246 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.HttpResponseInterceptor; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Default implementation of {@link HttpProcessor}. + * <p> + * Please note access to the internal structures of this class is not + * synchronized and therefore this class may be thread-unsafe. + * + * @since 4.0 + * + * @deprecated (4.3) + */ +@NotThreadSafe +@Deprecated +public final class BasicHttpProcessor implements + HttpProcessor, HttpRequestInterceptorList, HttpResponseInterceptorList, Cloneable { + + // Don't allow direct access, as nulls are not allowed + protected final List<HttpRequestInterceptor> requestInterceptors = new ArrayList<HttpRequestInterceptor>(); + protected final List<HttpResponseInterceptor> responseInterceptors = new ArrayList<HttpResponseInterceptor>(); + + public void addRequestInterceptor(final HttpRequestInterceptor itcp) { + if (itcp == null) { + return; + } + this.requestInterceptors.add(itcp); + } + + public void addRequestInterceptor( + final HttpRequestInterceptor itcp, final int index) { + if (itcp == null) { + return; + } + this.requestInterceptors.add(index, itcp); + } + + public void addResponseInterceptor( + final HttpResponseInterceptor itcp, final int index) { + if (itcp == null) { + return; + } + this.responseInterceptors.add(index, itcp); + } + + public void removeRequestInterceptorByClass(final Class<? extends HttpRequestInterceptor> clazz) { + for (final Iterator<HttpRequestInterceptor> it = this.requestInterceptors.iterator(); + it.hasNext(); ) { + final Object request = it.next(); + if (request.getClass().equals(clazz)) { + it.remove(); + } + } + } + + public void removeResponseInterceptorByClass(final Class<? extends HttpResponseInterceptor> clazz) { + for (final Iterator<HttpResponseInterceptor> it = this.responseInterceptors.iterator(); + it.hasNext(); ) { + final Object request = it.next(); + if (request.getClass().equals(clazz)) { + it.remove(); + } + } + } + + public final void addInterceptor(final HttpRequestInterceptor interceptor) { + addRequestInterceptor(interceptor); + } + + public final void addInterceptor(final HttpRequestInterceptor interceptor, final int index) { + addRequestInterceptor(interceptor, index); + } + + public int getRequestInterceptorCount() { + return this.requestInterceptors.size(); + } + + public HttpRequestInterceptor getRequestInterceptor(final int index) { + if ((index < 0) || (index >= this.requestInterceptors.size())) { + return null; + } + return this.requestInterceptors.get(index); + } + + public void clearRequestInterceptors() { + this.requestInterceptors.clear(); + } + + public void addResponseInterceptor(final HttpResponseInterceptor itcp) { + if (itcp == null) { + return; + } + this.responseInterceptors.add(itcp); + } + + public final void addInterceptor(final HttpResponseInterceptor interceptor) { + addResponseInterceptor(interceptor); + } + + public final void addInterceptor(final HttpResponseInterceptor interceptor, final int index) { + addResponseInterceptor(interceptor, index); + } + + public int getResponseInterceptorCount() { + return this.responseInterceptors.size(); + } + + public HttpResponseInterceptor getResponseInterceptor(final int index) { + if ((index < 0) || (index >= this.responseInterceptors.size())) { + return null; + } + return this.responseInterceptors.get(index); + } + + public void clearResponseInterceptors() { + this.responseInterceptors.clear(); + } + + /** + * Sets the interceptor lists. + * First, both interceptor lists maintained by this processor + * will be cleared. + * Subsequently, + * elements of the argument list that are request interceptors will be + * added to the request interceptor list. + * Elements that are response interceptors will be + * added to the response interceptor list. + * Elements that are both request and response interceptor will be + * added to both lists. + * Elements that are neither request nor response interceptor + * will be ignored. + * + * @param list the list of request and response interceptors + * from which to initialize + */ + public void setInterceptors(final List<?> list) { + Args.notNull(list, "Inteceptor list"); + this.requestInterceptors.clear(); + this.responseInterceptors.clear(); + for (final Object obj : list) { + if (obj instanceof HttpRequestInterceptor) { + addInterceptor((HttpRequestInterceptor) obj); + } + if (obj instanceof HttpResponseInterceptor) { + addInterceptor((HttpResponseInterceptor) obj); + } + } + } + + /** + * Clears both interceptor lists maintained by this processor. + */ + public void clearInterceptors() { + clearRequestInterceptors(); + clearResponseInterceptors(); + } + + public void process( + final HttpRequest request, + final HttpContext context) + throws IOException, HttpException { + for (final HttpRequestInterceptor interceptor : this.requestInterceptors) { + interceptor.process(request, context); + } + } + + public void process( + final HttpResponse response, + final HttpContext context) + throws IOException, HttpException { + for (final HttpResponseInterceptor interceptor : this.responseInterceptors) { + interceptor.process(response, context); + } + } + + /** + * Sets up the target to have the same list of interceptors + * as the current instance. + * + * @param target object to be initialised + */ + protected void copyInterceptors(final BasicHttpProcessor target) { + target.requestInterceptors.clear(); + target.requestInterceptors.addAll(this.requestInterceptors); + target.responseInterceptors.clear(); + target.responseInterceptors.addAll(this.responseInterceptors); + } + + /** + * Creates a copy of this instance + * + * @return new instance of the BasicHttpProcessor + */ + public BasicHttpProcessor copy() { + final BasicHttpProcessor clone = new BasicHttpProcessor(); + copyInterceptors(clone); + return clone; + } + + @Override + public Object clone() throws CloneNotSupportedException { + final BasicHttpProcessor clone = (BasicHttpProcessor) super.clone(); + copyInterceptors(clone); + return clone; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ChainBuilder.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ChainBuilder.java new file mode 100644 index 000000000..19971ffa1 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ChainBuilder.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.protocol; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; + +/** + * Builder class to build a linked list (chain) of unique class instances. Each class can have + * only one instance in the list. Useful for building lists of protocol interceptors. + * + * @see ImmutableHttpProcessor + * + * @since 4.3 + */ +@NotThreadSafe +final class ChainBuilder<E> { + + private final LinkedList<E> list; + private final Map<Class<?>, E> uniqueClasses; + + public ChainBuilder() { + this.list = new LinkedList<E>(); + this.uniqueClasses = new HashMap<Class<?>, E>(); + } + + private void ensureUnique(final E e) { + final E previous = this.uniqueClasses.remove(e.getClass()); + if (previous != null) { + this.list.remove(previous); + } + this.uniqueClasses.put(e.getClass(), e); + } + + public ChainBuilder<E> addFirst(final E e) { + if (e == null) { + return this; + } + ensureUnique(e); + this.list.addFirst(e); + return this; + } + + public ChainBuilder<E> addLast(final E e) { + if (e == null) { + return this; + } + ensureUnique(e); + this.list.addLast(e); + return this; + } + + public ChainBuilder<E> addAllFirst(final Collection<E> c) { + if (c == null) { + return this; + } + for (final E e: c) { + addFirst(e); + } + return this; + } + + public ChainBuilder<E> addAllFirst(final E... c) { + if (c == null) { + return this; + } + for (final E e: c) { + addFirst(e); + } + return this; + } + + public ChainBuilder<E> addAllLast(final Collection<E> c) { + if (c == null) { + return this; + } + for (final E e: c) { + addLast(e); + } + return this; + } + + public ChainBuilder<E> addAllLast(final E... c) { + if (c == null) { + return this; + } + for (final E e: c) { + addLast(e); + } + return this; + } + + public LinkedList<E> build() { + return new LinkedList<E>(this.list); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/DefaultedHttpContext.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/DefaultedHttpContext.java new file mode 100644 index 000000000..63ef87b98 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/DefaultedHttpContext.java @@ -0,0 +1,84 @@ +/* + * ==================================================================== + * 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.protocol; + +import ch.boye.httpclientandroidlib.util.Args; + +/** + * {@link HttpContext} implementation that delegates resolution of an attribute + * to the given default {@link HttpContext} instance if the attribute is not + * present in the local one. The state of the local context can be mutated, + * whereas the default context is treated as read-only. + * + * @since 4.0 + * + * @deprecated (4.3) no longer used. + */ +@Deprecated +public final class DefaultedHttpContext implements HttpContext { + + private final HttpContext local; + private final HttpContext defaults; + + public DefaultedHttpContext(final HttpContext local, final HttpContext defaults) { + super(); + this.local = Args.notNull(local, "HTTP context"); + this.defaults = defaults; + } + + public Object getAttribute(final String id) { + final Object obj = this.local.getAttribute(id); + if (obj == null) { + return this.defaults.getAttribute(id); + } else { + return obj; + } + } + + public Object removeAttribute(final String id) { + return this.local.removeAttribute(id); + } + + public void setAttribute(final String id, final Object obj) { + this.local.setAttribute(id, obj); + } + + public HttpContext getDefaults() { + return this.defaults; + } + + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + buf.append("[local: ").append(this.local); + buf.append("defaults: ").append(this.defaults); + buf.append("]"); + return buf.toString(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ExecutionContext.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ExecutionContext.java new file mode 100644 index 000000000..b27a481df --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ExecutionContext.java @@ -0,0 +1,80 @@ +/* + * ==================================================================== + * 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.protocol; + +/** + * {@link HttpContext} attribute names for protocol execution. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link HttpCoreContext}. + */ +@Deprecated +public interface ExecutionContext { + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.HttpConnection} object that + * represents the actual HTTP connection. + */ + public static final String HTTP_CONNECTION = "http.connection"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.HttpRequest} object that + * represents the actual HTTP request. + */ + public static final String HTTP_REQUEST = "http.request"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.HttpResponse} object that + * represents the actual HTTP response. + */ + public static final String HTTP_RESPONSE = "http.response"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.HttpHost} object that + * represents the connection target. + */ + public static final String HTTP_TARGET_HOST = "http.target_host"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.HttpHost} object that + * represents the connection proxy. + * + * @deprecated (4.3) do not use. + */ + @Deprecated + public static final String HTTP_PROXY_HOST = "http.proxy_host"; + + /** + * Attribute name of a {@link Boolean} object that represents the + * the flag indicating whether the actual request has been fully transmitted + * to the target host. + */ + public static final String HTTP_REQ_SENT = "http.request_sent"; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HTTP.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HTTP.java new file mode 100644 index 000000000..593b3bfdf --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HTTP.java @@ -0,0 +1,135 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.nio.charset.Charset; + +import ch.boye.httpclientandroidlib.Consts; + +/** + * Constants and static helpers related to the HTTP protocol. + * + * @since 4.0 + */ +public final class HTTP { + + public static final int CR = 13; // <US-ASCII CR, carriage return (13)> + public static final int LF = 10; // <US-ASCII LF, linefeed (10)> + public static final int SP = 32; // <US-ASCII SP, space (32)> + public static final int HT = 9; // <US-ASCII HT, horizontal-tab (9)> + + /** HTTP header definitions */ + public static final String TRANSFER_ENCODING = "Transfer-Encoding"; + public static final String CONTENT_LEN = "Content-Length"; + public static final String CONTENT_TYPE = "Content-Type"; + public static final String CONTENT_ENCODING = "Content-Encoding"; + public static final String EXPECT_DIRECTIVE = "Expect"; + public static final String CONN_DIRECTIVE = "Connection"; + public static final String TARGET_HOST = "Host"; + public static final String USER_AGENT = "User-Agent"; + public static final String DATE_HEADER = "Date"; + public static final String SERVER_HEADER = "Server"; + + /** HTTP expectations */ + public static final String EXPECT_CONTINUE = "100-continue"; + + /** HTTP connection control */ + public static final String CONN_CLOSE = "Close"; + public static final String CONN_KEEP_ALIVE = "Keep-Alive"; + + /** Transfer encoding definitions */ + public static final String CHUNK_CODING = "chunked"; + public static final String IDENTITY_CODING = "identity"; + + public static final Charset DEF_CONTENT_CHARSET = Consts.ISO_8859_1; + public static final Charset DEF_PROTOCOL_CHARSET = Consts.ASCII; + + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String UTF_8 = "UTF-8"; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String UTF_16 = "UTF-16"; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String US_ASCII = "US-ASCII"; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String ASCII = "ASCII"; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String ISO_8859_1 = "ISO-8859-1"; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String DEFAULT_CONTENT_CHARSET = ISO_8859_1; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String DEFAULT_PROTOCOL_CHARSET = US_ASCII; + /** + * @deprecated (4.2) + */ + @Deprecated + public final static String OCTET_STREAM_TYPE = "application/octet-stream"; + /** + * @deprecated (4.2) + */ + @Deprecated + public final static String PLAIN_TEXT_TYPE = "text/plain"; + /** + * @deprecated (4.2) + */ + @Deprecated + public final static String CHARSET_PARAM = "; charset="; + /** + * @deprecated (4.2) + */ + @Deprecated + public final static String DEFAULT_CONTENT_TYPE = OCTET_STREAM_TYPE; + + public static boolean isWhitespace(final char ch) { + return ch == SP || ch == HT || ch == CR || ch == LF; + } + + private HTTP() { + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpContext.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpContext.java new file mode 100644 index 000000000..c2b70ccea --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpContext.java @@ -0,0 +1,75 @@ +/* + * ==================================================================== + * 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.protocol; + +/** + * HttpContext represents execution state of an HTTP process. It is a structure + * that can be used to map an attribute name to an attribute value. + * <p/> + * The primary purpose of the HTTP context is to facilitate information sharing + * among various logically related components. HTTP context can be used + * to store a processing state for one message or several consecutive messages. + * Multiple logically related messages can participate in a logical session + * if the same context is reused between consecutive messages. + * <p>/ + * IMPORTANT: Please note HTTP context implementation, even when thread safe, + * may not be used concurrently by multiple threads, as the context may contain + * thread unsafe attributes. + * + * @since 4.0 + */ +public interface HttpContext { + + /** The prefix reserved for use by HTTP components. "http." */ + public static final String RESERVED_PREFIX = "http."; + + /** + * Obtains attribute with the given name. + * + * @param id the attribute name. + * @return attribute value, or <code>null</code> if not set. + */ + Object getAttribute(String id); + + /** + * Sets value of the attribute with the given name. + * + * @param id the attribute name. + * @param obj the attribute value. + */ + void setAttribute(String id, Object obj); + + /** + * Removes attribute with the given name from the context. + * + * @param id the attribute name. + * @return attribute value, or <code>null</code> if not set. + */ + Object removeAttribute(String id); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpCoreContext.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpCoreContext.java new file mode 100644 index 000000000..3d4262751 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpCoreContext.java @@ -0,0 +1,152 @@ +/* + * ==================================================================== + * 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.protocol; + +import ch.boye.httpclientandroidlib.HttpConnection; +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Implementation of {@link HttpContext} that provides convenience + * setters for user assignable attributes and getter for readable attributes. + * + * @since 4.3 + */ +@NotThreadSafe +public class HttpCoreContext implements HttpContext { + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.HttpConnection} object that + * represents the actual HTTP connection. + */ + public static final String HTTP_CONNECTION = "http.connection"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.HttpRequest} object that + * represents the actual HTTP request. + */ + public static final String HTTP_REQUEST = "http.request"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.HttpResponse} object that + * represents the actual HTTP response. + */ + public static final String HTTP_RESPONSE = "http.response"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.HttpHost} object that + * represents the connection target. + */ + public static final String HTTP_TARGET_HOST = "http.target_host"; + + /** + * Attribute name of a {@link Boolean} object that represents the + * the flag indicating whether the actual request has been fully transmitted + * to the target host. + */ + public static final String HTTP_REQ_SENT = "http.request_sent"; + + public static HttpCoreContext create() { + return new HttpCoreContext(new BasicHttpContext()); + } + + public static HttpCoreContext adapt(final HttpContext context) { + Args.notNull(context, "HTTP context"); + if (context instanceof HttpCoreContext) { + return (HttpCoreContext) context; + } else { + return new HttpCoreContext(context); + } + } + + private final HttpContext context; + + public HttpCoreContext(final HttpContext context) { + super(); + this.context = context; + } + + public HttpCoreContext() { + super(); + this.context = new BasicHttpContext(); + } + + public Object getAttribute(final String id) { + return context.getAttribute(id); + } + + public void setAttribute(final String id, final Object obj) { + context.setAttribute(id, obj); + } + + public Object removeAttribute(final String id) { + return context.removeAttribute(id); + } + + public <T> T getAttribute(final String attribname, final Class<T> clazz) { + Args.notNull(clazz, "Attribute class"); + final Object obj = getAttribute(attribname); + if (obj == null) { + return null; + } + return clazz.cast(obj); + } + + public <T extends HttpConnection> T getConnection(final Class<T> clazz) { + return getAttribute(HTTP_CONNECTION, clazz); + } + + public HttpConnection getConnection() { + return getAttribute(HTTP_CONNECTION, HttpConnection.class); + } + + public HttpRequest getRequest() { + return getAttribute(HTTP_REQUEST, HttpRequest.class); + } + + public boolean isRequestSent() { + final Boolean b = getAttribute(HTTP_REQ_SENT, Boolean.class); + return b != null && b.booleanValue(); + } + + public HttpResponse getResponse() { + return getAttribute(HTTP_RESPONSE, HttpResponse.class); + } + + public void setTargetHost(final HttpHost host) { + setAttribute(HTTP_TARGET_HOST, host); + } + + public HttpHost getTargetHost() { + return getAttribute(HTTP_TARGET_HOST, HttpHost.class); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpDateGenerator.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpDateGenerator.java new file mode 100644 index 000000000..8e99c1ea2 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpDateGenerator.java @@ -0,0 +1,77 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import ch.boye.httpclientandroidlib.annotation.GuardedBy; +import ch.boye.httpclientandroidlib.annotation.ThreadSafe; + +/** + * Generates a date in the format required by the HTTP protocol. + * + * @since 4.0 + */ +@ThreadSafe +public class HttpDateGenerator { + + /** Date format pattern used to generate the header in RFC 1123 format. */ + public static final + String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"; + + /** The time zone to use in the date header. */ + public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + + @GuardedBy("this") + private final DateFormat dateformat; + @GuardedBy("this") + private long dateAsLong = 0L; + @GuardedBy("this") + private String dateAsText = null; + + public HttpDateGenerator() { + super(); + this.dateformat = new SimpleDateFormat(PATTERN_RFC1123, Locale.US); + this.dateformat.setTimeZone(GMT); + } + + public synchronized String getCurrentDate() { + final long now = System.currentTimeMillis(); + if (now - this.dateAsLong > 1000) { + // Generate new date string + this.dateAsText = this.dateformat.format(new Date(now)); + this.dateAsLong = now; + } + return this.dateAsText; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpExpectationVerifier.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpExpectationVerifier.java new file mode 100644 index 000000000..105704616 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpExpectationVerifier.java @@ -0,0 +1,81 @@ +/* + * ==================================================================== + * 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.protocol; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpResponse; + +/** + * Defines an interface to verify whether an incoming HTTP request meets + * the target server's expectations. + *<p> + * The Expect request-header field is used to indicate that particular + * server behaviors are required by the client. + *</p> + *<pre> + * Expect = "Expect" ":" 1#expectation + * + * expectation = "100-continue" | expectation-extension + * expectation-extension = token [ "=" ( token | quoted-string ) + * *expect-params ] + * expect-params = ";" token [ "=" ( token | quoted-string ) ] + *</pre> + *<p> + * A server that does not understand or is unable to comply with any of + * the expectation values in the Expect field of a request MUST respond + * with appropriate error status. The server MUST respond with a 417 + * (Expectation Failed) status if any of the expectations cannot be met + * or, if there are other problems with the request, some other 4xx + * status. + *</p> + * + * @since 4.0 + */ +public interface HttpExpectationVerifier { + + /** + * Verifies whether the given request meets the server's expectations. + * <p> + * If the request fails to meet particular criteria, this method can + * trigger a terminal response back to the client by setting the status + * code of the response object to a value greater or equal to + * <code>200</code>. In this case the client will not have to transmit + * the request body. If the request meets expectations this method can + * terminate without modifying the response object. Per default the status + * code of the response object will be set to <code>100</code>. + * + * @param request the HTTP request. + * @param response the HTTP response. + * @param context the HTTP context. + * @throws HttpException in case of an HTTP protocol violation. + */ + void verify(HttpRequest request, HttpResponse response, HttpContext context) + throws HttpException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpProcessor.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpProcessor.java new file mode 100644 index 000000000..e4dac6795 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpProcessor.java @@ -0,0 +1,55 @@ +/* + * ==================================================================== + * 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.protocol; + +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.HttpResponseInterceptor; + +/** + * HTTP protocol processor is a collection of protocol interceptors that + * implements the 'Chain of Responsibility' pattern, where each individual + * protocol interceptor is expected to work on a particular aspect of the HTTP + * protocol the interceptor is responsible for. + * <p> + * Usually the order in which interceptors are executed should not matter as + * long as they do not depend on a particular state of the execution context. + * If protocol interceptors have interdependencies and therefore must be + * executed in a particular order, they should be added to the protocol + * processor in the same sequence as their expected execution order. + * <p> + * Protocol interceptors must be implemented as thread-safe. Similarly to + * servlets, protocol interceptors should not use instance variables unless + * access to those variables is synchronized. + * + * @since 4.0 + */ +public interface HttpProcessor + extends HttpRequestInterceptor, HttpResponseInterceptor { + + // no additional methods +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpProcessorBuilder.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpProcessorBuilder.java new file mode 100644 index 000000000..29dfccd60 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpProcessorBuilder.java @@ -0,0 +1,151 @@ +/* + * ==================================================================== + * 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.protocol; + +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.HttpResponseInterceptor; + +/** + * Builder for {@link HttpProcessor} instances. + * + * @since 4.3 + */ +public class HttpProcessorBuilder { + + private ChainBuilder<HttpRequestInterceptor> requestChainBuilder; + private ChainBuilder<HttpResponseInterceptor> responseChainBuilder; + + public static HttpProcessorBuilder create() { + return new HttpProcessorBuilder(); + } + + HttpProcessorBuilder() { + super(); + } + + private ChainBuilder<HttpRequestInterceptor> getRequestChainBuilder() { + if (requestChainBuilder == null) { + requestChainBuilder = new ChainBuilder<HttpRequestInterceptor>(); + } + return requestChainBuilder; + } + + private ChainBuilder<HttpResponseInterceptor> getResponseChainBuilder() { + if (responseChainBuilder == null) { + responseChainBuilder = new ChainBuilder<HttpResponseInterceptor>(); + } + return responseChainBuilder; + } + + public HttpProcessorBuilder addFirst(final HttpRequestInterceptor e) { + if (e == null) { + return this; + } + getRequestChainBuilder().addFirst(e); + return this; + } + + public HttpProcessorBuilder addLast(final HttpRequestInterceptor e) { + if (e == null) { + return this; + } + getRequestChainBuilder().addLast(e); + return this; + } + + public HttpProcessorBuilder add(final HttpRequestInterceptor e) { + return addLast(e); + } + + public HttpProcessorBuilder addAllFirst(final HttpRequestInterceptor... e) { + if (e == null) { + return this; + } + getRequestChainBuilder().addAllFirst(e); + return this; + } + + public HttpProcessorBuilder addAllLast(final HttpRequestInterceptor... e) { + if (e == null) { + return this; + } + getRequestChainBuilder().addAllLast(e); + return this; + } + + public HttpProcessorBuilder addAll(final HttpRequestInterceptor... e) { + return addAllLast(e); + } + + public HttpProcessorBuilder addFirst(final HttpResponseInterceptor e) { + if (e == null) { + return this; + } + getResponseChainBuilder().addFirst(e); + return this; + } + + public HttpProcessorBuilder addLast(final HttpResponseInterceptor e) { + if (e == null) { + return this; + } + getResponseChainBuilder().addLast(e); + return this; + } + + public HttpProcessorBuilder add(final HttpResponseInterceptor e) { + return addLast(e); + } + + public HttpProcessorBuilder addAllFirst(final HttpResponseInterceptor... e) { + if (e == null) { + return this; + } + getResponseChainBuilder().addAllFirst(e); + return this; + } + + public HttpProcessorBuilder addAllLast(final HttpResponseInterceptor... e) { + if (e == null) { + return this; + } + getResponseChainBuilder().addAllLast(e); + return this; + } + + public HttpProcessorBuilder addAll(final HttpResponseInterceptor... e) { + return addAllLast(e); + } + + public HttpProcessor build() { + return new ImmutableHttpProcessor( + requestChainBuilder != null ? requestChainBuilder.build() : null, + responseChainBuilder != null ? responseChainBuilder.build() : null); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestExecutor.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestExecutor.java new file mode 100644 index 000000000..d895f0420 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestExecutor.java @@ -0,0 +1,311 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpClientConnection; +import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.HttpStatus; +import ch.boye.httpclientandroidlib.HttpVersion; +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.ProtocolVersion; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * <tt>HttpRequestExecutor</tt> is a client side HTTP protocol handler based + * on the blocking (classic) I/O model. + * <p/> + * <tt>HttpRequestExecutor</tt> relies on {@link HttpProcessor} to generate + * mandatory protocol headers for all outgoing messages and apply common, + * cross-cutting message transformations to all incoming and outgoing messages. + * Application specific processing can be implemented outside + * <tt>HttpRequestExecutor</tt> once the request has been executed and + * a response has been received. + * + * @since 4.0 + */ +@Immutable +public class HttpRequestExecutor { + + public static final int DEFAULT_WAIT_FOR_CONTINUE = 3000; + + private final int waitForContinue; + + /** + * Creates new instance of HttpRequestExecutor. + * + * @since 4.3 + */ + public HttpRequestExecutor(final int waitForContinue) { + super(); + this.waitForContinue = Args.positive(waitForContinue, "Wait for continue time"); + } + + public HttpRequestExecutor() { + this(DEFAULT_WAIT_FOR_CONTINUE); + } + + /** + * Decide whether a response comes with an entity. + * The implementation in this class is based on RFC 2616. + * <br/> + * Derived executors can override this method to handle + * methods and response codes not specified in RFC 2616. + * + * @param request the request, to obtain the executed method + * @param response the response, to obtain the status code + */ + protected boolean canResponseHaveBody(final HttpRequest request, + final HttpResponse response) { + + if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) { + return false; + } + final int status = response.getStatusLine().getStatusCode(); + return status >= HttpStatus.SC_OK + && status != HttpStatus.SC_NO_CONTENT + && status != HttpStatus.SC_NOT_MODIFIED + && status != HttpStatus.SC_RESET_CONTENT; + } + + /** + * Sends the request and obtain a response. + * + * @param request the request to execute. + * @param conn the connection over which to execute the request. + * + * @return the response to the request. + * + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + public HttpResponse execute( + final HttpRequest request, + final HttpClientConnection conn, + final HttpContext context) throws IOException, HttpException { + Args.notNull(request, "HTTP request"); + Args.notNull(conn, "Client connection"); + Args.notNull(context, "HTTP context"); + try { + HttpResponse response = doSendRequest(request, conn, context); + if (response == null) { + response = doReceiveResponse(request, conn, context); + } + return response; + } catch (final IOException ex) { + closeConnection(conn); + throw ex; + } catch (final HttpException ex) { + closeConnection(conn); + throw ex; + } catch (final RuntimeException ex) { + closeConnection(conn); + throw ex; + } + } + + private static void closeConnection(final HttpClientConnection conn) { + try { + conn.close(); + } catch (final IOException ignore) { + } + } + + /** + * Pre-process the given request using the given protocol processor and + * initiates the process of request execution. + * + * @param request the request to prepare + * @param processor the processor to use + * @param context the context for sending the request + * + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + public void preProcess( + final HttpRequest request, + final HttpProcessor processor, + final HttpContext context) throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + Args.notNull(processor, "HTTP processor"); + Args.notNull(context, "HTTP context"); + context.setAttribute(HttpCoreContext.HTTP_REQUEST, request); + processor.process(request, context); + } + + /** + * Send the given request over the given connection. + * <p> + * This method also handles the expect-continue handshake if necessary. + * If it does not have to handle an expect-continue handshake, it will + * not use the connection for reading or anything else that depends on + * data coming in over the connection. + * + * @param request the request to send, already + * {@link #preProcess preprocessed} + * @param conn the connection over which to send the request, + * already established + * @param context the context for sending the request + * + * @return a terminal response received as part of an expect-continue + * handshake, or + * <code>null</code> if the expect-continue handshake is not used + * + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + protected HttpResponse doSendRequest( + final HttpRequest request, + final HttpClientConnection conn, + final HttpContext context) throws IOException, HttpException { + Args.notNull(request, "HTTP request"); + Args.notNull(conn, "Client connection"); + Args.notNull(context, "HTTP context"); + + HttpResponse response = null; + + context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); + context.setAttribute(HttpCoreContext.HTTP_REQ_SENT, Boolean.FALSE); + + conn.sendRequestHeader(request); + if (request instanceof HttpEntityEnclosingRequest) { + // Check for expect-continue handshake. We have to flush the + // headers and wait for an 100-continue response to handle it. + // If we get a different response, we must not send the entity. + boolean sendentity = true; + final ProtocolVersion ver = + request.getRequestLine().getProtocolVersion(); + if (((HttpEntityEnclosingRequest) request).expectContinue() && + !ver.lessEquals(HttpVersion.HTTP_1_0)) { + + conn.flush(); + // As suggested by RFC 2616 section 8.2.3, we don't wait for a + // 100-continue response forever. On timeout, send the entity. + if (conn.isResponseAvailable(this.waitForContinue)) { + response = conn.receiveResponseHeader(); + if (canResponseHaveBody(request, response)) { + conn.receiveResponseEntity(response); + } + final int status = response.getStatusLine().getStatusCode(); + if (status < 200) { + if (status != HttpStatus.SC_CONTINUE) { + throw new ProtocolException( + "Unexpected response: " + response.getStatusLine()); + } + // discard 100-continue + response = null; + } else { + sendentity = false; + } + } + } + if (sendentity) { + conn.sendRequestEntity((HttpEntityEnclosingRequest) request); + } + } + conn.flush(); + context.setAttribute(HttpCoreContext.HTTP_REQ_SENT, Boolean.TRUE); + return response; + } + + /** + * Waits for and receives a response. + * This method will automatically ignore intermediate responses + * with status code 1xx. + * + * @param request the request for which to obtain the response + * @param conn the connection over which the request was sent + * @param context the context for receiving the response + * + * @return the terminal response, not yet post-processed + * + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + protected HttpResponse doReceiveResponse( + final HttpRequest request, + final HttpClientConnection conn, + final HttpContext context) throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + Args.notNull(conn, "Client connection"); + Args.notNull(context, "HTTP context"); + HttpResponse response = null; + int statusCode = 0; + + while (response == null || statusCode < HttpStatus.SC_OK) { + + response = conn.receiveResponseHeader(); + if (canResponseHaveBody(request, response)) { + conn.receiveResponseEntity(response); + } + statusCode = response.getStatusLine().getStatusCode(); + + } // while intermediate response + + return response; + } + + /** + * Post-processes the given response using the given protocol processor and + * completes the process of request execution. + * <p> + * This method does <i>not</i> read the response entity, if any. + * The connection over which content of the response entity is being + * streamed from cannot be reused until + * {@link ch.boye.httpclientandroidlib.util.EntityUtils#consume(ch.boye.httpclientandroidlib.HttpEntity)} + * has been invoked. + * + * @param response the response object to post-process + * @param processor the processor to use + * @param context the context for post-processing the response + * + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + public void postProcess( + final HttpResponse response, + final HttpProcessor processor, + final HttpContext context) throws HttpException, IOException { + Args.notNull(response, "HTTP response"); + Args.notNull(processor, "HTTP processor"); + Args.notNull(context, "HTTP context"); + context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response); + processor.process(response, context); + } + +} // class HttpRequestExecutor diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandler.java new file mode 100644 index 000000000..b948ae65d --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandler.java @@ -0,0 +1,62 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpResponse; + +/** + * HttpRequestHandler represents a routine for processing of a specific group + * of HTTP requests. Protocol handlers are designed to take care of protocol + * specific aspects, whereas individual request handlers are expected to take + * care of application specific HTTP processing. The main purpose of a request + * handler is to generate a response object with a content entity to be sent + * back to the client in response to the given request + * + * @since 4.0 + */ +public interface HttpRequestHandler { + + /** + * Handles the request and produces a response to be sent back to + * the client. + * + * @param request the HTTP request. + * @param response the HTTP response. + * @param context the HTTP execution context. + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + void handle(HttpRequest request, HttpResponse response, HttpContext context) + throws HttpException, IOException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandlerMapper.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandlerMapper.java new file mode 100644 index 000000000..e97da4e88 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandlerMapper.java @@ -0,0 +1,50 @@ +/* + * ==================================================================== + * 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.protocol; + +import ch.boye.httpclientandroidlib.HttpRequest; + +/** + * HttpRequestHandlerMapper can be used to resolve an instance of + * {@link HttpRequestHandler} matching a particular {@link HttpRequest}. Usually the + * mapped request handler will be used to process the request. + * + * @since 4.3 + */ +public interface HttpRequestHandlerMapper { + + /** + * Looks up a handler matching the given request. + * + * @param request the request to map to a handler + * @return HTTP request handler or <code>null</code> if no match + * is found. + */ + HttpRequestHandler lookup(HttpRequest request); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandlerRegistry.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandlerRegistry.java new file mode 100644 index 000000000..3592d00ac --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandlerRegistry.java @@ -0,0 +1,107 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.util.Map; + +import ch.boye.httpclientandroidlib.annotation.ThreadSafe; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Maintains a map of HTTP request handlers keyed by a request URI pattern. + * <br> + * Patterns may have three formats: + * <ul> + * <li><code>*</code></li> + * <li><code>*<uri></code></li> + * <li><code><uri>*</code></li> + * </ul> + * <br> + * This class can be used to resolve an instance of + * {@link HttpRequestHandler} matching a particular request URI. Usually the + * resolved request handler will be used to process the request with the + * specified request URI. + * + * @since 4.0 + * @deprecated (4.3) use {@link UriHttpRequestHandlerMapper} + */ +@ThreadSafe // provided injected dependencies are thread-safe +@Deprecated +public class HttpRequestHandlerRegistry implements HttpRequestHandlerResolver { + + private final UriPatternMatcher<HttpRequestHandler> matcher; + + public HttpRequestHandlerRegistry() { + matcher = new UriPatternMatcher<HttpRequestHandler>(); + } + + /** + * Registers the given {@link HttpRequestHandler} as a handler for URIs + * matching the given pattern. + * + * @param pattern the pattern to register the handler for. + * @param handler the handler. + */ + public void register(final String pattern, final HttpRequestHandler handler) { + Args.notNull(pattern, "URI request pattern"); + Args.notNull(handler, "Request handler"); + matcher.register(pattern, handler); + } + + /** + * Removes registered handler, if exists, for the given pattern. + * + * @param pattern the pattern to unregister the handler for. + */ + public void unregister(final String pattern) { + matcher.unregister(pattern); + } + + /** + * Sets handlers from the given map. + * @param map the map containing handlers keyed by their URI patterns. + */ + public void setHandlers(final Map<String, HttpRequestHandler> map) { + matcher.setObjects(map); + } + + /** + * Get the handler map. + * @return The map of handlers and their associated URI patterns. + * + * @since 4.2 + */ + public Map<String, HttpRequestHandler> getHandlers() { + return matcher.getObjects(); + } + + public HttpRequestHandler lookup(final String requestURI) { + return matcher.lookup(requestURI); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandlerResolver.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandlerResolver.java new file mode 100644 index 000000000..a898b8d18 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestHandlerResolver.java @@ -0,0 +1,51 @@ +/* + * ==================================================================== + * 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.protocol; + +/** + * HttpRequestHandlerResolver can be used to resolve an instance of + * {@link HttpRequestHandler} matching a particular request URI. Usually the + * mapped request handler will be used to process the request with the + * specified request URI. + * + * @since 4.0 + * @deprecated see {@link HttpRequestHandlerMapper} + */ +@Deprecated +public interface HttpRequestHandlerResolver { + + /** + * Looks up a handler matching the given request URI. + * + * @param requestURI the request URI + * @return HTTP request handler or <code>null</code> if no match + * is found. + */ + HttpRequestHandler lookup(String requestURI); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestInterceptorList.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestInterceptorList.java new file mode 100644 index 000000000..da4fd6f86 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpRequestInterceptorList.java @@ -0,0 +1,103 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.util.List; + +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; + +/** + * Provides access to an ordered list of request interceptors. + * Lists are expected to be built upfront and used read-only afterwards + * for {@link HttpProcessor processing}. + * + * @since 4.0 + * + * @deprecated (4.3) + */ +@Deprecated +public interface HttpRequestInterceptorList { + + /** + * Appends a request interceptor to this list. + * + * @param interceptor the request interceptor to add + */ + void addRequestInterceptor(HttpRequestInterceptor interceptor); + + /** + * Inserts a request interceptor at the specified index. + * + * @param interceptor the request interceptor to add + * @param index the index to insert the interceptor at + */ + void addRequestInterceptor(HttpRequestInterceptor interceptor, int index); + + /** + * Obtains the current size of this list. + * + * @return the number of request interceptors in this list + */ + int getRequestInterceptorCount(); + + /** + * Obtains a request interceptor from this list. + * + * @param index the index of the interceptor to obtain, + * 0 for first + * + * @return the interceptor at the given index, or + * <code>null</code> if the index is out of range + */ + HttpRequestInterceptor getRequestInterceptor(int index); + + /** + * Removes all request interceptors from this list. + */ + void clearRequestInterceptors(); + + /** + * Removes all request interceptor of the specified class + * + * @param clazz the class of the instances to be removed. + */ + void removeRequestInterceptorByClass(Class<? extends HttpRequestInterceptor> clazz); + + /** + * Sets the request interceptors in this list. + * This list will be cleared and re-initialized to contain + * all request interceptors from the argument list. + * If the argument list includes elements that are not request + * interceptors, the behavior is implementation dependent. + * + * @param list the list of request interceptors + */ + void setInterceptors(List<?> list); + +} + diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpResponseInterceptorList.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpResponseInterceptorList.java new file mode 100644 index 000000000..9265b6738 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpResponseInterceptorList.java @@ -0,0 +1,103 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.util.List; + +import ch.boye.httpclientandroidlib.HttpResponseInterceptor; + +/** + * Provides access to an ordered list of response interceptors. + * Lists are expected to be built upfront and used read-only afterwards + * for {@link HttpProcessor processing}. + * + * @since 4.0 + * + * @deprecated (4.3) + */ +@Deprecated +public interface HttpResponseInterceptorList { + + /** + * Appends a response interceptor to this list. + * + * @param interceptor the response interceptor to add + */ + void addResponseInterceptor(HttpResponseInterceptor interceptor); + + /** + * Inserts a response interceptor at the specified index. + * + * @param interceptor the response interceptor to add + * @param index the index to insert the interceptor at + */ + void addResponseInterceptor(HttpResponseInterceptor interceptor, int index); + + /** + * Obtains the current size of this list. + * + * @return the number of response interceptors in this list + */ + int getResponseInterceptorCount(); + + /** + * Obtains a response interceptor from this list. + * + * @param index the index of the interceptor to obtain, + * 0 for first + * + * @return the interceptor at the given index, or + * <code>null</code> if the index is out of range + */ + HttpResponseInterceptor getResponseInterceptor(int index); + + /** + * Removes all response interceptors from this list. + */ + void clearResponseInterceptors(); + + /** + * Removes all response interceptor of the specified class + * + * @param clazz the class of the instances to be removed. + */ + void removeResponseInterceptorByClass(Class<? extends HttpResponseInterceptor> clazz); + + /** + * Sets the response interceptors in this list. + * This list will be cleared and re-initialized to contain + * all response interceptors from the argument list. + * If the argument list includes elements that are not response + * interceptors, the behavior is implementation dependent. + * + * @param list the list of response interceptors + */ + void setInterceptors(List<?> list); + +} + diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpService.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpService.java new file mode 100644 index 000000000..13defa2d9 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/HttpService.java @@ -0,0 +1,447 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.ConnectionReuseStrategy; +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.HttpResponseFactory; +import ch.boye.httpclientandroidlib.HttpServerConnection; +import ch.boye.httpclientandroidlib.HttpStatus; +import ch.boye.httpclientandroidlib.HttpVersion; +import ch.boye.httpclientandroidlib.MethodNotSupportedException; +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.UnsupportedHttpVersionException; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.entity.ByteArrayEntity; +import ch.boye.httpclientandroidlib.impl.DefaultConnectionReuseStrategy; +import ch.boye.httpclientandroidlib.impl.DefaultHttpResponseFactory; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.util.Args; +import ch.boye.httpclientandroidlib.util.EncodingUtils; +import ch.boye.httpclientandroidlib.util.EntityUtils; + +/** + * <tt>HttpService</tt> is a server side HTTP protocol handler based on + * the classic (blocking) I/O model. + * <p/> + * <tt>HttpService</tt> relies on {@link HttpProcessor} to generate mandatory + * protocol headers for all outgoing messages and apply common, cross-cutting + * message transformations to all incoming and outgoing messages, whereas + * individual {@link HttpRequestHandler}s are expected to implement + * application specific content generation and processing. + * <p/> + * <tt>HttpService</tt> uses {@link HttpRequestHandlerMapper} to map + * matching request handler for a particular request URI of an incoming HTTP + * request. + * <p/> + * <tt>HttpService</tt> can use optional {@link HttpExpectationVerifier} + * to ensure that incoming requests meet server's expectations. + * + * @since 4.0 + */ +@SuppressWarnings("deprecation") +@Immutable // provided injected dependencies are immutable and deprecated methods are not used +public class HttpService { + + /** + * TODO: make all variables final in the next major version + */ + private volatile HttpParams params = null; + private volatile HttpProcessor processor = null; + private volatile HttpRequestHandlerMapper handlerMapper = null; + private volatile ConnectionReuseStrategy connStrategy = null; + private volatile HttpResponseFactory responseFactory = null; + private volatile HttpExpectationVerifier expectationVerifier = null; + + /** + * Create a new HTTP service. + * + * @param processor the processor to use on requests and responses + * @param connStrategy the connection reuse strategy + * @param responseFactory the response factory + * @param handlerResolver the handler resolver. May be null. + * @param expectationVerifier the expectation verifier. May be null. + * @param params the HTTP parameters + * + * @since 4.1 + * @deprecated (4.3) use {@link HttpService#HttpService(HttpProcessor, ConnectionReuseStrategy, + * HttpResponseFactory, HttpRequestHandlerMapper, HttpExpectationVerifier)} + */ + @Deprecated + public HttpService( + final HttpProcessor processor, + final ConnectionReuseStrategy connStrategy, + final HttpResponseFactory responseFactory, + final HttpRequestHandlerResolver handlerResolver, + final HttpExpectationVerifier expectationVerifier, + final HttpParams params) { + this(processor, + connStrategy, + responseFactory, + new HttpRequestHandlerResolverAdapter(handlerResolver), + expectationVerifier); + this.params = params; + } + + /** + * Create a new HTTP service. + * + * @param processor the processor to use on requests and responses + * @param connStrategy the connection reuse strategy + * @param responseFactory the response factory + * @param handlerResolver the handler resolver. May be null. + * @param params the HTTP parameters + * + * @since 4.1 + * @deprecated (4.3) use {@link HttpService#HttpService(HttpProcessor, ConnectionReuseStrategy, + * HttpResponseFactory, HttpRequestHandlerMapper)} + */ + @Deprecated + public HttpService( + final HttpProcessor processor, + final ConnectionReuseStrategy connStrategy, + final HttpResponseFactory responseFactory, + final HttpRequestHandlerResolver handlerResolver, + final HttpParams params) { + this(processor, + connStrategy, + responseFactory, + new HttpRequestHandlerResolverAdapter(handlerResolver), + null); + this.params = params; + } + + /** + * Create a new HTTP service. + * + * @param proc the processor to use on requests and responses + * @param connStrategy the connection reuse strategy + * @param responseFactory the response factory + * + * @deprecated (4.1) use {@link HttpService#HttpService(HttpProcessor, + * ConnectionReuseStrategy, HttpResponseFactory, HttpRequestHandlerResolver, HttpParams)} + */ + @Deprecated + public HttpService( + final HttpProcessor proc, + final ConnectionReuseStrategy connStrategy, + final HttpResponseFactory responseFactory) { + super(); + setHttpProcessor(proc); + setConnReuseStrategy(connStrategy); + setResponseFactory(responseFactory); + } + + /** + * Create a new HTTP service. + * + * @param processor the processor to use on requests and responses + * @param connStrategy the connection reuse strategy. If <code>null</code> + * {@link DefaultConnectionReuseStrategy#INSTANCE} will be used. + * @param responseFactory the response factory. If <code>null</code> + * {@link DefaultHttpResponseFactory#INSTANCE} will be used. + * @param handlerMapper the handler mapper. May be null. + * @param expectationVerifier the expectation verifier. May be null. + * + * @since 4.3 + */ + public HttpService( + final HttpProcessor processor, + final ConnectionReuseStrategy connStrategy, + final HttpResponseFactory responseFactory, + final HttpRequestHandlerMapper handlerMapper, + final HttpExpectationVerifier expectationVerifier) { + super(); + this.processor = Args.notNull(processor, "HTTP processor"); + this.connStrategy = connStrategy != null ? connStrategy : + DefaultConnectionReuseStrategy.INSTANCE; + this.responseFactory = responseFactory != null ? responseFactory : + DefaultHttpResponseFactory.INSTANCE; + this.handlerMapper = handlerMapper; + this.expectationVerifier = expectationVerifier; + } + + /** + * Create a new HTTP service. + * + * @param processor the processor to use on requests and responses + * @param connStrategy the connection reuse strategy. If <code>null</code> + * {@link DefaultConnectionReuseStrategy#INSTANCE} will be used. + * @param responseFactory the response factory. If <code>null</code> + * {@link DefaultHttpResponseFactory#INSTANCE} will be used. + * @param handlerMapper the handler mapper. May be null. + * + * @since 4.3 + */ + public HttpService( + final HttpProcessor processor, + final ConnectionReuseStrategy connStrategy, + final HttpResponseFactory responseFactory, + final HttpRequestHandlerMapper handlerMapper) { + this(processor, connStrategy, responseFactory, handlerMapper, null); + } + + /** + * Create a new HTTP service. + * + * @param processor the processor to use on requests and responses + * @param handlerMapper the handler mapper. May be null. + * + * @since 4.3 + */ + public HttpService( + final HttpProcessor processor, final HttpRequestHandlerMapper handlerMapper) { + this(processor, null, null, handlerMapper, null); + } + + /** + * @deprecated (4.1) set {@link HttpProcessor} using constructor + */ + @Deprecated + public void setHttpProcessor(final HttpProcessor processor) { + Args.notNull(processor, "HTTP processor"); + this.processor = processor; + } + + /** + * @deprecated (4.1) set {@link ConnectionReuseStrategy} using constructor + */ + @Deprecated + public void setConnReuseStrategy(final ConnectionReuseStrategy connStrategy) { + Args.notNull(connStrategy, "Connection reuse strategy"); + this.connStrategy = connStrategy; + } + + /** + * @deprecated (4.1) set {@link HttpResponseFactory} using constructor + */ + @Deprecated + public void setResponseFactory(final HttpResponseFactory responseFactory) { + Args.notNull(responseFactory, "Response factory"); + this.responseFactory = responseFactory; + } + + /** + * @deprecated (4.1) set {@link HttpResponseFactory} using constructor + */ + @Deprecated + public void setParams(final HttpParams params) { + this.params = params; + } + + /** + * @deprecated (4.1) set {@link HttpRequestHandlerResolver} using constructor + */ + @Deprecated + public void setHandlerResolver(final HttpRequestHandlerResolver handlerResolver) { + this.handlerMapper = new HttpRequestHandlerResolverAdapter(handlerResolver); + } + + /** + * @deprecated (4.1) set {@link HttpExpectationVerifier} using constructor + */ + @Deprecated + public void setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) { + this.expectationVerifier = expectationVerifier; + } + + /** + * @deprecated (4.3) no longer used. + */ + @Deprecated + public HttpParams getParams() { + return this.params; + } + + /** + * Handles receives one HTTP request over the given connection within the + * given execution context and sends a response back to the client. + * + * @param conn the active connection to the client + * @param context the actual execution context. + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + public void handleRequest( + final HttpServerConnection conn, + final HttpContext context) throws IOException, HttpException { + + context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); + + HttpResponse response = null; + + try { + + final HttpRequest request = conn.receiveRequestHeader(); + if (request instanceof HttpEntityEnclosingRequest) { + + if (((HttpEntityEnclosingRequest) request).expectContinue()) { + response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, + HttpStatus.SC_CONTINUE, context); + if (this.expectationVerifier != null) { + try { + this.expectationVerifier.verify(request, response, context); + } catch (final HttpException ex) { + response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0, + HttpStatus.SC_INTERNAL_SERVER_ERROR, context); + handleException(ex, response); + } + } + if (response.getStatusLine().getStatusCode() < 200) { + // Send 1xx response indicating the server expections + // have been met + conn.sendResponseHeader(response); + conn.flush(); + response = null; + conn.receiveRequestEntity((HttpEntityEnclosingRequest) request); + } + } else { + conn.receiveRequestEntity((HttpEntityEnclosingRequest) request); + } + } + + context.setAttribute(HttpCoreContext.HTTP_REQUEST, request); + + if (response == null) { + response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, + HttpStatus.SC_OK, context); + this.processor.process(request, context); + doService(request, response, context); + } + + // Make sure the request content is fully consumed + if (request instanceof HttpEntityEnclosingRequest) { + final HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); + EntityUtils.consume(entity); + } + + } catch (final HttpException ex) { + response = this.responseFactory.newHttpResponse + (HttpVersion.HTTP_1_0, HttpStatus.SC_INTERNAL_SERVER_ERROR, + context); + handleException(ex, response); + } + + context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response); + + this.processor.process(response, context); + conn.sendResponseHeader(response); + conn.sendResponseEntity(response); + conn.flush(); + + if (!this.connStrategy.keepAlive(response, context)) { + conn.close(); + } + } + + /** + * Handles the given exception and generates an HTTP response to be sent + * back to the client to inform about the exceptional condition encountered + * in the course of the request processing. + * + * @param ex the exception. + * @param response the HTTP response. + */ + protected void handleException(final HttpException ex, final HttpResponse response) { + if (ex instanceof MethodNotSupportedException) { + response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED); + } else if (ex instanceof UnsupportedHttpVersionException) { + response.setStatusCode(HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED); + } else if (ex instanceof ProtocolException) { + response.setStatusCode(HttpStatus.SC_BAD_REQUEST); + } else { + response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR); + } + String message = ex.getMessage(); + if (message == null) { + message = ex.toString(); + } + final byte[] msg = EncodingUtils.getAsciiBytes(message); + final ByteArrayEntity entity = new ByteArrayEntity(msg); + entity.setContentType("text/plain; charset=US-ASCII"); + response.setEntity(entity); + } + + /** + * The default implementation of this method attempts to resolve an + * {@link HttpRequestHandler} for the request URI of the given request + * and, if found, executes its + * {@link HttpRequestHandler#handle(HttpRequest, HttpResponse, HttpContext)} + * method. + * <p> + * Super-classes can override this method in order to provide a custom + * implementation of the request processing logic. + * + * @param request the HTTP request. + * @param response the HTTP response. + * @param context the execution context. + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + protected void doService( + final HttpRequest request, + final HttpResponse response, + final HttpContext context) throws HttpException, IOException { + HttpRequestHandler handler = null; + if (this.handlerMapper != null) { + handler = this.handlerMapper.lookup(request); + } + if (handler != null) { + handler.handle(request, response, context); + } else { + response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED); + } + } + + /** + * Adaptor class to transition from HttpRequestHandlerResolver to HttpRequestHandlerMapper. + */ + @Deprecated + private static class HttpRequestHandlerResolverAdapter implements HttpRequestHandlerMapper { + + private final HttpRequestHandlerResolver resolver; + + public HttpRequestHandlerResolverAdapter(final HttpRequestHandlerResolver resolver) { + this.resolver = resolver; + } + + public HttpRequestHandler lookup(final HttpRequest request) { + return resolver.lookup(request.getRequestLine().getUri()); + } + + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ImmutableHttpProcessor.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ImmutableHttpProcessor.java new file mode 100644 index 000000000..8cb80c91b --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ImmutableHttpProcessor.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.protocol; + +import java.io.IOException; +import java.util.List; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.HttpResponseInterceptor; +import ch.boye.httpclientandroidlib.annotation.ThreadSafe; + +/** + * Immutable {@link HttpProcessor}. + * + * @since 4.1 + */ +@ThreadSafe // provided injected dependencies are immutable +public final class ImmutableHttpProcessor implements HttpProcessor { + + private final HttpRequestInterceptor[] requestInterceptors; + private final HttpResponseInterceptor[] responseInterceptors; + + public ImmutableHttpProcessor( + final HttpRequestInterceptor[] requestInterceptors, + final HttpResponseInterceptor[] responseInterceptors) { + super(); + if (requestInterceptors != null) { + final int l = requestInterceptors.length; + this.requestInterceptors = new HttpRequestInterceptor[l]; + System.arraycopy(requestInterceptors, 0, this.requestInterceptors, 0, l); + } else { + this.requestInterceptors = new HttpRequestInterceptor[0]; + } + if (responseInterceptors != null) { + final int l = responseInterceptors.length; + this.responseInterceptors = new HttpResponseInterceptor[l]; + System.arraycopy(responseInterceptors, 0, this.responseInterceptors, 0, l); + } else { + this.responseInterceptors = new HttpResponseInterceptor[0]; + } + } + + /** + * @since 4.3 + */ + public ImmutableHttpProcessor( + final List<HttpRequestInterceptor> requestInterceptors, + final List<HttpResponseInterceptor> responseInterceptors) { + super(); + if (requestInterceptors != null) { + final int l = requestInterceptors.size(); + this.requestInterceptors = requestInterceptors.toArray(new HttpRequestInterceptor[l]); + } else { + this.requestInterceptors = new HttpRequestInterceptor[0]; + } + if (responseInterceptors != null) { + final int l = responseInterceptors.size(); + this.responseInterceptors = responseInterceptors.toArray(new HttpResponseInterceptor[l]); + } else { + this.responseInterceptors = new HttpResponseInterceptor[0]; + } + } + + /** + * @deprecated (4.3) do not use. + */ + @Deprecated + public ImmutableHttpProcessor( + final HttpRequestInterceptorList requestInterceptors, + final HttpResponseInterceptorList responseInterceptors) { + super(); + if (requestInterceptors != null) { + final int count = requestInterceptors.getRequestInterceptorCount(); + this.requestInterceptors = new HttpRequestInterceptor[count]; + for (int i = 0; i < count; i++) { + this.requestInterceptors[i] = requestInterceptors.getRequestInterceptor(i); + } + } else { + this.requestInterceptors = new HttpRequestInterceptor[0]; + } + if (responseInterceptors != null) { + final int count = responseInterceptors.getResponseInterceptorCount(); + this.responseInterceptors = new HttpResponseInterceptor[count]; + for (int i = 0; i < count; i++) { + this.responseInterceptors[i] = responseInterceptors.getResponseInterceptor(i); + } + } else { + this.responseInterceptors = new HttpResponseInterceptor[0]; + } + } + + public ImmutableHttpProcessor(final HttpRequestInterceptor... requestInterceptors) { + this(requestInterceptors, null); + } + + public ImmutableHttpProcessor(final HttpResponseInterceptor... responseInterceptors) { + this(null, responseInterceptors); + } + + public void process( + final HttpRequest request, + final HttpContext context) throws IOException, HttpException { + for (final HttpRequestInterceptor requestInterceptor : this.requestInterceptors) { + requestInterceptor.process(request, context); + } + } + + public void process( + final HttpResponse response, + final HttpContext context) throws IOException, HttpException { + for (final HttpResponseInterceptor responseInterceptor : this.responseInterceptors) { + responseInterceptor.process(response, context); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestConnControl.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestConnControl.java new file mode 100644 index 000000000..1db509599 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestConnControl.java @@ -0,0 +1,69 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * RequestConnControl is responsible for adding <code>Connection</code> header + * to the outgoing requests, which is essential for managing persistence of + * <code>HTTP/1.0</code> connections. This interceptor is recommended for + * client side protocol processors. + * + * @since 4.0 + */ +@Immutable +public class RequestConnControl implements HttpRequestInterceptor { + + public RequestConnControl() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + + final String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase("CONNECT")) { + return; + } + + if (!request.containsHeader(HTTP.CONN_DIRECTIVE)) { + // Default policy is to keep connection alive + // whenever possible + request.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestContent.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestContent.java new file mode 100644 index 000000000..2f90ad6d8 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestContent.java @@ -0,0 +1,127 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.HttpVersion; +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.ProtocolVersion; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * RequestContent is the most important interceptor for outgoing requests. + * It is responsible for delimiting content length by adding + * <code>Content-Length</code> or <code>Transfer-Content</code> headers based + * on the properties of the enclosed entity and the protocol version. + * This interceptor is required for correct functioning of client side protocol + * processors. + * + * @since 4.0 + */ +@Immutable +public class RequestContent implements HttpRequestInterceptor { + + private final boolean overwrite; + + /** + * Default constructor. The <code>Content-Length</code> or <code>Transfer-Encoding</code> + * will cause the interceptor to throw {@link ProtocolException} if already present in the + * response message. + */ + public RequestContent() { + this(false); + } + + /** + * Constructor that can be used to fine-tune behavior of this interceptor. + * + * @param overwrite If set to <code>true</code> the <code>Content-Length</code> and + * <code>Transfer-Encoding</code> headers will be created or updated if already present. + * If set to <code>false</code> the <code>Content-Length</code> and + * <code>Transfer-Encoding</code> headers will cause the interceptor to throw + * {@link ProtocolException} if already present in the response message. + * + * @since 4.2 + */ + public RequestContent(final boolean overwrite) { + super(); + this.overwrite = overwrite; + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + if (request instanceof HttpEntityEnclosingRequest) { + if (this.overwrite) { + request.removeHeaders(HTTP.TRANSFER_ENCODING); + request.removeHeaders(HTTP.CONTENT_LEN); + } else { + if (request.containsHeader(HTTP.TRANSFER_ENCODING)) { + throw new ProtocolException("Transfer-encoding header already present"); + } + if (request.containsHeader(HTTP.CONTENT_LEN)) { + throw new ProtocolException("Content-Length header already present"); + } + } + final ProtocolVersion ver = request.getRequestLine().getProtocolVersion(); + final HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); + if (entity == null) { + request.addHeader(HTTP.CONTENT_LEN, "0"); + return; + } + // Must specify a transfer encoding or a content length + if (entity.isChunked() || entity.getContentLength() < 0) { + if (ver.lessEquals(HttpVersion.HTTP_1_0)) { + throw new ProtocolException( + "Chunked transfer encoding not allowed for " + ver); + } + request.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING); + } else { + request.addHeader(HTTP.CONTENT_LEN, Long.toString(entity.getContentLength())); + } + // Specify a content type if known + if (entity.getContentType() != null && !request.containsHeader( + HTTP.CONTENT_TYPE )) { + request.addHeader(entity.getContentType()); + } + // Specify a content encoding if known + if (entity.getContentEncoding() != null && !request.containsHeader( + HTTP.CONTENT_ENCODING)) { + request.addHeader(entity.getContentEncoding()); + } + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestDate.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestDate.java new file mode 100644 index 000000000..a2a0fa8b6 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestDate.java @@ -0,0 +1,65 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.annotation.ThreadSafe; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * RequestDate interceptor is responsible for adding <code>Date</code> header + * to the outgoing requests This interceptor is optional for client side + * protocol processors. + * + * @since 4.0 + */ +@ThreadSafe +public class RequestDate implements HttpRequestInterceptor { + + private static final HttpDateGenerator DATE_GENERATOR = new HttpDateGenerator(); + + public RequestDate() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + if ((request instanceof HttpEntityEnclosingRequest) && + !request.containsHeader(HTTP.DATE_HEADER)) { + final String httpdate = DATE_GENERATOR.getCurrentDate(); + request.setHeader(HTTP.DATE_HEADER, httpdate); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestExpectContinue.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestExpectContinue.java new file mode 100644 index 000000000..16cb8cd1c --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestExpectContinue.java @@ -0,0 +1,93 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.HttpVersion; +import ch.boye.httpclientandroidlib.ProtocolVersion; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.params.CoreProtocolPNames; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * RequestExpectContinue is responsible for enabling the 'expect-continue' + * handshake by adding <code>Expect</code> header. This interceptor is + * recommended for client side protocol processors. + * + * @since 4.0 + */ +@Immutable +@SuppressWarnings("deprecation") +public class RequestExpectContinue implements HttpRequestInterceptor { + + private final boolean activeByDefault; + + /** + * @deprecated (4.3) use {@link ch.boye.httpclientandroidlib.protocol.RequestExpectContinue#RequestExpectContinue(boolean)} + */ + @Deprecated + public RequestExpectContinue() { + this(false); + } + + /** + * @since 4.3 + */ + public RequestExpectContinue(final boolean activeByDefault) { + super(); + this.activeByDefault = activeByDefault; + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + + if (!request.containsHeader(HTTP.EXPECT_DIRECTIVE)) { + if (request instanceof HttpEntityEnclosingRequest) { + final ProtocolVersion ver = request.getRequestLine().getProtocolVersion(); + final HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); + // Do not send the expect header if request body is known to be empty + if (entity != null + && entity.getContentLength() != 0 && !ver.lessEquals(HttpVersion.HTTP_1_0)) { + final boolean active = request.getParams().getBooleanParameter( + CoreProtocolPNames.USE_EXPECT_CONTINUE, this.activeByDefault); + if (active) { + request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE); + } + } + } + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestTargetHost.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestTargetHost.java new file mode 100644 index 000000000..531a8a235 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestTargetHost.java @@ -0,0 +1,95 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; +import java.net.InetAddress; + +import ch.boye.httpclientandroidlib.HttpConnection; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.HttpInetConnection; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.HttpVersion; +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.ProtocolVersion; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * RequestTargetHost is responsible for adding <code>Host</code> header. This + * interceptor is required for client side protocol processors. + * + * @since 4.0 + */ +@Immutable +public class RequestTargetHost implements HttpRequestInterceptor { + + public RequestTargetHost() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + + final HttpCoreContext corecontext = HttpCoreContext.adapt(context); + + final ProtocolVersion ver = request.getRequestLine().getProtocolVersion(); + final String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase("CONNECT") && ver.lessEquals(HttpVersion.HTTP_1_0)) { + return; + } + + if (!request.containsHeader(HTTP.TARGET_HOST)) { + HttpHost targethost = corecontext.getTargetHost(); + if (targethost == null) { + final HttpConnection conn = corecontext.getConnection(); + if (conn instanceof HttpInetConnection) { + // Populate the context with a default HTTP host based on the + // inet address of the target host + final InetAddress address = ((HttpInetConnection) conn).getRemoteAddress(); + final int port = ((HttpInetConnection) conn).getRemotePort(); + if (address != null) { + targethost = new HttpHost(address.getHostName(), port); + } + } + if (targethost == null) { + if (ver.lessEquals(HttpVersion.HTTP_1_0)) { + return; + } else { + throw new ProtocolException("Target host missing"); + } + } + } + request.addHeader(HTTP.TARGET_HOST, targethost.toHostString()); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestUserAgent.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestUserAgent.java new file mode 100644 index 000000000..23f4a45a7 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/RequestUserAgent.java @@ -0,0 +1,79 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.params.CoreProtocolPNames; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * RequestUserAgent is responsible for adding <code>User-Agent</code> header. + * This interceptor is recommended for client side protocol processors. + * + * @since 4.0 + */ +@SuppressWarnings("deprecation") +@Immutable +public class RequestUserAgent implements HttpRequestInterceptor { + + private final String userAgent; + + public RequestUserAgent(final String userAgent) { + super(); + this.userAgent = userAgent; + } + + public RequestUserAgent() { + this(null); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + if (!request.containsHeader(HTTP.USER_AGENT)) { + String s = null; + final HttpParams params = request.getParams(); + if (params != null) { + s = (String) params.getParameter(CoreProtocolPNames.USER_AGENT); + } + if (s == null) { + s = this.userAgent; + } + if (s != null) { + request.addHeader(HTTP.USER_AGENT, s); + } + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseConnControl.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseConnControl.java new file mode 100644 index 000000000..29014e32f --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseConnControl.java @@ -0,0 +1,105 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.HttpResponseInterceptor; +import ch.boye.httpclientandroidlib.HttpStatus; +import ch.boye.httpclientandroidlib.HttpVersion; +import ch.boye.httpclientandroidlib.ProtocolVersion; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * ResponseConnControl is responsible for adding <code>Connection</code> header + * to the outgoing responses, which is essential for managing persistence of + * <code>HTTP/1.0</code> connections. This interceptor is recommended for + * server side protocol processors. + * + * @since 4.0 + */ +@Immutable +public class ResponseConnControl implements HttpResponseInterceptor { + + public ResponseConnControl() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + Args.notNull(response, "HTTP response"); + + final HttpCoreContext corecontext = HttpCoreContext.adapt(context); + + // Always drop connection after certain type of responses + final int status = response.getStatusLine().getStatusCode(); + if (status == HttpStatus.SC_BAD_REQUEST || + status == HttpStatus.SC_REQUEST_TIMEOUT || + status == HttpStatus.SC_LENGTH_REQUIRED || + status == HttpStatus.SC_REQUEST_TOO_LONG || + status == HttpStatus.SC_REQUEST_URI_TOO_LONG || + status == HttpStatus.SC_SERVICE_UNAVAILABLE || + status == HttpStatus.SC_NOT_IMPLEMENTED) { + response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); + return; + } + final Header explicit = response.getFirstHeader(HTTP.CONN_DIRECTIVE); + if (explicit != null && HTTP.CONN_CLOSE.equalsIgnoreCase(explicit.getValue())) { + // Connection persistence explicitly disabled + return; + } + // Always drop connection for HTTP/1.0 responses and below + // if the content body cannot be correctly delimited + final HttpEntity entity = response.getEntity(); + if (entity != null) { + final ProtocolVersion ver = response.getStatusLine().getProtocolVersion(); + if (entity.getContentLength() < 0 && + (!entity.isChunked() || ver.lessEquals(HttpVersion.HTTP_1_0))) { + response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); + return; + } + } + // Drop connection if requested by the client or request was <= 1.0 + final HttpRequest request = corecontext.getRequest(); + if (request != null) { + final Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE); + if (header != null) { + response.setHeader(HTTP.CONN_DIRECTIVE, header.getValue()); + } else if (request.getProtocolVersion().lessEquals(HttpVersion.HTTP_1_0)) { + response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); + } + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseContent.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseContent.java new file mode 100644 index 000000000..e2dcf2eef --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseContent.java @@ -0,0 +1,133 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.HttpResponseInterceptor; +import ch.boye.httpclientandroidlib.HttpStatus; +import ch.boye.httpclientandroidlib.HttpVersion; +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.ProtocolVersion; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * ResponseContent is the most important interceptor for outgoing responses. + * It is responsible for delimiting content length by adding + * <code>Content-Length</code> or <code>Transfer-Content</code> headers based + * on the properties of the enclosed entity and the protocol version. + * This interceptor is required for correct functioning of server side protocol + * processors. + * + * @since 4.0 + */ +@Immutable +public class ResponseContent implements HttpResponseInterceptor { + + private final boolean overwrite; + + /** + * Default constructor. The <code>Content-Length</code> or <code>Transfer-Encoding</code> + * will cause the interceptor to throw {@link ProtocolException} if already present in the + * response message. + */ + public ResponseContent() { + this(false); + } + + /** + * Constructor that can be used to fine-tune behavior of this interceptor. + * + * @param overwrite If set to <code>true</code> the <code>Content-Length</code> and + * <code>Transfer-Encoding</code> headers will be created or updated if already present. + * If set to <code>false</code> the <code>Content-Length</code> and + * <code>Transfer-Encoding</code> headers will cause the interceptor to throw + * {@link ProtocolException} if already present in the response message. + * + * @since 4.2 + */ + public ResponseContent(final boolean overwrite) { + super(); + this.overwrite = overwrite; + } + + /** + * Processes the response (possibly updating or inserting) Content-Length and Transfer-Encoding headers. + * @param response The HttpResponse to modify. + * @param context Unused. + * @throws ProtocolException If either the Content-Length or Transfer-Encoding headers are found. + * @throws IllegalArgumentException If the response is null. + */ + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + Args.notNull(response, "HTTP response"); + if (this.overwrite) { + response.removeHeaders(HTTP.TRANSFER_ENCODING); + response.removeHeaders(HTTP.CONTENT_LEN); + } else { + if (response.containsHeader(HTTP.TRANSFER_ENCODING)) { + throw new ProtocolException("Transfer-encoding header already present"); + } + if (response.containsHeader(HTTP.CONTENT_LEN)) { + throw new ProtocolException("Content-Length header already present"); + } + } + final ProtocolVersion ver = response.getStatusLine().getProtocolVersion(); + final HttpEntity entity = response.getEntity(); + if (entity != null) { + final long len = entity.getContentLength(); + if (entity.isChunked() && !ver.lessEquals(HttpVersion.HTTP_1_0)) { + response.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING); + } else if (len >= 0) { + response.addHeader(HTTP.CONTENT_LEN, Long.toString(entity.getContentLength())); + } + // Specify a content type if known + if (entity.getContentType() != null && !response.containsHeader( + HTTP.CONTENT_TYPE )) { + response.addHeader(entity.getContentType()); + } + // Specify a content encoding if known + if (entity.getContentEncoding() != null && !response.containsHeader( + HTTP.CONTENT_ENCODING)) { + response.addHeader(entity.getContentEncoding()); + } + } else { + final int status = response.getStatusLine().getStatusCode(); + if (status != HttpStatus.SC_NO_CONTENT + && status != HttpStatus.SC_NOT_MODIFIED + && status != HttpStatus.SC_RESET_CONTENT) { + response.addHeader(HTTP.CONTENT_LEN, "0"); + } + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseDate.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseDate.java new file mode 100644 index 000000000..300ff761e --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseDate.java @@ -0,0 +1,66 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.HttpResponseInterceptor; +import ch.boye.httpclientandroidlib.HttpStatus; +import ch.boye.httpclientandroidlib.annotation.ThreadSafe; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * ResponseDate is responsible for adding <code>Date<c/ode> header to the + * outgoing responses. This interceptor is recommended for server side protocol + * processors. + * + * @since 4.0 + */ +@ThreadSafe +public class ResponseDate implements HttpResponseInterceptor { + + private static final HttpDateGenerator DATE_GENERATOR = new HttpDateGenerator(); + + public ResponseDate() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + Args.notNull(response, "HTTP response"); + final int status = response.getStatusLine().getStatusCode(); + if ((status >= HttpStatus.SC_OK) && + !response.containsHeader(HTTP.DATE_HEADER)) { + final String httpdate = DATE_GENERATOR.getCurrentDate(); + response.setHeader(HTTP.DATE_HEADER, httpdate); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseServer.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseServer.java new file mode 100644 index 000000000..f0672a006 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/ResponseServer.java @@ -0,0 +1,71 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.HttpResponseInterceptor; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * ResponseServer is responsible for adding <code>Server</code> header. This + * interceptor is recommended for server side protocol processors. + * + * @since 4.0 + */ +@Immutable +public class ResponseServer implements HttpResponseInterceptor { + + private final String originServer; + + /** + * @since 4.3 + */ + public ResponseServer(final String originServer) { + super(); + this.originServer = originServer; + } + + public ResponseServer() { + this(null); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + Args.notNull(response, "HTTP response"); + if (!response.containsHeader(HTTP.SERVER_HEADER)) { + if (this.originServer != null) { + response.addHeader(HTTP.SERVER_HEADER, this.originServer); + } + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/SyncBasicHttpContext.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/SyncBasicHttpContext.java new file mode 100644 index 000000000..60138764b --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/SyncBasicHttpContext.java @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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.protocol; + +/** + * Thread-safe extension of the {@link BasicHttpContext}. + * + * @since 4.0 + * + * @deprecated (4.2) HttpContext instances may not be shared by multiple threads + */ +@Deprecated +public class SyncBasicHttpContext extends BasicHttpContext { + + public SyncBasicHttpContext(final HttpContext parentContext) { + super(parentContext); + } + + /** + * @since 4.2 + */ + public SyncBasicHttpContext() { + super(); + } + + @Override + public synchronized Object getAttribute(final String id) { + return super.getAttribute(id); + } + + @Override + public synchronized void setAttribute(final String id, final Object obj) { + super.setAttribute(id, obj); + } + + @Override + public synchronized Object removeAttribute(final String id) { + return super.removeAttribute(id); + } + + /** + * @since 4.2 + */ + @Override + public synchronized void clear() { + super.clear(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/UriHttpRequestHandlerMapper.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/UriHttpRequestHandlerMapper.java new file mode 100644 index 000000000..f09dea611 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/UriHttpRequestHandlerMapper.java @@ -0,0 +1,115 @@ +/* + * ==================================================================== + * 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.protocol; + +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.annotation.ThreadSafe; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Maintains a map of HTTP request handlers keyed by a request URI pattern. + * <br> + * Patterns may have three formats: + * <ul> + * <li><code>*</code></li> + * <li><code>*<uri></code></li> + * <li><code><uri>*</code></li> + * </ul> + * <br> + * This class can be used to map an instance of + * {@link HttpRequestHandler} matching a particular request URI. Usually the + * mapped request handler will be used to process the request with the + * specified request URI. + * + * @since 4.3 + */ +@ThreadSafe // provided injected dependencies are thread-safe +public class UriHttpRequestHandlerMapper implements HttpRequestHandlerMapper { + + private final UriPatternMatcher<HttpRequestHandler> matcher; + + protected UriHttpRequestHandlerMapper(final UriPatternMatcher<HttpRequestHandler> matcher) { + super(); + this.matcher = Args.notNull(matcher, "Pattern matcher"); + } + + public UriHttpRequestHandlerMapper() { + this(new UriPatternMatcher<HttpRequestHandler>()); + } + + /** + * Registers the given {@link HttpRequestHandler} as a handler for URIs + * matching the given pattern. + * + * @param pattern the pattern to register the handler for. + * @param handler the handler. + */ + public void register(final String pattern, final HttpRequestHandler handler) { + Args.notNull(pattern, "Pattern"); + Args.notNull(handler, "Handler"); + matcher.register(pattern, handler); + } + + /** + * Removes registered handler, if exists, for the given pattern. + * + * @param pattern the pattern to unregister the handler for. + */ + public void unregister(final String pattern) { + matcher.unregister(pattern); + } + + /** + * Extracts request path from the given {@link HttpRequest} + */ + protected String getRequestPath(final HttpRequest request) { + String uriPath = request.getRequestLine().getUri(); + int index = uriPath.indexOf("?"); + if (index != -1) { + uriPath = uriPath.substring(0, index); + } else { + index = uriPath.indexOf("#"); + if (index != -1) { + uriPath = uriPath.substring(0, index); + } + } + return uriPath; + } + + /** + * Looks up a handler matching the given request URI. + * + * @param request the request + * @return handler or <code>null</code> if no match is found. + */ + public HttpRequestHandler lookup(final HttpRequest request) { + Args.notNull(request, "HTTP request"); + return matcher.lookup(getRequestPath(request)); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/UriPatternMatcher.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/UriPatternMatcher.java new file mode 100644 index 000000000..77c46a70c --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/UriPatternMatcher.java @@ -0,0 +1,165 @@ +/* + * ==================================================================== + * 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.protocol; + +import java.util.HashMap; +import java.util.Map; + +import ch.boye.httpclientandroidlib.annotation.GuardedBy; +import ch.boye.httpclientandroidlib.annotation.ThreadSafe; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Maintains a map of objects keyed by a request URI pattern. + * <br> + * Patterns may have three formats: + * <ul> + * <li><code>*</code></li> + * <li><code>*<uri></code></li> + * <li><code><uri>*</code></li> + * </ul> + * <br> + * This class can be used to resolve an object matching a particular request + * URI. + * + * @since 4.0 + */ +@ThreadSafe +public class UriPatternMatcher<T> { + + @GuardedBy("this") + private final Map<String, T> map; + + public UriPatternMatcher() { + super(); + this.map = new HashMap<String, T>(); + } + + /** + * Registers the given object for URIs matching the given pattern. + * + * @param pattern the pattern to register the handler for. + * @param obj the object. + */ + public synchronized void register(final String pattern, final T obj) { + Args.notNull(pattern, "URI request pattern"); + this.map.put(pattern, obj); + } + + /** + * Removes registered object, if exists, for the given pattern. + * + * @param pattern the pattern to unregister. + */ + public synchronized void unregister(final String pattern) { + if (pattern == null) { + return; + } + this.map.remove(pattern); + } + + /** + * @deprecated (4.1) do not use + */ + @Deprecated + public synchronized void setHandlers(final Map<String, T> map) { + Args.notNull(map, "Map of handlers"); + this.map.clear(); + this.map.putAll(map); + } + + /** + * @deprecated (4.1) do not use + */ + @Deprecated + public synchronized void setObjects(final Map<String, T> map) { + Args.notNull(map, "Map of handlers"); + this.map.clear(); + this.map.putAll(map); + } + + /** + * @deprecated (4.1) do not use + */ + @Deprecated + public synchronized Map<String, T> getObjects() { + return this.map; + } + + /** + * Looks up an object matching the given request path. + * + * @param path the request path + * @return object or <code>null</code> if no match is found. + */ + public synchronized T lookup(final String path) { + Args.notNull(path, "Request path"); + // direct match? + T obj = this.map.get(path); + if (obj == null) { + // pattern match? + String bestMatch = null; + for (final String pattern : this.map.keySet()) { + if (matchUriRequestPattern(pattern, path)) { + // we have a match. is it any better? + if (bestMatch == null + || (bestMatch.length() < pattern.length()) + || (bestMatch.length() == pattern.length() && pattern.endsWith("*"))) { + obj = this.map.get(pattern); + bestMatch = pattern; + } + } + } + } + return obj; + } + + /** + * Tests if the given request path matches the given pattern. + * + * @param pattern the pattern + * @param path the request path + * @return <code>true</code> if the request URI matches the pattern, + * <code>false</code> otherwise. + */ + protected boolean matchUriRequestPattern(final String pattern, final String path) { + if (pattern.equals("*")) { + return true; + } else { + return + (pattern.endsWith("*") && path.startsWith(pattern.substring(0, pattern.length() - 1))) || + (pattern.startsWith("*") && path.endsWith(pattern.substring(1, pattern.length()))); + } + } + + @Override + public String toString() { + return this.map.toString(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/package-info.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/package-info.java new file mode 100644 index 000000000..97fcbfdc1 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/protocol/package-info.java @@ -0,0 +1,32 @@ +/* + * ==================================================================== + * 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/>. + * + */ + +/** + * Core HTTP protocol execution framework and HTTP protocol handlers + * for synchronous, blocking communication. + */ +package ch.boye.httpclientandroidlib.protocol; |