diff options
Diffstat (limited to 'mobile/android/thirdparty/ch/boye/httpclientandroidlib/client')
102 files changed, 11304 insertions, 0 deletions
diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/AuthCache.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/AuthCache.java new file mode 100644 index 000000000..3fd0a473d --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/AuthCache.java @@ -0,0 +1,49 @@ +/* + * ==================================================================== + * 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.client; + +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.auth.AuthScheme; + +/** + * Abstract {@link AuthScheme} cache. Initialized {@link AuthScheme} objects + * from this cache can be used to preemptively authenticate against known + * hosts. + * + * @since 4.1 + */ +public interface AuthCache { + + void put(HttpHost host, AuthScheme authScheme); + + AuthScheme get(HttpHost host); + + void remove(HttpHost host); + + void clear(); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/AuthenticationHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/AuthenticationHandler.java new file mode 100644 index 000000000..24b30b54f --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/AuthenticationHandler.java @@ -0,0 +1,101 @@ +/* + * ==================================================================== + * 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.client; + +import java.util.Map; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.auth.AuthScheme; +import ch.boye.httpclientandroidlib.auth.AuthenticationException; +import ch.boye.httpclientandroidlib.auth.MalformedChallengeException; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** +/** + * A handler for determining if an HTTP response represents an authentication + * challenge that was sent back to the client as a result of authentication + * failure. + * <p> + * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link AuthenticationStrategy} + */ +@Deprecated +public interface AuthenticationHandler { + + /** + * Determines if the given HTTP response response represents + * an authentication challenge that was sent back as a result + * of authentication failure + * @param response HTTP response. + * @param context HTTP context. + * @return <code>true</code> if user authentication is required, + * <code>false</code> otherwise. + */ + boolean isAuthenticationRequested( + HttpResponse response, + HttpContext context); + + /** + * Extracts from the given HTTP response a collection of authentication + * challenges, each of which represents an authentication scheme supported + * by the authentication host. + * + * @param response HTTP response. + * @param context HTTP context. + * @return a collection of challenges keyed by names of corresponding + * authentication schemes. + * @throws MalformedChallengeException if one of the authentication + * challenges is not valid or malformed. + */ + Map<String, Header> getChallenges( + HttpResponse response, + HttpContext context) throws MalformedChallengeException; + + /** + * Selects one authentication challenge out of all available and + * creates and generates {@link AuthScheme} instance capable of + * processing that challenge. + * @param challenges collection of challenges. + * @param response HTTP response. + * @param context HTTP context. + * @return authentication scheme to use for authentication. + * @throws AuthenticationException if an authentication scheme + * could not be selected. + */ + AuthScheme selectScheme( + Map<String, Header> challenges, + HttpResponse response, + HttpContext context) throws AuthenticationException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/AuthenticationStrategy.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/AuthenticationStrategy.java new file mode 100644 index 000000000..2aa1fb536 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/AuthenticationStrategy.java @@ -0,0 +1,130 @@ +/* + * ==================================================================== + * 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.client; + +import java.util.Map; +import java.util.Queue; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.auth.AuthOption; +import ch.boye.httpclientandroidlib.auth.AuthScheme; +import ch.boye.httpclientandroidlib.auth.MalformedChallengeException; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** +/** + * A handler for determining if an HTTP response represents an authentication challenge that was + * sent back to the client as a result of authentication failure. + * <p> + * Implementations of this interface must be thread-safe. Access to shared data must be + * synchronized as methods of this interface may be executed from multiple threads. + * + * @since 4.2 + */ +public interface AuthenticationStrategy { + + /** + * Determines if the given HTTP response response represents + * an authentication challenge that was sent back as a result + * of authentication failure. + * + * @param authhost authentication host. + * @param response HTTP response. + * @param context HTTP context. + * @return <code>true</code> if user authentication is required, + * <code>false</code> otherwise. + */ + boolean isAuthenticationRequested( + HttpHost authhost, + HttpResponse response, + HttpContext context); + + /** + * Extracts from the given HTTP response a collection of authentication + * challenges, each of which represents an authentication scheme supported + * by the authentication host. + * + * @param authhost authentication host. + * @param response HTTP response. + * @param context HTTP context. + * @return a collection of challenges keyed by names of corresponding + * authentication schemes. + * @throws MalformedChallengeException if one of the authentication + * challenges is not valid or malformed. + */ + Map<String, Header> getChallenges( + HttpHost authhost, + HttpResponse response, + HttpContext context) throws MalformedChallengeException; + + /** + * Selects one authentication challenge out of all available and + * creates and generates {@link AuthOption} instance capable of + * processing that challenge. + * + * @param challenges collection of challenges. + * @param authhost authentication host. + * @param response HTTP response. + * @param context HTTP context. + * @return authentication auth schemes that can be used for authentication. Can be empty. + * @throws MalformedChallengeException if one of the authentication + * challenges is not valid or malformed. + */ + Queue<AuthOption> select( + Map<String, Header> challenges, + HttpHost authhost, + HttpResponse response, + HttpContext context) throws MalformedChallengeException; + + /** + * Callback invoked in case of successful authentication. + * + * @param authhost authentication host. + * @param authScheme authentication scheme used. + * @param context HTTP context. + */ + void authSucceeded( + HttpHost authhost, + AuthScheme authScheme, + HttpContext context); + + /** + * Callback invoked in case of unsuccessful authentication. + * + * @param authhost authentication host. + * @param authScheme authentication scheme used. + * @param context HTTP context. + */ + void authFailed( + HttpHost authhost, + AuthScheme authScheme, + HttpContext context); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/BackoffManager.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/BackoffManager.java new file mode 100644 index 000000000..afce4f277 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/BackoffManager.java @@ -0,0 +1,54 @@ +/* + * ==================================================================== + * 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.client; + +import ch.boye.httpclientandroidlib.conn.routing.HttpRoute; + +/** + * Represents a controller that dynamically adjusts the size + * of an available connection pool based on feedback from + * using the connections. + * + * @since 4.2 + * + */ +public interface BackoffManager { + + /** + * Called when we have decided that the result of + * using a connection should be interpreted as a + * backoff signal. + */ + public void backOff(HttpRoute route); + + /** + * Called when we have determined that the result of + * using a connection has succeeded and that we may + * probe for more connections. + */ + public void probe(HttpRoute route); +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/CircularRedirectException.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/CircularRedirectException.java new file mode 100644 index 000000000..22d301885 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/CircularRedirectException.java @@ -0,0 +1,68 @@ +/* + * ==================================================================== + * 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.client; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Signals a circular redirect + * + * + * @since 4.0 + */ +@Immutable +public class CircularRedirectException extends RedirectException { + + private static final long serialVersionUID = 6830063487001091803L; + + /** + * Creates a new CircularRedirectException with a <tt>null</tt> detail message. + */ + public CircularRedirectException() { + super(); + } + + /** + * Creates a new CircularRedirectException with the specified detail message. + * + * @param message The exception detail message + */ + public CircularRedirectException(final String message) { + super(message); + } + + /** + * Creates a new CircularRedirectException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the <tt>Throwable</tt> that caused this exception, or <tt>null</tt> + * if the cause is unavailable, unknown, or not a <tt>Throwable</tt> + */ + public CircularRedirectException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ClientProtocolException.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ClientProtocolException.java new file mode 100644 index 000000000..3b807ae71 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ClientProtocolException.java @@ -0,0 +1,61 @@ +/* + * ==================================================================== + * 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.client; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Signals an error in the HTTP protocol. + * + * @since 4.0 + */ +@Immutable +public class ClientProtocolException extends IOException { + + private static final long serialVersionUID = -5596590843227115865L; + + public ClientProtocolException() { + super(); + } + + public ClientProtocolException(final String s) { + super(s); + } + + public ClientProtocolException(final Throwable cause) { + initCause(cause); + } + + public ClientProtocolException(final String message, final Throwable cause) { + super(message); + initCause(cause); + } + + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ConnectionBackoffStrategy.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ConnectionBackoffStrategy.java new file mode 100644 index 000000000..1f30329cf --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ConnectionBackoffStrategy.java @@ -0,0 +1,64 @@ +/* + * ==================================================================== + * 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.client; + +import ch.boye.httpclientandroidlib.HttpResponse; + +/** + * When managing a dynamic number of connections for a given route, this + * strategy assesses whether a given request execution outcome should + * result in a backoff signal or not, based on either examining the + * <code>Throwable</code> that resulted or by examining the resulting + * response (e.g. for its status code). + * + * @since 4.2 + * + */ +public interface ConnectionBackoffStrategy { + + /** + * Determines whether seeing the given <code>Throwable</code> as + * a result of request execution should result in a backoff + * signal. + * @param t the <code>Throwable</code> that happened + * @return <code>true</code> if a backoff signal should be + * given + */ + boolean shouldBackoff(Throwable t); + + /** + * Determines whether receiving the given {@link HttpResponse} as + * a result of request execution should result in a backoff + * signal. Implementations MUST restrict themselves to examining + * the response header and MUST NOT consume any of the response + * body, if any. + * @param resp the <code>HttpResponse</code> that was received + * @return <code>true</code> if a backoff signal should be + * given + */ + boolean shouldBackoff(HttpResponse resp); +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/CookieStore.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/CookieStore.java new file mode 100644 index 000000000..683109ac4 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/CookieStore.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.client; + +import java.util.Date; +import java.util.List; + +import ch.boye.httpclientandroidlib.cookie.Cookie; + +/** + * This interface represents an abstract store for {@link Cookie} + * objects. + * + * @since 4.0 + */ +public interface CookieStore { + + /** + * Adds an {@link Cookie}, replacing any existing equivalent cookies. + * If the given cookie has already expired it will not be added, but existing + * values will still be removed. + * + * @param cookie the {@link Cookie cookie} to be added + */ + void addCookie(Cookie cookie); + + /** + * Returns all cookies contained in this store. + * + * @return all cookies + */ + List<Cookie> getCookies(); + + /** + * Removes all of {@link Cookie}s in this store that have expired by + * the specified {@link java.util.Date}. + * + * @return true if any cookies were purged. + */ + boolean clearExpired(Date date); + + /** + * Clears all cookies. + */ + void clear(); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/CredentialsProvider.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/CredentialsProvider.java new file mode 100644 index 000000000..dc790399c --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/CredentialsProvider.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.client; + +import ch.boye.httpclientandroidlib.auth.AuthScope; +import ch.boye.httpclientandroidlib.auth.Credentials; + +/** + * Abstract credentials provider that maintains a collection of user + * credentials. + * <p> + * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + */ +public interface CredentialsProvider { + + /** + * Sets the {@link Credentials credentials} for the given authentication + * scope. Any previous credentials for the given scope will be overwritten. + * + * @param authscope the {@link AuthScope authentication scope} + * @param credentials the authentication {@link Credentials credentials} + * for the given scope. + * + * @see #getCredentials(AuthScope) + */ + void setCredentials(AuthScope authscope, Credentials credentials); + + /** + * Get the {@link Credentials credentials} for the given authentication scope. + * + * @param authscope the {@link AuthScope authentication scope} + * @return the credentials + * + * @see #setCredentials(AuthScope, Credentials) + */ + Credentials getCredentials(AuthScope authscope); + + /** + * Clears all credentials. + */ + void clear(); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/HttpClient.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/HttpClient.java new file mode 100644 index 000000000..4cc87fcfe --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/HttpClient.java @@ -0,0 +1,258 @@ +/* + * ==================================================================== + * 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.client; + +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.client.methods.HttpUriRequest; +import ch.boye.httpclientandroidlib.conn.ClientConnectionManager; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +import java.io.IOException; + +/** + * This interface represents only the most basic contract for HTTP request + * execution. It imposes no restrictions or particular details on the request + * execution process and leaves the specifics of state management, + * authentication and redirect handling up to individual implementations. + * + * @since 4.0 + */ +@SuppressWarnings("deprecation") +public interface HttpClient { + + + /** + * Obtains the parameters for this client. + * These parameters will become defaults for all requests being + * executed with this client, and for the parameters of + * dependent objects in this client. + * + * @return the default parameters + * + * @deprecated (4.3) use + * {@link ch.boye.httpclientandroidlib.client.config.RequestConfig}. + */ + @Deprecated + HttpParams getParams(); + + /** + * Obtains the connection manager used by this client. + * + * @return the connection manager + * + * @deprecated (4.3) use + * {@link ch.boye.httpclientandroidlib.impl.client.HttpClientBuilder}. + */ + @Deprecated + ClientConnectionManager getConnectionManager(); + + /** + * Executes HTTP request using the default context. + * + * @param request the request to execute + * + * @return the response to the request. This is always a final response, + * never an intermediate response with an 1xx status code. + * Whether redirects or authentication challenges will be returned + * or handled automatically depends on the implementation and + * configuration of this client. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + HttpResponse execute(HttpUriRequest request) + throws IOException, ClientProtocolException; + + /** + * Executes HTTP request using the given context. + * + * @param request the request to execute + * @param context the context to use for the execution, or + * <code>null</code> to use the default context + * + * @return the response to the request. This is always a final response, + * never an intermediate response with an 1xx status code. + * Whether redirects or authentication challenges will be returned + * or handled automatically depends on the implementation and + * configuration of this client. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + HttpResponse execute(HttpUriRequest request, HttpContext context) + throws IOException, ClientProtocolException; + + /** + * Executes HTTP request using the default context. + * + * @param target the target host for the request. + * Implementations may accept <code>null</code> + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * + * @return the response to the request. This is always a final response, + * never an intermediate response with an 1xx status code. + * Whether redirects or authentication challenges will be returned + * or handled automatically depends on the implementation and + * configuration of this client. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + HttpResponse execute(HttpHost target, HttpRequest request) + throws IOException, ClientProtocolException; + + /** + * Executes HTTP request using the given context. + * + * @param target the target host for the request. + * Implementations may accept <code>null</code> + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * @param context the context to use for the execution, or + * <code>null</code> to use the default context + * + * @return the response to the request. This is always a final response, + * never an intermediate response with an 1xx status code. + * Whether redirects or authentication challenges will be returned + * or handled automatically depends on the implementation and + * configuration of this client. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + HttpResponse execute(HttpHost target, HttpRequest request, + HttpContext context) + throws IOException, ClientProtocolException; + + /** + * Executes HTTP request using the default context and processes the + * response using the given response handler. + * <p/> + * Implementing classes are required to ensure that the content entity + * associated with the response is fully consumed and the underlying + * connection is released back to the connection manager automatically + * in all cases relieving individual {@link ResponseHandler}s from + * having to manage resource deallocation internally. + * + * @param request the request to execute + * @param responseHandler the response handler + * + * @return the response object as generated by the response handler. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + <T> T execute( + HttpUriRequest request, + ResponseHandler<? extends T> responseHandler) + throws IOException, ClientProtocolException; + + /** + * Executes HTTP request using the given context and processes the + * response using the given response handler. + * <p/> + * Implementing classes are required to ensure that the content entity + * associated with the response is fully consumed and the underlying + * connection is released back to the connection manager automatically + * in all cases relieving individual {@link ResponseHandler}s from + * having to manage resource deallocation internally. + * + * @param request the request to execute + * @param responseHandler the response handler + * @param context the context to use for the execution, or + * <code>null</code> to use the default context + * + * @return the response object as generated by the response handler. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + <T> T execute( + HttpUriRequest request, + ResponseHandler<? extends T> responseHandler, + HttpContext context) + throws IOException, ClientProtocolException; + + /** + * Executes HTTP request to the target using the default context and + * processes the response using the given response handler. + * <p/> + * Implementing classes are required to ensure that the content entity + * associated with the response is fully consumed and the underlying + * connection is released back to the connection manager automatically + * in all cases relieving individual {@link ResponseHandler}s from + * having to manage resource deallocation internally. + * + * @param target the target host for the request. + * Implementations may accept <code>null</code> + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * @param responseHandler the response handler + * + * @return the response object as generated by the response handler. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + <T> T execute( + HttpHost target, + HttpRequest request, + ResponseHandler<? extends T> responseHandler) + throws IOException, ClientProtocolException; + + /** + * Executes HTTP request to the target using the given context and + * processes the response using the given response handler. + * <p/> + * Implementing classes are required to ensure that the content entity + * associated with the response is fully consumed and the underlying + * connection is released back to the connection manager automatically + * in all cases relieving individual {@link ResponseHandler}s from + * having to manage resource deallocation internally. + * + * @param target the target host for the request. + * Implementations may accept <code>null</code> + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * @param responseHandler the response handler + * @param context the context to use for the execution, or + * <code>null</code> to use the default context + * + * @return the response object as generated by the response handler. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + <T> T execute( + HttpHost target, + HttpRequest request, + ResponseHandler<? extends T> responseHandler, + HttpContext context) + throws IOException, ClientProtocolException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/HttpRequestRetryHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/HttpRequestRetryHandler.java new file mode 100644 index 000000000..8bbb11c49 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/HttpRequestRetryHandler.java @@ -0,0 +1,60 @@ +/* + * ==================================================================== + * 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.client; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * A handler for determining if an HttpRequest should be retried after a + * recoverable exception during execution. + * <p> + * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + */ +public interface HttpRequestRetryHandler { + + /** + * Determines if a method should be retried after an IOException + * occurs during execution. + * + * @param exception the exception that occurred + * @param executionCount the number of times this method has been + * unsuccessfully executed + * @param context the context for the request execution + * + * @return <code>true</code> if the method should be retried, <code>false</code> + * otherwise + */ + boolean retryRequest(IOException exception, int executionCount, HttpContext context); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/HttpResponseException.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/HttpResponseException.java new file mode 100644 index 000000000..68500c6ac --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/HttpResponseException.java @@ -0,0 +1,52 @@ +/* + * ==================================================================== + * 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.client; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Signals a non 2xx HTTP response. + * + * @since 4.0 + */ +@Immutable +public class HttpResponseException extends ClientProtocolException { + + private static final long serialVersionUID = -7186627969477257933L; + + private final int statusCode; + + public HttpResponseException(final int statusCode, final String s) { + super(s); + this.statusCode = statusCode; + } + + public int getStatusCode() { + return this.statusCode; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/NonRepeatableRequestException.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/NonRepeatableRequestException.java new file mode 100644 index 000000000..6d9dce208 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/NonRepeatableRequestException.java @@ -0,0 +1,72 @@ +/* + * ==================================================================== + * 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.client; + +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Signals failure to retry the request due to non-repeatable request + * entity. + * + * + * @since 4.0 + */ +@Immutable +public class NonRepeatableRequestException extends ProtocolException { + + private static final long serialVersionUID = 82685265288806048L; + + /** + * Creates a new NonRepeatableEntityException with a <tt>null</tt> detail message. + */ + public NonRepeatableRequestException() { + super(); + } + + /** + * Creates a new NonRepeatableEntityException with the specified detail message. + * + * @param message The exception detail message + */ + public NonRepeatableRequestException(final String message) { + super(message); + } + + /** + * Creates a new NonRepeatableEntityException with the specified detail message. + * + * @param message The exception detail message + * @param cause the cause + */ + public NonRepeatableRequestException(final String message, final Throwable cause) { + super(message, cause); + } + + + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RedirectException.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RedirectException.java new file mode 100644 index 000000000..e187db789 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RedirectException.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.client; + +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Signals violation of HTTP specification caused by an invalid redirect + * + * + * @since 4.0 + */ +@Immutable +public class RedirectException extends ProtocolException { + + private static final long serialVersionUID = 4418824536372559326L; + + /** + * Creates a new RedirectException with a <tt>null</tt> detail message. + */ + public RedirectException() { + super(); + } + + /** + * Creates a new RedirectException with the specified detail message. + * + * @param message The exception detail message + */ + public RedirectException(final String message) { + super(message); + } + + /** + * Creates a new RedirectException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the <tt>Throwable</tt> that caused this exception, or <tt>null</tt> + * if the cause is unavailable, unknown, or not a <tt>Throwable</tt> + */ + public RedirectException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RedirectHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RedirectHandler.java new file mode 100644 index 000000000..f2dcd842b --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RedirectHandler.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.client; + +import java.net.URI; + +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * A handler for determining if an HTTP request should be redirected to + * a new location in response to an HTTP response received from the target + * server. + * <p> + * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + * + * @deprecated (4.1) use {@link RedirectStrategy} + */ +@Deprecated +public interface RedirectHandler { + + /** + * Determines if a request should be redirected to a new location + * given the response from the target server. + * + * @param response the response received from the target server + * @param context the context for the request execution + * + * @return <code>true</code> if the request should be redirected, <code>false</code> + * otherwise + */ + boolean isRedirectRequested(HttpResponse response, HttpContext context); + + /** + * Determines the location request is expected to be redirected to + * given the response from the target server and the current request + * execution context. + * + * @param response the response received from the target server + * @param context the context for the request execution + * + * @return redirect URI + */ + URI getLocationURI(HttpResponse response, HttpContext context) + throws ProtocolException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RedirectStrategy.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RedirectStrategy.java new file mode 100644 index 000000000..ad2499c37 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RedirectStrategy.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.client; + +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.ProtocolException; +import ch.boye.httpclientandroidlib.client.methods.HttpUriRequest; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * A strategy for determining if an HTTP request should be redirected to + * a new location in response to an HTTP response received from the target + * server. + * <p> + * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.1 + */ +public interface RedirectStrategy { + + /** + * Determines if a request should be redirected to a new location + * given the response from the target server. + * + * @param request the executed request + * @param response the response received from the target server + * @param context the context for the request execution + * + * @return <code>true</code> if the request should be redirected, <code>false</code> + * otherwise + */ + boolean isRedirected( + HttpRequest request, + HttpResponse response, + HttpContext context) throws ProtocolException; + + /** + * Determines the redirect location given the response from the target + * server and the current request execution context and generates a new + * request to be sent to the location. + * + * @param request the executed request + * @param response the response received from the target server + * @param context the context for the request execution + * + * @return redirected request + */ + HttpUriRequest getRedirect( + HttpRequest request, + HttpResponse response, + HttpContext context) throws ProtocolException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RequestDirector.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RequestDirector.java new file mode 100644 index 000000000..ebaeb74a0 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/RequestDirector.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.client; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * A client-side request director. + * The director decides which steps are necessary to execute a request. + * It establishes connections and optionally processes redirects and + * authentication challenges. The director may therefore generate and + * send a sequence of requests in order to execute one initial request. + * + * @since 4.0 + * + * @deprecated (4.3) No longer used + */ +@Deprecated +public interface RequestDirector { + + + /** + * Executes a request. + * <br/><b>Note:</b> + * For the time being, a new director is instantiated for each request. + * This is the same behavior as for <code>HttpMethodDirector</code> + * in HttpClient 3. + * + * @param target the target host for the request. + * Implementations may accept <code>null</code> + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * @param context the context for executing the request + * + * @return the final response to the request. + * This is never an intermediate response with status code 1xx. + * + * @throws HttpException in case of a problem + * @throws IOException in case of an IO problem + * or if the connection was aborted + */ + HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) + throws HttpException, IOException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ResponseHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ResponseHandler.java new file mode 100644 index 000000000..6fa02b650 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ResponseHandler.java @@ -0,0 +1,54 @@ +/* + * ==================================================================== + * 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.client; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpResponse; + +/** + * Handler that encapsulates the process of generating a response object + * from a {@link HttpResponse}. + * + * + * @since 4.0 + */ +public interface ResponseHandler<T> { + + /** + * Processes an {@link HttpResponse} and returns some value + * corresponding to that response. + * + * @param response The response to process + * @return A value determined by the response + * + * @throws ClientProtocolException in case of an http protocol error + * @throws IOException in case of a problem or the connection was aborted + */ + T handleResponse(HttpResponse response) throws ClientProtocolException, IOException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ServiceUnavailableRetryStrategy.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ServiceUnavailableRetryStrategy.java new file mode 100644 index 000000000..7a08dab65 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/ServiceUnavailableRetryStrategy.java @@ -0,0 +1,60 @@ +/* + * ==================================================================== + * 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.client; + +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * Strategy interface that allows API users to plug in their own logic to + * control whether or not a retry should automatically be done, how many times + * it should be retried and so on. + * + * @since 4.2 + */ +public interface ServiceUnavailableRetryStrategy { + + /** + * Determines if a method should be retried given the response from the target server. + * + * @param response the response from the target server + * @param executionCount the number of times this method has been + * unsuccessfully executed + * @param context the context for the request execution + + * @return <code>true</code> if the method should be retried, <code>false</code> + * otherwise + */ + boolean retryRequest(HttpResponse response, int executionCount, HttpContext context); + + /** + * @return The interval between the subsequent auto-retries. + */ + long getRetryInterval(); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/UserTokenHandler.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/UserTokenHandler.java new file mode 100644 index 000000000..1e15ef7c6 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/UserTokenHandler.java @@ -0,0 +1,58 @@ +/* + * ==================================================================== + * 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.client; + +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * A handler for determining if the given execution context is user specific + * or not. The token object returned by this handler is expected to uniquely + * identify the current user if the context is user specific or to be + * <code>null</code> if the context does not contain any resources or details + * specific to the current user. + * <p/> + * The user token will be used to ensure that user specific resources will not + * be shared with or reused by other users. + * + * @since 4.0 + */ +public interface UserTokenHandler { + + /** + * The token object returned by this method is expected to uniquely + * identify the current user if the context is user specific or to be + * <code>null</code> if it is not. + * + * @param context the execution context + * + * @return user token that uniquely identifies the user or + * <code>null</null> if the context is not user specific. + */ + Object getUserToken(HttpContext context); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/CacheResponseStatus.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/CacheResponseStatus.java new file mode 100644 index 000000000..d000839af --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/CacheResponseStatus.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.client.cache; + +/** + * This enumeration represents the various ways a response can be generated + * by the {@link ch.boye.httpclientandroidlib.impl.client.cache.CachingHttpClient}; + * if a request is executed with an {@link ch.boye.httpclientandroidlib.protocol.HttpContext} + * then a parameter with one of these values will be registered in the + * context under the key + * {@link ch.boye.httpclientandroidlib.impl.client.cache.CachingHttpClient#CACHE_RESPONSE_STATUS}. + */ +public enum CacheResponseStatus { + + /** The response was generated directly by the caching module. */ + CACHE_MODULE_RESPONSE, + + /** A response was generated from the cache with no requests sent + * upstream. + */ + CACHE_HIT, + + /** The response came from an upstream server. */ + CACHE_MISS, + + /** The response was generated from the cache after validating the + * entry with the origin server. + */ + VALIDATED; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HeaderConstants.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HeaderConstants.java new file mode 100644 index 000000000..22f34dcff --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HeaderConstants.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.client.cache; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Records static constants for various HTTP header names. + * @since 4.1 + */ +@Immutable +public class HeaderConstants { + + public static final String GET_METHOD = "GET"; + public static final String HEAD_METHOD = "HEAD"; + public static final String OPTIONS_METHOD = "OPTIONS"; + public static final String PUT_METHOD = "PUT"; + public static final String DELETE_METHOD = "DELETE"; + public static final String TRACE_METHOD = "TRACE"; + + public static final String LAST_MODIFIED = "Last-Modified"; + public static final String IF_MATCH = "If-Match"; + public static final String IF_RANGE = "If-Range"; + public static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since"; + public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; + public static final String IF_NONE_MATCH = "If-None-Match"; + + public static final String PRAGMA = "Pragma"; + public static final String MAX_FORWARDS = "Max-Forwards"; + public static final String ETAG = "ETag"; + public static final String EXPIRES = "Expires"; + public static final String AGE = "Age"; + public static final String VARY = "Vary"; + public static final String ALLOW = "Allow"; + public static final String VIA = "Via"; + public static final String PUBLIC = "public"; + public static final String PRIVATE = "private"; + + public static final String CACHE_CONTROL = "Cache-Control"; + public static final String CACHE_CONTROL_NO_STORE = "no-store"; + public static final String CACHE_CONTROL_NO_CACHE = "no-cache"; + public static final String CACHE_CONTROL_MAX_AGE = "max-age"; + public static final String CACHE_CONTROL_MAX_STALE = "max-stale"; + public static final String CACHE_CONTROL_MIN_FRESH = "min-fresh"; + public static final String CACHE_CONTROL_MUST_REVALIDATE = "must-revalidate"; + public static final String CACHE_CONTROL_PROXY_REVALIDATE = "proxy-revalidate"; + public static final String STALE_IF_ERROR = "stale-if-error"; + public static final String STALE_WHILE_REVALIDATE = "stale-while-revalidate"; + + public static final String WARNING = "Warning"; + public static final String RANGE = "Range"; + public static final String CONTENT_RANGE = "Content-Range"; + public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; + public static final String PROXY_AUTHENTICATE = "Proxy-Authenticate"; + public static final String AUTHORIZATION = "Authorization"; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheContext.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheContext.java new file mode 100644 index 000000000..54edfa12a --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheContext.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.client.cache; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.client.protocol.HttpClientContext; +import ch.boye.httpclientandroidlib.protocol.BasicHttpContext; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * @since 4.3 + */ +@NotThreadSafe +public class HttpCacheContext extends HttpClientContext { + + /** + * This is the name under which the {@link CacheResponseStatus} of a request + * (for example, whether it resulted in a cache hit) will be recorded if an + * {@link HttpContext} is provided during execution. + */ + public static final String CACHE_RESPONSE_STATUS = "http.cache.response.status"; + + public static HttpCacheContext adapt(final HttpContext context) { + if (context instanceof HttpCacheContext) { + return (HttpCacheContext) context; + } else { + return new HttpCacheContext(context); + } + } + + public static HttpCacheContext create() { + return new HttpCacheContext(new BasicHttpContext()); + } + + public HttpCacheContext(final HttpContext context) { + super(context); + } + + public HttpCacheContext() { + super(); + } + + public CacheResponseStatus getCacheResponseStatus() { + return getAttribute(CACHE_RESPONSE_STATUS, CacheResponseStatus.class); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheEntry.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheEntry.java new file mode 100644 index 000000000..d03786279 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheEntry.java @@ -0,0 +1,263 @@ +/* + * ==================================================================== + * 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.client.cache; + +import java.io.Serializable; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.ProtocolVersion; +import ch.boye.httpclientandroidlib.StatusLine; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.client.utils.DateUtils; +import ch.boye.httpclientandroidlib.message.HeaderGroup; +import ch.boye.httpclientandroidlib.protocol.HTTP; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Structure used to store an {@link ch.boye.httpclientandroidlib.HttpResponse} in a cache. + * Some entries can optionally depend on system resources that may require + * explicit deallocation. In such a case {@link #getResource()} should return + * a non null instance of {@link Resource} that must be deallocated by calling + * {@link Resource#dispose()} method when no longer used. + * + * @since 4.1 + */ +@Immutable +public class HttpCacheEntry implements Serializable { + + private static final long serialVersionUID = -6300496422359477413L; + + private final Date requestDate; + private final Date responseDate; + private final StatusLine statusLine; + private final HeaderGroup responseHeaders; + private final Resource resource; + private final Map<String,String> variantMap; + private final Date date; + + /** + * Create a new {@link HttpCacheEntry} with variants. + * @param requestDate + * Date/time when the request was made (Used for age + * calculations) + * @param responseDate + * Date/time that the response came back (Used for age + * calculations) + * @param statusLine + * HTTP status line from origin response + * @param responseHeaders + * Header[] from original HTTP Response + * @param resource representing origin response body + * @param variantMap describing cache entries that are variants + * of this parent entry; this maps a "variant key" (derived + * from the varying request headers) to a "cache key" (where + * in the cache storage the particular variant is located) + */ + public HttpCacheEntry( + final Date requestDate, + final Date responseDate, + final StatusLine statusLine, + final Header[] responseHeaders, + final Resource resource, + final Map<String,String> variantMap) { + super(); + Args.notNull(requestDate, "Request date"); + Args.notNull(responseDate, "Response date"); + Args.notNull(statusLine, "Status line"); + Args.notNull(responseHeaders, "Response headers"); + this.requestDate = requestDate; + this.responseDate = responseDate; + this.statusLine = statusLine; + this.responseHeaders = new HeaderGroup(); + this.responseHeaders.setHeaders(responseHeaders); + this.resource = resource; + this.variantMap = variantMap != null + ? new HashMap<String,String>(variantMap) + : null; + this.date = parseDate(); + } + + /** + * Create a new {@link HttpCacheEntry}. + * + * @param requestDate + * Date/time when the request was made (Used for age + * calculations) + * @param responseDate + * Date/time that the response came back (Used for age + * calculations) + * @param statusLine + * HTTP status line from origin response + * @param responseHeaders + * Header[] from original HTTP Response + * @param resource representing origin response body + */ + public HttpCacheEntry(final Date requestDate, final Date responseDate, final StatusLine statusLine, + final Header[] responseHeaders, final Resource resource) { + this(requestDate, responseDate, statusLine, responseHeaders, resource, + new HashMap<String,String>()); + } + + /** + * Find the "Date" response header and parse it into a java.util.Date + * @return the Date value of the header or null if the header is not present + */ + private Date parseDate() { + final Header dateHdr = getFirstHeader(HTTP.DATE_HEADER); + if (dateHdr == null) { + return null; + } + return DateUtils.parseDate(dateHdr.getValue()); + } + + /** + * Returns the {@link StatusLine} from the origin + * {@link ch.boye.httpclientandroidlib.HttpResponse}. + */ + public StatusLine getStatusLine() { + return this.statusLine; + } + + /** + * Returns the {@link ProtocolVersion} from the origin + * {@link ch.boye.httpclientandroidlib.HttpResponse}. + */ + public ProtocolVersion getProtocolVersion() { + return this.statusLine.getProtocolVersion(); + } + + /** + * Gets the reason phrase from the origin + * {@link ch.boye.httpclientandroidlib.HttpResponse}, for example, "Not Modified". + */ + public String getReasonPhrase() { + return this.statusLine.getReasonPhrase(); + } + + /** + * Returns the HTTP response code from the origin + * {@link ch.boye.httpclientandroidlib.HttpResponse}. + */ + public int getStatusCode() { + return this.statusLine.getStatusCode(); + } + + /** + * Returns the time the associated origin request was initiated by the + * caching module. + * @return {@link Date} + */ + public Date getRequestDate() { + return requestDate; + } + + /** + * Returns the time the origin response was received by the caching module. + * @return {@link Date} + */ + public Date getResponseDate() { + return responseDate; + } + + /** + * Returns all the headers that were on the origin response. + */ + public Header[] getAllHeaders() { + return responseHeaders.getAllHeaders(); + } + + /** + * Returns the first header from the origin response with the given + * name. + */ + public Header getFirstHeader(final String name) { + return responseHeaders.getFirstHeader(name); + } + + /** + * Gets all the headers with the given name that were on the origin + * response. + */ + public Header[] getHeaders(final String name) { + return responseHeaders.getHeaders(name); + } + + /** + * Gets the Date value of the "Date" header or null if the header is missing or cannot be + * parsed. + * + * @since 4.3 + */ + public Date getDate() { + return date; + } + + /** + * Returns the {@link Resource} containing the origin response body. + */ + public Resource getResource() { + return this.resource; + } + + /** + * Indicates whether the origin response indicated the associated + * resource had variants (i.e. that the Vary header was set on the + * origin response). + * @return {@code true} if this cached response was a variant + */ + public boolean hasVariants() { + return getFirstHeader(HeaderConstants.VARY) != null; + } + + /** + * Returns an index about where in the cache different variants for + * a given resource are stored. This maps "variant keys" to "cache keys", + * where the variant key is derived from the varying request headers, + * and the cache key is the location in the + * {@link ch.boye.httpclientandroidlib.client.cache.HttpCacheStorage} where that + * particular variant is stored. The first variant returned is used as + * the "parent" entry to hold this index of the other variants. + */ + public Map<String, String> getVariantMap() { + return Collections.unmodifiableMap(variantMap); + } + + /** + * Provides a string representation of this instance suitable for + * human consumption. + */ + @Override + public String toString() { + return "[request date=" + this.requestDate + "; response date=" + this.responseDate + + "; statusLine=" + this.statusLine + "]"; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheEntrySerializationException.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheEntrySerializationException.java new file mode 100644 index 000000000..e74f64db6 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheEntrySerializationException.java @@ -0,0 +1,48 @@ +/* + * ==================================================================== + * 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.client.cache; + +import java.io.IOException; + +/** + * Thrown if serialization or deserialization of an {@link HttpCacheEntry} + * fails. + */ +public class HttpCacheEntrySerializationException extends IOException { + + private static final long serialVersionUID = 9219188365878433519L; + + public HttpCacheEntrySerializationException(final String message) { + super(); + } + + public HttpCacheEntrySerializationException(final String message, final Throwable cause) { + super(message); + initCause(cause); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheEntrySerializer.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheEntrySerializer.java new file mode 100644 index 000000000..2903fb74d --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheEntrySerializer.java @@ -0,0 +1,54 @@ +/* + * ==================================================================== + * 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.client.cache; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Used by some {@link HttpCacheStorage} implementations to serialize + * {@link HttpCacheEntry} instances to a byte representation before + * storage. + */ +public interface HttpCacheEntrySerializer { + + /** + * Serializes the given entry to a byte representation on the + * given {@link OutputStream}. + * @throws IOException + */ + void writeTo(HttpCacheEntry entry, OutputStream os) throws IOException; + + /** + * Deserializes a byte representation of a cache entry by reading + * from the given {@link InputStream}. + * @throws IOException + */ + HttpCacheEntry readFrom(InputStream is) throws IOException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheInvalidator.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheInvalidator.java new file mode 100644 index 000000000..f8e70968b --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheInvalidator.java @@ -0,0 +1,58 @@ +/* + * ==================================================================== + * 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.client.cache; + +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpResponse; + +/** + * Given a particular HttpRequest, flush any cache entries that this request + * would invalidate. + * + * @since 4.3 + */ +public interface HttpCacheInvalidator { + + /** + * Remove cache entries from the cache that are no longer fresh or have been + * invalidated in some way. + * + * @param host + * The backend host we are talking to + * @param req + * The HttpRequest to that host + */ + void flushInvalidatedCacheEntries(HttpHost host, HttpRequest req); + + /** + * Flushes entries that were invalidated by the given response received for + * the given host/request pair. + */ + void flushInvalidatedCacheEntries(HttpHost host, HttpRequest request, HttpResponse response); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheStorage.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheStorage.java new file mode 100644 index 000000000..b0759d195 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheStorage.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.client.cache; + +import java.io.IOException; + +/** + * New storage backends should implement this {@link HttpCacheStorage} + * interface. They can then be plugged into the existing + * {@link ch.boye.httpclientandroidlib.impl.client.cache.CachingHttpClient} + * implementation. + * + * @since 4.1 + */ +public interface HttpCacheStorage { + + /** + * Store a given cache entry under the given key. + * @param key where in the cache to store the entry + * @param entry cached response to store + * @throws IOException + */ + void putEntry(String key, HttpCacheEntry entry) throws IOException; + + /** + * Retrieves the cache entry stored under the given key + * or null if no entry exists under that key. + * @param key cache key + * @return an {@link HttpCacheEntry} or {@code null} if no + * entry exists + * @throws IOException + */ + HttpCacheEntry getEntry(String key) throws IOException; + + /** + * Deletes/invalidates/removes any cache entries currently + * stored under the given key. + * @param key + * @throws IOException + */ + void removeEntry(String key) throws IOException; + + /** + * Atomically applies the given callback to update an existing cache + * entry under a given key. + * @param key indicates which entry to modify + * @param callback performs the update; see + * {@link HttpCacheUpdateCallback} for details, but roughly the + * callback expects to be handed the current entry and will return + * the new value for the entry. + * @throws IOException + * @throws HttpCacheUpdateException + */ + void updateEntry( + String key, HttpCacheUpdateCallback callback) throws IOException, HttpCacheUpdateException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheUpdateCallback.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheUpdateCallback.java new file mode 100644 index 000000000..abc810fe8 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheUpdateCallback.java @@ -0,0 +1,52 @@ +/* + * ==================================================================== + * 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.client.cache; + +import java.io.IOException; + +/** + * Used for atomically updating entries in a {@link HttpCacheStorage} + * implementation. The current entry (if any) is fed into an implementation + * of this interface, and the new, possibly updated entry (if any) + * should be returned. + */ +public interface HttpCacheUpdateCallback { + + /** + * Returns the new cache entry that should replace an existing one. + * + * @param existing + * the cache entry currently in-place in the cache, possibly + * <code>null</code> if nonexistent + * @return the cache entry that should replace it, again, + * possibly <code>null</code> if the entry should be deleted + * + * @since 4.1 + */ + HttpCacheEntry update(HttpCacheEntry existing) throws IOException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheUpdateException.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheUpdateException.java new file mode 100644 index 000000000..278fe3afb --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/HttpCacheUpdateException.java @@ -0,0 +1,48 @@ +/* + * ==================================================================== + * 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.client.cache; + +/** + * Signals that {@link HttpCacheStorage} encountered an error performing an + * update operation. + * + * @since 4.1 + */ +public class HttpCacheUpdateException extends Exception { + + private static final long serialVersionUID = 823573584868632876L; + + public HttpCacheUpdateException(final String message) { + super(message); + } + + public HttpCacheUpdateException(final String message, final Throwable cause) { + super(message); + initCause(cause); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/InputLimit.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/InputLimit.java new file mode 100644 index 000000000..45ef3b26d --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/InputLimit.java @@ -0,0 +1,76 @@ +/* + * ==================================================================== + * 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.client.cache; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; + +/** + * Used to limiting the size of an incoming response body of + * unknown size that is optimistically being read in anticipation + * of caching it. + * @since 4.1 + */ +@NotThreadSafe // reached +public class InputLimit { + + private final long value; + private boolean reached; + + /** + * Create a limit for how many bytes of a response body to + * read. + * @param value maximum length in bytes + */ + public InputLimit(final long value) { + super(); + this.value = value; + this.reached = false; + } + + /** + * Returns the current maximum limit that was set on + * creation. + */ + public long getValue() { + return this.value; + } + + /** + * Used to report that the limit has been reached. + */ + public void reached() { + this.reached = true; + } + + /** + * Returns {@code true} if the input limit has been reached. + */ + public boolean isReached() { + return this.reached; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/Resource.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/Resource.java new file mode 100644 index 000000000..86811e85c --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/Resource.java @@ -0,0 +1,60 @@ +/* + * ==================================================================== + * 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.client.cache; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; + +/** + * Represents a disposable system resource used for handling + * cached response bodies. + * + * @since 4.1 + */ +public interface Resource extends Serializable { + + /** + * Returns an {@link InputStream} from which the response + * body can be read. + * @throws IOException + */ + InputStream getInputStream() throws IOException; + + /** + * Returns the length in bytes of the response body. + */ + long length(); + + /** + * Indicates the system no longer needs to keep this + * response body and any system resources associated with + * it may be reclaimed. + */ + void dispose(); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/ResourceFactory.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/ResourceFactory.java new file mode 100644 index 000000000..0583d2605 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/ResourceFactory.java @@ -0,0 +1,67 @@ +/* + * ==================================================================== + * 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.client.cache; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Generates {@link Resource} instances for handling cached + * HTTP response bodies. + * + * @since 4.1 + */ +public interface ResourceFactory { + + /** + * Creates a {@link Resource} from a given response body. + * @param requestId a unique identifier for this particular + * response body + * @param instream the original {@link InputStream} + * containing the response body of the origin HTTP response. + * @param limit maximum number of bytes to consume of the + * response body; if this limit is reached before the + * response body is fully consumed, mark the limit has + * having been reached and return a {@code Resource} + * containing the data read to that point. + * @return a {@code Resource} containing however much of + * the response body was successfully read. + * @throws IOException + */ + Resource generate(String requestId, InputStream instream, InputLimit limit) throws IOException; + + /** + * Clones an existing {@link Resource}. + * @param requestId unique identifier provided to associate + * with the cloned response body. + * @param resource the original response body to clone. + * @return the {@code Resource} copy + * @throws IOException + */ + Resource copy(String requestId, Resource resource) throws IOException; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/package.html b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/package.html new file mode 100644 index 000000000..58a1e3ff3 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/cache/package.html @@ -0,0 +1,78 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> +<head> +<!-- +==================================================================== +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/>. +--> +</head> +<body bgcolor="white"> + +<p> +This package consists largely of constants and interfaces that are +necessary for building new storage backends for the +{@link org.apache.http.impl.client.cache.CachingHttpClient} or for +those clients wanting to get a little more behavioral information +out of the cache module (for example, whether a particular response +was a cache hit or not). Developers that simply want to instantiate +and make use of the caching module will be better off looking at +the {@code CachingHttpClient} documentation itself. +</p> +<p> +The classes in this package can be divided into two main groups: +reference constants and interfaces needed for storage backends. In +the former group, +{@link org.apache.http.client.cache.HeaderConstants} contains a list +of HTTP header names encoded as static fields, and the +{@link org.apache.http.client.cache.CacheResponseStatus} enumeration +values are set in an {@link org.apache.http.protocol.HttpContext} by +the {@code CachingHttpClient} to indicate how the request was +processed by the caching module itself. +</p> +<p> +New storage backends will need to implement the +{@link org.apache.http.client.cache.HttpCacheStorage} +interface; they can then be passed to one of the {@code CachingHttpClient} +constructors, which will happily make use of the new storage mechanism. +The {@link org.apache.http.client.cache.HttpCacheEntry} class shows the +datastructure for a cache entry that must be stored by the +{@code HttpCacheStorage}. +There is, in addition, the notion of a +{@link org.apache.http.client.cache.Resource} and an associated +{@link org.apache.http.client.cache.ResourceFactory}, which are used for +managing the handling of cached response bodies. The default implementation +used by the {@code CachingHttpClient} stores response bodies in memory; +alternative implementations might involve storing these in a filesystem. A new +{@code ResourceFactory} can be provided along with a {@code HttpCacheStorage} +in one of the constructors to the {@code CachingHttpClient}. Finally, some +of the additional storage backends we provide, like the +{@link org.apache.http.impl.client.cache.ehcache.EhcacheHttpCacheStorage} and +{@link org.apache.http.impl.client.cache.memcached.MemcachedHttpCacheStorage}, +can be provided with different serializers for the cache entry metadata; +developers wanting to experiment with different serialization techniques +should implement the +{@link org.apache.http.client.cache.HttpCacheEntrySerializer} interface. +</p> +</body> +</html> diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/AuthSchemes.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/AuthSchemes.java new file mode 100644 index 000000000..a8b4db5e0 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/AuthSchemes.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.client.config; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Standard authentication schemes supported by HttpClient. + * + * @since 4.3 + */ +@Immutable +public final class AuthSchemes { + + /** + * Basic authentication scheme as defined in RFC2617 (considered inherently + * insecure, but most widely supported) + */ + public static final String BASIC = "Basic"; + + /** + * Digest authentication scheme as defined in RFC2617. + */ + public static final String DIGEST = "Digest"; + + /** + * The NTLM scheme is a proprietary Microsoft Windows Authentication + * protocol (considered to be the most secure among currently supported + * authentication schemes). + */ + public static final String NTLM = "NTLM"; + + /** + * SPNEGO Authentication scheme. + */ + public static final String SPNEGO = "negotiate"; + + /** + * Kerberos Authentication scheme. + */ + public static final String KERBEROS = "Kerberos"; + + private AuthSchemes() { + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/CookieSpecs.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/CookieSpecs.java new file mode 100644 index 000000000..132c6606f --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/CookieSpecs.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.client.config; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Standard cookie specifications supported by HttpClient. + * + * @since 4.3 + */ +@Immutable +public final class CookieSpecs { + + /** + * The policy that provides high degree of compatibility + * with common cookie management of popular HTTP agents. + */ + public static final String BROWSER_COMPATIBILITY = "compatibility"; + + /** + * The Netscape cookie draft compliant policy. + */ + public static final String NETSCAPE = "netscape"; + + /** + * The RFC 2965 compliant policy (standard). + */ + public static final String STANDARD = "standard"; + + /** + * The default 'best match' policy. + */ + public static final String BEST_MATCH = "best-match"; + + /** + * The policy that ignores cookies. + */ + public static final String IGNORE_COOKIES = "ignoreCookies"; + + private CookieSpecs() { + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/RequestConfig.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/RequestConfig.java new file mode 100644 index 000000000..e861f5e68 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/RequestConfig.java @@ -0,0 +1,442 @@ +/* + * ==================================================================== + * 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.client.config; + +import java.net.InetAddress; +import java.util.Collection; + +import ch.boye.httpclientandroidlib.HttpHost; + +public class RequestConfig implements Cloneable { + + public static final RequestConfig DEFAULT = new Builder().build(); + + private final boolean expectContinueEnabled; + private final HttpHost proxy; + private final InetAddress localAddress; + private final boolean staleConnectionCheckEnabled; + private final String cookieSpec; + private final boolean redirectsEnabled; + private final boolean relativeRedirectsAllowed; + private final boolean circularRedirectsAllowed; + private final int maxRedirects; + private final boolean authenticationEnabled; + private final Collection<String> targetPreferredAuthSchemes; + private final Collection<String> proxyPreferredAuthSchemes; + private final int connectionRequestTimeout; + private final int connectTimeout; + private final int socketTimeout; + + RequestConfig( + final boolean expectContinueEnabled, + final HttpHost proxy, + final InetAddress localAddress, + final boolean staleConnectionCheckEnabled, + final String cookieSpec, + final boolean redirectsEnabled, + final boolean relativeRedirectsAllowed, + final boolean circularRedirectsAllowed, + final int maxRedirects, + final boolean authenticationEnabled, + final Collection<String> targetPreferredAuthSchemes, + final Collection<String> proxyPreferredAuthSchemes, + final int connectionRequestTimeout, + final int connectTimeout, + final int socketTimeout) { + super(); + this.expectContinueEnabled = expectContinueEnabled; + this.proxy = proxy; + this.localAddress = localAddress; + this.staleConnectionCheckEnabled = staleConnectionCheckEnabled; + this.cookieSpec = cookieSpec; + this.redirectsEnabled = redirectsEnabled; + this.relativeRedirectsAllowed = relativeRedirectsAllowed; + this.circularRedirectsAllowed = circularRedirectsAllowed; + this.maxRedirects = maxRedirects; + this.authenticationEnabled = authenticationEnabled; + this.targetPreferredAuthSchemes = targetPreferredAuthSchemes; + this.proxyPreferredAuthSchemes = proxyPreferredAuthSchemes; + this.connectionRequestTimeout = connectionRequestTimeout; + this.connectTimeout = connectTimeout; + this.socketTimeout = socketTimeout; + } + + /** + * Determines whether the 'Expect: 100-Continue' handshake is enabled + * for entity enclosing methods. The purpose of the 'Expect: 100-Continue' + * handshake is to allow a client that is sending a request message with + * a request body to determine if the origin server is willing to + * accept the request (based on the request headers) before the client + * sends the request body. + * <p/> + * The use of the 'Expect: 100-continue' handshake can result in + * a noticeable performance improvement for entity enclosing requests + * (such as POST and PUT) that require the target server's + * authentication. + * <p/> + * 'Expect: 100-continue' handshake should be used with caution, as it + * may cause problems with HTTP servers and proxies that do not support + * HTTP/1.1 protocol. + * <p/> + * Default: <code>false</code> + */ + public boolean isExpectContinueEnabled() { + return expectContinueEnabled; + } + + /** + * Returns HTTP proxy to be used for request execution. + * <p/> + * Default: <code>null</code> + */ + public HttpHost getProxy() { + return proxy; + } + + /** + * Returns local address to be used for request execution. + * <p/> + * On machines with multiple network interfaces, this parameter + * can be used to select the network interface from which the + * connection originates. + * <p/> + * Default: <code>null</code> + */ + public InetAddress getLocalAddress() { + return localAddress; + } + + /** + * Determines whether stale connection check is to be used. The stale + * connection check can cause up to 30 millisecond overhead per request and + * should be used only when appropriate. For performance critical + * operations this check should be disabled. + * <p/> + * Default: <code>true</code> + */ + public boolean isStaleConnectionCheckEnabled() { + return staleConnectionCheckEnabled; + } + + /** + * Determines the name of the cookie specification to be used for HTTP state + * management. + * <p/> + * Default: <code>null</code> + */ + public String getCookieSpec() { + return cookieSpec; + } + + /** + * Determines whether redirects should be handled automatically. + * <p/> + * Default: <code>true</code> + */ + public boolean isRedirectsEnabled() { + return redirectsEnabled; + } + + /** + * Determines whether relative redirects should be rejected. HTTP specification + * requires the location value be an absolute URI. + * <p/> + * Default: <code>true</code> + */ + public boolean isRelativeRedirectsAllowed() { + return relativeRedirectsAllowed; + } + + /** + * Determines whether circular redirects (redirects to the same location) should + * be allowed. The HTTP spec is not sufficiently clear whether circular redirects + * are permitted, therefore optionally they can be enabled + * <p/> + * Default: <code>false</code> + */ + public boolean isCircularRedirectsAllowed() { + return circularRedirectsAllowed; + } + + /** + * Returns the maximum number of redirects to be followed. The limit on number + * of redirects is intended to prevent infinite loops. + * <p/> + * Default: <code>50</code> + */ + public int getMaxRedirects() { + return maxRedirects; + } + + /** + * Determines whether authentication should be handled automatically. + * <p/> + * Default: <code>true</code> + */ + public boolean isAuthenticationEnabled() { + return authenticationEnabled; + } + + /** + * Determines the order of preference for supported authentication schemes + * when authenticating with the target host. + * <p/> + * Default: <code>null</code> + */ + public Collection<String> getTargetPreferredAuthSchemes() { + return targetPreferredAuthSchemes; + } + + /** + * Determines the order of preference for supported authentication schemes + * when authenticating with the proxy host. + * <p/> + * Default: <code>null</code> + */ + public Collection<String> getProxyPreferredAuthSchemes() { + return proxyPreferredAuthSchemes; + } + + /** + * Returns the timeout in milliseconds used when requesting a connection + * from the connection manager. A timeout value of zero is interpreted + * as an infinite timeout. + * <p/> + * A timeout value of zero is interpreted as an infinite timeout. + * A negative value is interpreted as undefined (system default). + * <p/> + * Default: <code>-1</code> + */ + public int getConnectionRequestTimeout() { + return connectionRequestTimeout; + } + + /** + * Determines the timeout in milliseconds until a connection is established. + * A timeout value of zero is interpreted as an infinite timeout. + * <p/> + * A timeout value of zero is interpreted as an infinite timeout. + * A negative value is interpreted as undefined (system default). + * <p/> + * Default: <code>-1</code> + */ + public int getConnectTimeout() { + return connectTimeout; + } + + /** + * Defines the socket timeout (<code>SO_TIMEOUT</code>) in milliseconds, + * which is the timeout for waiting for data or, put differently, + * a maximum period inactivity between two consecutive data packets). + * <p/> + * A timeout value of zero is interpreted as an infinite timeout. + * A negative value is interpreted as undefined (system default). + * <p/> + * Default: <code>-1</code> + */ + public int getSocketTimeout() { + return socketTimeout; + } + + @Override + protected RequestConfig clone() throws CloneNotSupportedException { + return (RequestConfig) super.clone(); + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append(", expectContinueEnabled=").append(expectContinueEnabled); + builder.append(", proxy=").append(proxy); + builder.append(", localAddress=").append(localAddress); + builder.append(", staleConnectionCheckEnabled=").append(staleConnectionCheckEnabled); + builder.append(", cookieSpec=").append(cookieSpec); + builder.append(", redirectsEnabled=").append(redirectsEnabled); + builder.append(", relativeRedirectsAllowed=").append(relativeRedirectsAllowed); + builder.append(", maxRedirects=").append(maxRedirects); + builder.append(", circularRedirectsAllowed=").append(circularRedirectsAllowed); + builder.append(", authenticationEnabled=").append(authenticationEnabled); + builder.append(", targetPreferredAuthSchemes=").append(targetPreferredAuthSchemes); + builder.append(", proxyPreferredAuthSchemes=").append(proxyPreferredAuthSchemes); + builder.append(", connectionRequestTimeout=").append(connectionRequestTimeout); + builder.append(", connectTimeout=").append(connectTimeout); + builder.append(", socketTimeout=").append(socketTimeout); + builder.append("]"); + return builder.toString(); + } + + public static RequestConfig.Builder custom() { + return new Builder(); + } + + public static RequestConfig.Builder copy(final RequestConfig config) { + return new Builder() + .setExpectContinueEnabled(config.isExpectContinueEnabled()) + .setProxy(config.getProxy()) + .setLocalAddress(config.getLocalAddress()) + .setStaleConnectionCheckEnabled(config.isStaleConnectionCheckEnabled()) + .setCookieSpec(config.getCookieSpec()) + .setRedirectsEnabled(config.isRedirectsEnabled()) + .setRelativeRedirectsAllowed(config.isRelativeRedirectsAllowed()) + .setCircularRedirectsAllowed(config.isCircularRedirectsAllowed()) + .setMaxRedirects(config.getMaxRedirects()) + .setAuthenticationEnabled(config.isAuthenticationEnabled()) + .setTargetPreferredAuthSchemes(config.getTargetPreferredAuthSchemes()) + .setProxyPreferredAuthSchemes(config.getProxyPreferredAuthSchemes()) + .setConnectionRequestTimeout(config.getConnectionRequestTimeout()) + .setConnectTimeout(config.getConnectTimeout()) + .setSocketTimeout(config.getSocketTimeout()); + } + + public static class Builder { + + private boolean expectContinueEnabled; + private HttpHost proxy; + private InetAddress localAddress; + private boolean staleConnectionCheckEnabled; + private String cookieSpec; + private boolean redirectsEnabled; + private boolean relativeRedirectsAllowed; + private boolean circularRedirectsAllowed; + private int maxRedirects; + private boolean authenticationEnabled; + private Collection<String> targetPreferredAuthSchemes; + private Collection<String> proxyPreferredAuthSchemes; + private int connectionRequestTimeout; + private int connectTimeout; + private int socketTimeout; + + Builder() { + super(); + this.staleConnectionCheckEnabled = true; + this.redirectsEnabled = true; + this.maxRedirects = 50; + this.relativeRedirectsAllowed = true; + this.authenticationEnabled = true; + this.connectionRequestTimeout = -1; + this.connectTimeout = -1; + this.socketTimeout = -1; + } + + public Builder setExpectContinueEnabled(final boolean expectContinueEnabled) { + this.expectContinueEnabled = expectContinueEnabled; + return this; + } + + public Builder setProxy(final HttpHost proxy) { + this.proxy = proxy; + return this; + } + + public Builder setLocalAddress(final InetAddress localAddress) { + this.localAddress = localAddress; + return this; + } + + public Builder setStaleConnectionCheckEnabled(final boolean staleConnectionCheckEnabled) { + this.staleConnectionCheckEnabled = staleConnectionCheckEnabled; + return this; + } + + public Builder setCookieSpec(final String cookieSpec) { + this.cookieSpec = cookieSpec; + return this; + } + + public Builder setRedirectsEnabled(final boolean redirectsEnabled) { + this.redirectsEnabled = redirectsEnabled; + return this; + } + + public Builder setRelativeRedirectsAllowed(final boolean relativeRedirectsAllowed) { + this.relativeRedirectsAllowed = relativeRedirectsAllowed; + return this; + } + + public Builder setCircularRedirectsAllowed(final boolean circularRedirectsAllowed) { + this.circularRedirectsAllowed = circularRedirectsAllowed; + return this; + } + + public Builder setMaxRedirects(final int maxRedirects) { + this.maxRedirects = maxRedirects; + return this; + } + + public Builder setAuthenticationEnabled(final boolean authenticationEnabled) { + this.authenticationEnabled = authenticationEnabled; + return this; + } + + public Builder setTargetPreferredAuthSchemes(final Collection<String> targetPreferredAuthSchemes) { + this.targetPreferredAuthSchemes = targetPreferredAuthSchemes; + return this; + } + + public Builder setProxyPreferredAuthSchemes(final Collection<String> proxyPreferredAuthSchemes) { + this.proxyPreferredAuthSchemes = proxyPreferredAuthSchemes; + return this; + } + + public Builder setConnectionRequestTimeout(final int connectionRequestTimeout) { + this.connectionRequestTimeout = connectionRequestTimeout; + return this; + } + + public Builder setConnectTimeout(final int connectTimeout) { + this.connectTimeout = connectTimeout; + return this; + } + + public Builder setSocketTimeout(final int socketTimeout) { + this.socketTimeout = socketTimeout; + return this; + } + + public RequestConfig build() { + return new RequestConfig( + expectContinueEnabled, + proxy, + localAddress, + staleConnectionCheckEnabled, + cookieSpec, + redirectsEnabled, + relativeRedirectsAllowed, + circularRedirectsAllowed, + maxRedirects, + authenticationEnabled, + targetPreferredAuthSchemes, + proxyPreferredAuthSchemes, + connectionRequestTimeout, + connectTimeout, + socketTimeout); + } + + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/package-info.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/package-info.java new file mode 100644 index 000000000..a7af2d46b --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/config/package-info.java @@ -0,0 +1,31 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +/** + * Client configuration APIs. + */ +package ch.boye.httpclientandroidlib.client.config; diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/DecompressingEntity.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/DecompressingEntity.java new file mode 100644 index 000000000..9adec5edb --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/DecompressingEntity.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.client.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.entity.HttpEntityWrapper; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Common base class for decompressing {@link HttpEntity} implementations. + * + * @since 4.1 + */ +abstract class DecompressingEntity extends HttpEntityWrapper { + + /** + * Default buffer size. + */ + private static final int BUFFER_SIZE = 1024 * 2; + + /** + * {@link #getContent()} method must return the same {@link InputStream} + * instance when DecompressingEntity is wrapping a streaming entity. + */ + private InputStream content; + + /** + * Creates a new {@link DecompressingEntity}. + * + * @param wrapped + * the non-null {@link HttpEntity} to be wrapped + */ + public DecompressingEntity(final HttpEntity wrapped) { + super(wrapped); + } + + abstract InputStream decorate(final InputStream wrapped) throws IOException; + + private InputStream getDecompressingStream() throws IOException { + final InputStream in = wrappedEntity.getContent(); + return new LazyDecompressingInputStream(in, this); + } + + /** + * {@inheritDoc} + */ + @Override + public InputStream getContent() throws IOException { + if (wrappedEntity.isStreaming()) { + if (content == null) { + content = getDecompressingStream(); + } + return content; + } else { + return getDecompressingStream(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void writeTo(final OutputStream outstream) throws IOException { + Args.notNull(outstream, "Output stream"); + final InputStream instream = getContent(); + try { + final byte[] buffer = new byte[BUFFER_SIZE]; + int l; + while ((l = instream.read(buffer)) != -1) { + outstream.write(buffer, 0, l); + } + } finally { + instream.close(); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/DeflateDecompressingEntity.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/DeflateDecompressingEntity.java new file mode 100644 index 000000000..4bce8b5b5 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/DeflateDecompressingEntity.java @@ -0,0 +1,96 @@ +/* + * ==================================================================== + * 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.client.entity; + +import java.io.IOException; +import java.io.InputStream; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpEntity; + +/** + * {@link ch.boye.httpclientandroidlib.entity.HttpEntityWrapper} responsible for handling + * deflate Content Coded responses. In RFC2616 terms, <code>deflate</code> + * means a <code>zlib</code> stream as defined in RFC1950. Some server + * implementations have misinterpreted RFC2616 to mean that a + * <code>deflate</code> stream as defined in RFC1951 should be used + * (or maybe they did that since that's how IE behaves?). It's confusing + * that <code>deflate</code> in HTTP 1.1 means <code>zlib</code> streams + * rather than <code>deflate</code> streams. We handle both types in here, + * since that's what is seen on the internet. Moral - prefer + * <code>gzip</code>! + * + * @see GzipDecompressingEntity + * + * @since 4.1 + */ +public class DeflateDecompressingEntity extends DecompressingEntity { + + /** + * Creates a new {@link DeflateDecompressingEntity} which will wrap the specified + * {@link HttpEntity}. + * + * @param entity + * a non-null {@link HttpEntity} to be wrapped + */ + public DeflateDecompressingEntity(final HttpEntity entity) { + super(entity); + } + + /** + * Returns the non-null InputStream that should be returned to by all requests to + * {@link #getContent()}. + * + * @return a non-null InputStream + * @throws IOException if there was a problem + */ + @Override + InputStream decorate(final InputStream wrapped) throws IOException { + return new DeflateInputStream(wrapped); + } + + /** + * {@inheritDoc} + */ + @Override + public Header getContentEncoding() { + + /* This HttpEntityWrapper has dealt with the Content-Encoding. */ + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public long getContentLength() { + + /* Length of inflated content is unknown. */ + return -1; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/DeflateInputStream.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/DeflateInputStream.java new file mode 100644 index 000000000..392a28a74 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/DeflateInputStream.java @@ -0,0 +1,228 @@ +/* + * ==================================================================== + * 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.client.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.io.PushbackInputStream; +import java.util.zip.DataFormatException; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; + +/** Deflate input stream. This class includes logic needed for various Rfc's in order +* to reasonably implement the "deflate" compression style. +*/ +public class DeflateInputStream extends InputStream +{ + private InputStream sourceStream; + + public DeflateInputStream(final InputStream wrapped) + throws IOException + { + /* + * A zlib stream will have a header. + * + * CMF | FLG [| DICTID ] | ...compressed data | ADLER32 | + * + * * CMF is one byte. + * + * * FLG is one byte. + * + * * DICTID is four bytes, and only present if FLG.FDICT is set. + * + * Sniff the content. Does it look like a zlib stream, with a CMF, etc? c.f. RFC1950, + * section 2.2. http://tools.ietf.org/html/rfc1950#page-4 + * + * We need to see if it looks like a proper zlib stream, or whether it is just a deflate + * stream. RFC2616 calls zlib streams deflate. Confusing, isn't it? That's why some servers + * implement deflate Content-Encoding using deflate streams, rather than zlib streams. + * + * We could start looking at the bytes, but to be honest, someone else has already read + * the RFCs and implemented that for us. So we'll just use the JDK libraries and exception + * handling to do this. If that proves slow, then we could potentially change this to check + * the first byte - does it look like a CMF? What about the second byte - does it look like + * a FLG, etc. + */ + + /* We read a small buffer to sniff the content. */ + final byte[] peeked = new byte[6]; + + final PushbackInputStream pushback = new PushbackInputStream(wrapped, peeked.length); + + final int headerLength = pushback.read(peeked); + + if (headerLength == -1) { + throw new IOException("Unable to read the response"); + } + + /* We try to read the first uncompressed byte. */ + final byte[] dummy = new byte[1]; + + final Inflater inf = new Inflater(); + + try { + int n; + while ((n = inf.inflate(dummy)) == 0) { + if (inf.finished()) { + + /* Not expecting this, so fail loudly. */ + throw new IOException("Unable to read the response"); + } + + if (inf.needsDictionary()) { + + /* Need dictionary - then it must be zlib stream with DICTID part? */ + break; + } + + if (inf.needsInput()) { + inf.setInput(peeked); + } + } + + if (n == -1) { + throw new IOException("Unable to read the response"); + } + + /* + * We read something without a problem, so it's a valid zlib stream. Just need to reset + * and return an unused InputStream now. + */ + pushback.unread(peeked, 0, headerLength); + sourceStream = new DeflateStream(pushback, new Inflater()); + } catch (final DataFormatException e) { + + /* Presume that it's an RFC1951 deflate stream rather than RFC1950 zlib stream and try + * again. */ + pushback.unread(peeked, 0, headerLength); + sourceStream = new DeflateStream(pushback, new Inflater(true)); + } finally { + inf.end(); + } + + } + + /** Read a byte. + */ + @Override + public int read() + throws IOException + { + return sourceStream.read(); + } + + /** Read lots of bytes. + */ + @Override + public int read(final byte[] b) + throws IOException + { + return sourceStream.read(b); + } + + /** Read lots of specific bytes. + */ + @Override + public int read(final byte[] b, final int off, final int len) + throws IOException + { + return sourceStream.read(b,off,len); + } + + /** Skip + */ + @Override + public long skip(final long n) + throws IOException + { + return sourceStream.skip(n); + } + + /** Get available. + */ + @Override + public int available() + throws IOException + { + return sourceStream.available(); + } + + /** Mark. + */ + @Override + public void mark(final int readLimit) + { + sourceStream.mark(readLimit); + } + + /** Reset. + */ + @Override + public void reset() + throws IOException + { + sourceStream.reset(); + } + + /** Check if mark is supported. + */ + @Override + public boolean markSupported() + { + return sourceStream.markSupported(); + } + + /** Close. + */ + @Override + public void close() + throws IOException + { + sourceStream.close(); + } + + static class DeflateStream extends InflaterInputStream { + + private boolean closed = false; + + public DeflateStream(final InputStream in, final Inflater inflater) { + super(in, inflater); + } + + @Override + public void close() throws IOException { + if (closed) { + return; + } + closed = true; + inf.end(); + super.close(); + } + + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/EntityBuilder.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/EntityBuilder.java new file mode 100644 index 000000000..ebec48a13 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/EntityBuilder.java @@ -0,0 +1,342 @@ +/* + * ==================================================================== + * 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.client.entity; + +import java.io.File; +import java.io.InputStream; +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; + +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.NameValuePair; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.entity.AbstractHttpEntity; +import ch.boye.httpclientandroidlib.entity.BasicHttpEntity; +import ch.boye.httpclientandroidlib.entity.ByteArrayEntity; +import ch.boye.httpclientandroidlib.entity.ContentType; +import ch.boye.httpclientandroidlib.entity.FileEntity; +import ch.boye.httpclientandroidlib.entity.InputStreamEntity; +import ch.boye.httpclientandroidlib.entity.SerializableEntity; +import ch.boye.httpclientandroidlib.entity.StringEntity; + +/** + * Builder for {@link HttpEntity} instances. + * <p/> + * Several setter methods of this builder are mutually exclusive. In case of multiple invocations + * of the following methods only the last one will have effect: + * <ul> + * <li>{@link #setText(String)}</li> + * <li>{@link #setBinary(byte[])}</li> + * <li>{@link #setStream(java.io.InputStream)}</li> + * <li>{@link #setSerializable(java.io.Serializable)}</li> + * <li>{@link #setParameters(java.util.List)}</li> + * <li>{@link #setParameters(ch.boye.httpclientandroidlib.NameValuePair...)}</li> + * <li>{@link #setFile(java.io.File)}</li> + * </ul> + * + * @since 4.3 + */ +@NotThreadSafe +public class EntityBuilder { + + private String text; + private byte[] binary; + private InputStream stream; + private List<NameValuePair> parameters; + private Serializable serializable; + private File file; + private ContentType contentType; + private String contentEncoding; + private boolean chunked; + private boolean gzipCompress; + + EntityBuilder() { + super(); + } + + public static EntityBuilder create() { + return new EntityBuilder(); + } + + private void clearContent() { + this.text = null; + this.binary = null; + this.stream = null; + this.parameters = null; + this.serializable = null; + this.file = null; + } + + /** + * Returns entity content as a string if set using {@link #setText(String)} method. + */ + public String getText() { + return text; + } + + /** + * Sets entity content as a string. This method is mutually exclusive with + * {@link #setBinary(byte[])}, + * {@link #setStream(java.io.InputStream)} , + * {@link #setSerializable(java.io.Serializable)} , + * {@link #setParameters(java.util.List)}, + * {@link #setParameters(ch.boye.httpclientandroidlib.NameValuePair...)} + * {@link #setFile(java.io.File)} methods. + */ + public EntityBuilder setText(final String text) { + clearContent(); + this.text = text; + return this; + } + + /** + * Returns entity content as a byte array if set using + * {@link #setBinary(byte[])} method. + */ + public byte[] getBinary() { + return binary; + } + + /** + * Sets entity content as a byte array. This method is mutually exclusive with + * {@link #setText(String)}, + * {@link #setStream(java.io.InputStream)} , + * {@link #setSerializable(java.io.Serializable)} , + * {@link #setParameters(java.util.List)}, + * {@link #setParameters(ch.boye.httpclientandroidlib.NameValuePair...)} + * {@link #setFile(java.io.File)} methods. + */ + public EntityBuilder setBinary(final byte[] binary) { + clearContent(); + this.binary = binary; + return this; + } + + /** + * Returns entity content as a {@link InputStream} if set using + * {@link #setStream(java.io.InputStream)} method. + */ + public InputStream getStream() { + return stream; + } + + /** + * Sets entity content as a {@link InputStream}. This method is mutually exclusive with + * {@link #setText(String)}, + * {@link #setBinary(byte[])}, + * {@link #setSerializable(java.io.Serializable)} , + * {@link #setParameters(java.util.List)}, + * {@link #setParameters(ch.boye.httpclientandroidlib.NameValuePair...)} + * {@link #setFile(java.io.File)} methods. + */ + public EntityBuilder setStream(final InputStream stream) { + clearContent(); + this.stream = stream; + return this; + } + + /** + * Returns entity content as a parameter list if set using + * {@link #setParameters(java.util.List)} or + * {@link #setParameters(ch.boye.httpclientandroidlib.NameValuePair...)} methods. + */ + public List<NameValuePair> getParameters() { + return parameters; + } + + /** + * Sets entity content as a parameter list. This method is mutually exclusive with + * {@link #setText(String)}, + * {@link #setBinary(byte[])}, + * {@link #setStream(java.io.InputStream)} , + * {@link #setSerializable(java.io.Serializable)} , + * {@link #setFile(java.io.File)} methods. + */ + public EntityBuilder setParameters(final List<NameValuePair> parameters) { + clearContent(); + this.parameters = parameters; + return this; + } + + /** + * Sets entity content as a parameter list. This method is mutually exclusive with + * {@link #setText(String)}, + * {@link #setBinary(byte[])}, + * {@link #setStream(java.io.InputStream)} , + * {@link #setSerializable(java.io.Serializable)} , + * {@link #setFile(java.io.File)} methods. + */ + public EntityBuilder setParameters(final NameValuePair... parameters) { + return setParameters(Arrays.asList(parameters)); + } + + /** + * Returns entity content as a {@link Serializable} if set using + * {@link #setSerializable(java.io.Serializable)} method. + */ + public Serializable getSerializable() { + return serializable; + } + + /** + * Sets entity content as a {@link Serializable}. This method is mutually exclusive with + * {@link #setText(String)}, + * {@link #setBinary(byte[])}, + * {@link #setStream(java.io.InputStream)} , + * {@link #setParameters(java.util.List)}, + * {@link #setParameters(ch.boye.httpclientandroidlib.NameValuePair...)} + * {@link #setFile(java.io.File)} methods. + */ + public EntityBuilder setSerializable(final Serializable serializable) { + clearContent(); + this.serializable = serializable; + return this; + } + + /** + * Returns entity content as a {@link File} if set using + * {@link #setFile(java.io.File)} method. + */ + public File getFile() { + return file; + } + + /** + * Sets entity content as a {@link File}. This method is mutually exclusive with + * {@link #setText(String)}, + * {@link #setBinary(byte[])}, + * {@link #setStream(java.io.InputStream)} , + * {@link #setParameters(java.util.List)}, + * {@link #setParameters(ch.boye.httpclientandroidlib.NameValuePair...)} + * {@link #setSerializable(java.io.Serializable)} methods. + */ + public EntityBuilder setFile(final File file) { + clearContent(); + this.file = file; + return this; + } + + /** + * Returns {@link ContentType} of the entity, if set. + */ + public ContentType getContentType() { + return contentType; + } + + /** + * Sets {@link ContentType} of the entity. + */ + public EntityBuilder setContentType(final ContentType contentType) { + this.contentType = contentType; + return this; + } + + /** + * Returns content encoding of the entity, if set. + */ + public String getContentEncoding() { + return contentEncoding; + } + + /** + * Sets content encoding of the entity. + */ + public EntityBuilder setContentEncoding(final String contentEncoding) { + this.contentEncoding = contentEncoding; + return this; + } + + /** + * Returns <code>true</code> if entity is to be chunk coded, <code>false</code> otherwise. + */ + public boolean isChunked() { + return chunked; + } + + /** + * Makes entity chunk coded. + */ + public EntityBuilder chunked() { + this.chunked = true; + return this; + } + + /** + * Returns <code>true</code> if entity is to be GZIP compressed, <code>false</code> otherwise. + */ + public boolean isGzipCompress() { + return gzipCompress; + } + + /** + * Makes entity GZIP compressed. + */ + public EntityBuilder gzipCompress() { + this.gzipCompress = true; + return this; + } + + private ContentType getContentOrDefault(final ContentType def) { + return this.contentType != null ? this.contentType : def; + } + + /** + * Creates new instance of {@link HttpEntity} based on the current state. + */ + public HttpEntity build() { + final AbstractHttpEntity e; + if (this.text != null) { + e = new StringEntity(this.text, getContentOrDefault(ContentType.DEFAULT_TEXT)); + } else if (this.binary != null) { + e = new ByteArrayEntity(this.binary, getContentOrDefault(ContentType.DEFAULT_BINARY)); + } else if (this.stream != null) { + e = new InputStreamEntity(this.stream, 1, getContentOrDefault(ContentType.DEFAULT_BINARY)); + } else if (this.parameters != null) { + e = new UrlEncodedFormEntity(this.parameters, + this.contentType != null ? this.contentType.getCharset() : null); + } else if (this.serializable != null) { + e = new SerializableEntity(this.serializable); + e.setContentType(ContentType.DEFAULT_BINARY.toString()); + } else if (this.file != null) { + e = new FileEntity(this.file, getContentOrDefault(ContentType.DEFAULT_BINARY)); + } else { + e = new BasicHttpEntity(); + } + if (e.getContentType() != null && this.contentType != null) { + e.setContentType(this.contentType.toString()); + } + e.setContentEncoding(this.contentEncoding); + e.setChunked(this.chunked); + if (this.gzipCompress) { + return new GzipCompressingEntity(e); + } + return e; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/GzipCompressingEntity.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/GzipCompressingEntity.java new file mode 100644 index 000000000..89925a2b9 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/GzipCompressingEntity.java @@ -0,0 +1,113 @@ +/* + * ==================================================================== + * 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.client.entity; + +/* + * ==================================================================== + * 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/>. + * + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.GZIPOutputStream; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.entity.HttpEntityWrapper; +import ch.boye.httpclientandroidlib.message.BasicHeader; +import ch.boye.httpclientandroidlib.protocol.HTTP; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Wrapping entity that compresses content when {@link #writeTo writing}. + * + * + * @since 4.0 + */ +public class GzipCompressingEntity extends HttpEntityWrapper { + + private static final String GZIP_CODEC = "gzip"; + + public GzipCompressingEntity(final HttpEntity entity) { + super(entity); + } + + @Override + public Header getContentEncoding() { + return new BasicHeader(HTTP.CONTENT_ENCODING, GZIP_CODEC); + } + + @Override + public long getContentLength() { + return -1; + } + + @Override + public boolean isChunked() { + // force content chunking + return true; + } + + @Override + public InputStream getContent() throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeTo(final OutputStream outstream) throws IOException { + Args.notNull(outstream, "Output stream"); + final GZIPOutputStream gzip = new GZIPOutputStream(outstream); + wrappedEntity.writeTo(gzip); + // Only close output stream if the wrapped entity has been + // successfully written out + gzip.close(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/GzipDecompressingEntity.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/GzipDecompressingEntity.java new file mode 100644 index 000000000..a3dd5b259 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/GzipDecompressingEntity.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.client.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.GZIPInputStream; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpEntity; + +/** + * {@link ch.boye.httpclientandroidlib.entity.HttpEntityWrapper} for handling gzip + * Content Coded responses. + * + * @since 4.1 + */ +public class GzipDecompressingEntity extends DecompressingEntity { + + /** + * Creates a new {@link GzipDecompressingEntity} which will wrap the specified + * {@link HttpEntity}. + * + * @param entity + * the non-null {@link HttpEntity} to be wrapped + */ + public GzipDecompressingEntity(final HttpEntity entity) { + super(entity); + } + + @Override + InputStream decorate(final InputStream wrapped) throws IOException { + return new GZIPInputStream(wrapped); + } + + /** + * {@inheritDoc} + */ + @Override + public Header getContentEncoding() { + + /* This HttpEntityWrapper has dealt with the Content-Encoding. */ + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public long getContentLength() { + + /* length of ungzipped content is not known */ + return -1; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/LazyDecompressingInputStream.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/LazyDecompressingInputStream.java new file mode 100644 index 000000000..60215ff15 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/LazyDecompressingInputStream.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.client.entity; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Lazy init InputStream wrapper. + */ +@NotThreadSafe +class LazyDecompressingInputStream extends InputStream { + + private final InputStream wrappedStream; + + private final DecompressingEntity decompressingEntity; + + private InputStream wrapperStream; + + public LazyDecompressingInputStream( + final InputStream wrappedStream, + final DecompressingEntity decompressingEntity) { + this.wrappedStream = wrappedStream; + this.decompressingEntity = decompressingEntity; + } + + private void initWrapper() throws IOException { + if (wrapperStream == null) { + wrapperStream = decompressingEntity.decorate(wrappedStream); + } + } + + @Override + public int read() throws IOException { + initWrapper(); + return wrapperStream.read(); + } + + @Override + public int read(final byte[] b) throws IOException { + initWrapper(); + return wrapperStream.read(b); + } + + @Override + public int read(final byte[] b, final int off, final int len) throws IOException { + initWrapper(); + return wrapperStream.read(b, off, len); + } + + @Override + public long skip(final long n) throws IOException { + initWrapper(); + return wrapperStream.skip(n); + } + + @Override + public boolean markSupported() { + return false; + } + + @Override + public int available() throws IOException { + initWrapper(); + return wrapperStream.available(); + } + + @Override + public void close() throws IOException { + try { + if (wrapperStream != null) { + wrapperStream.close(); + } + } finally { + wrappedStream.close(); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/UrlEncodedFormEntity.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/UrlEncodedFormEntity.java new file mode 100644 index 000000000..855155927 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/UrlEncodedFormEntity.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.client.entity; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.List; + +import ch.boye.httpclientandroidlib.NameValuePair; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.client.utils.URLEncodedUtils; +import ch.boye.httpclientandroidlib.entity.ContentType; +import ch.boye.httpclientandroidlib.entity.StringEntity; +import ch.boye.httpclientandroidlib.protocol.HTTP; + +/** + * An entity composed of a list of url-encoded pairs. + * This is typically useful while sending an HTTP POST request. + * + * @since 4.0 + */ +@NotThreadSafe // AbstractHttpEntity is not thread-safe +public class UrlEncodedFormEntity extends StringEntity { + + /** + * Constructs a new {@link UrlEncodedFormEntity} with the list + * of parameters in the specified encoding. + * + * @param parameters list of name/value pairs + * @param charset encoding the name/value pairs be encoded with + * @throws UnsupportedEncodingException if the encoding isn't supported + */ + public UrlEncodedFormEntity ( + final List <? extends NameValuePair> parameters, + final String charset) throws UnsupportedEncodingException { + super(URLEncodedUtils.format(parameters, + charset != null ? charset : HTTP.DEF_CONTENT_CHARSET.name()), + ContentType.create(URLEncodedUtils.CONTENT_TYPE, charset)); + } + + /** + * Constructs a new {@link UrlEncodedFormEntity} with the list + * of parameters in the specified encoding. + * + * @param parameters iterable collection of name/value pairs + * @param charset encoding the name/value pairs be encoded with + * + * @since 4.2 + */ + public UrlEncodedFormEntity ( + final Iterable <? extends NameValuePair> parameters, + final Charset charset) { + super(URLEncodedUtils.format(parameters, + charset != null ? charset : HTTP.DEF_CONTENT_CHARSET), + ContentType.create(URLEncodedUtils.CONTENT_TYPE, charset)); + } + + /** + * Constructs a new {@link UrlEncodedFormEntity} with the list + * of parameters with the default encoding of {@link HTTP#DEFAULT_CONTENT_CHARSET} + * + * @param parameters list of name/value pairs + * @throws UnsupportedEncodingException if the default encoding isn't supported + */ + public UrlEncodedFormEntity ( + final List <? extends NameValuePair> parameters) throws UnsupportedEncodingException { + this(parameters, (Charset) null); + } + + /** + * Constructs a new {@link UrlEncodedFormEntity} with the list + * of parameters with the default encoding of {@link HTTP#DEFAULT_CONTENT_CHARSET} + * + * @param parameters iterable collection of name/value pairs + * + * @since 4.2 + */ + public UrlEncodedFormEntity ( + final Iterable <? extends NameValuePair> parameters) { + this(parameters, null); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/package-info.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/package-info.java new file mode 100644 index 000000000..703f80d58 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/entity/package-info.java @@ -0,0 +1,31 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +/** + * Client specific HTTP entity implementations. + */ +package ch.boye.httpclientandroidlib.client.entity; diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/AbortableHttpRequest.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/AbortableHttpRequest.java new file mode 100644 index 000000000..92715c26a --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/AbortableHttpRequest.java @@ -0,0 +1,82 @@ +/* + * ==================================================================== + * 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.client.methods; + +import ch.boye.httpclientandroidlib.conn.ClientConnectionRequest; +import ch.boye.httpclientandroidlib.conn.ConnectionReleaseTrigger; + +import java.io.IOException; + + +/** + * Interface representing an HTTP request that can be aborted by shutting + * down the underlying HTTP connection. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link HttpExecutionAware} + */ +@Deprecated +public interface AbortableHttpRequest { + + /** + * Sets the {@link ch.boye.httpclientandroidlib.conn.ClientConnectionRequest} + * callback that can be used to abort a long-lived request for a connection. + * If the request is already aborted, throws an {@link IOException}. + * + * @see ch.boye.httpclientandroidlib.conn.ClientConnectionManager + */ + void setConnectionRequest(ClientConnectionRequest connRequest) throws IOException; + + /** + * Sets the {@link ConnectionReleaseTrigger} callback that can + * be used to abort an active connection. + * Typically, this will be the + * {@link ch.boye.httpclientandroidlib.conn.ManagedClientConnection} itself. + * If the request is already aborted, throws an {@link IOException}. + */ + void setReleaseTrigger(ConnectionReleaseTrigger releaseTrigger) throws IOException; + + /** + * Aborts this http request. Any active execution of this method should + * return immediately. If the request has not started, it will abort after + * the next execution. Aborting this request will cause all subsequent + * executions with this request to fail. + * + * @see ch.boye.httpclientandroidlib.client.HttpClient#execute(HttpUriRequest) + * @see ch.boye.httpclientandroidlib.client.HttpClient#execute(ch.boye.httpclientandroidlib.HttpHost, + * ch.boye.httpclientandroidlib.HttpRequest) + * @see ch.boye.httpclientandroidlib.client.HttpClient#execute(HttpUriRequest, + * ch.boye.httpclientandroidlib.protocol.HttpContext) + * @see ch.boye.httpclientandroidlib.client.HttpClient#execute(ch.boye.httpclientandroidlib.HttpHost, + * ch.boye.httpclientandroidlib.HttpRequest, ch.boye.httpclientandroidlib.protocol.HttpContext) + */ + void abort(); + +} + diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/AbstractExecutionAwareRequest.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/AbstractExecutionAwareRequest.java new file mode 100644 index 000000000..2525769c3 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/AbstractExecutionAwareRequest.java @@ -0,0 +1,131 @@ +/* + * ==================================================================== + * 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.client.methods; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.client.utils.CloneUtils; +import ch.boye.httpclientandroidlib.concurrent.Cancellable; +import ch.boye.httpclientandroidlib.conn.ClientConnectionRequest; +import ch.boye.httpclientandroidlib.conn.ConnectionReleaseTrigger; +import ch.boye.httpclientandroidlib.message.AbstractHttpMessage; + +@SuppressWarnings("deprecation") +public abstract class AbstractExecutionAwareRequest extends AbstractHttpMessage implements + HttpExecutionAware, AbortableHttpRequest, Cloneable, HttpRequest { + + private final AtomicBoolean aborted; + private final AtomicReference<Cancellable> cancellableRef; + + protected AbstractExecutionAwareRequest() { + super(); + this.aborted = new AtomicBoolean(false); + this.cancellableRef = new AtomicReference<Cancellable>(null); + } + + @Deprecated + public void setConnectionRequest(final ClientConnectionRequest connRequest) { + setCancellable(new Cancellable() { + + public boolean cancel() { + connRequest.abortRequest(); + return true; + } + + }); + } + + @Deprecated + public void setReleaseTrigger(final ConnectionReleaseTrigger releaseTrigger) { + setCancellable(new Cancellable() { + + public boolean cancel() { + try { + releaseTrigger.abortConnection(); + return true; + } catch (final IOException ex) { + return false; + } + } + + }); + } + + public void abort() { + if (this.aborted.compareAndSet(false, true)) { + final Cancellable cancellable = this.cancellableRef.getAndSet(null); + if (cancellable != null) { + cancellable.cancel(); + } + } + } + + public boolean isAborted() { + return this.aborted.get(); + } + + /** + * @since 4.2 + */ + public void setCancellable(final Cancellable cancellable) { + if (!this.aborted.get()) { + this.cancellableRef.set(cancellable); + } + } + + @Override + public Object clone() throws CloneNotSupportedException { + final AbstractExecutionAwareRequest clone = (AbstractExecutionAwareRequest) super.clone(); + clone.headergroup = CloneUtils.cloneObject(this.headergroup); + clone.params = CloneUtils.cloneObject(this.params); + return clone; + } + + /** + * @since 4.2 + */ + public void completed() { + this.cancellableRef.set(null); + } + + /** + * Resets internal state of the request making it reusable. + * + * @since 4.2 + */ + public void reset() { + final Cancellable cancellable = this.cancellableRef.getAndSet(null); + if (cancellable != null) { + cancellable.cancel(); + } + this.aborted.set(false); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/CloseableHttpResponse.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/CloseableHttpResponse.java new file mode 100644 index 000000000..471a11219 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/CloseableHttpResponse.java @@ -0,0 +1,40 @@ +/* + * ==================================================================== + * 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.client.methods; + +import java.io.Closeable; + +import ch.boye.httpclientandroidlib.HttpResponse; + +/** + * Extended version of the {@link HttpResponse} interface that also extends {@link Closeable}. + * + * @since 4.3 + */ +public interface CloseableHttpResponse extends HttpResponse, Closeable { +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/Configurable.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/Configurable.java new file mode 100644 index 000000000..74f014f20 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/Configurable.java @@ -0,0 +1,44 @@ +/* + * ==================================================================== + * 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.client.methods; + +import ch.boye.httpclientandroidlib.client.config.RequestConfig; + +/** + * Configuration interface for HTTP requests. + * + * @since 4.3 + */ +public interface Configurable { + + /** + * Returns actual request configuration. + */ + RequestConfig getConfig(); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpDelete.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpDelete.java new file mode 100644 index 000000000..20baf651c --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpDelete.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.client.methods; + +import java.net.URI; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; + +/** + * HTTP DELETE method + * <p> + * The HTTP DELETE method is defined in section 9.7 of + * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>: + * <blockquote> + * The DELETE method requests that the origin server delete the resource + * identified by the Request-URI. [...] The client cannot + * be guaranteed that the operation has been carried out, even if the + * status code returned from the origin server indicates that the action + * has been completed successfully. + * </blockquote> + * + * @since 4.0 + */ +@NotThreadSafe // HttpRequestBase is @NotThreadSafe +public class HttpDelete extends HttpRequestBase { + + public final static String METHOD_NAME = "DELETE"; + + + public HttpDelete() { + super(); + } + + public HttpDelete(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpDelete(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpEntityEnclosingRequestBase.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpEntityEnclosingRequestBase.java new file mode 100644 index 000000000..cbc035ade --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpEntityEnclosingRequestBase.java @@ -0,0 +1,76 @@ +/* + * ==================================================================== + * 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.client.methods; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.client.utils.CloneUtils; +import ch.boye.httpclientandroidlib.protocol.HTTP; + +/** + * Basic implementation of an entity enclosing HTTP request + * that can be modified + * + * @since 4.0 + */ +@NotThreadSafe // HttpRequestBase is @NotThreadSafe +public abstract class HttpEntityEnclosingRequestBase + extends HttpRequestBase implements HttpEntityEnclosingRequest { + + private HttpEntity entity; + + public HttpEntityEnclosingRequestBase() { + super(); + } + + public HttpEntity getEntity() { + return this.entity; + } + + public void setEntity(final HttpEntity entity) { + this.entity = entity; + } + + public boolean expectContinue() { + final Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE); + return expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue()); + } + + @Override + public Object clone() throws CloneNotSupportedException { + final HttpEntityEnclosingRequestBase clone = + (HttpEntityEnclosingRequestBase) super.clone(); + if (this.entity != null) { + clone.entity = CloneUtils.cloneObject(this.entity); + } + return clone; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpExecutionAware.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpExecutionAware.java new file mode 100644 index 000000000..6dab381d3 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpExecutionAware.java @@ -0,0 +1,47 @@ +/* + * ==================================================================== + * 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.client.methods; + +import ch.boye.httpclientandroidlib.concurrent.Cancellable; + +/** + * Interface to be implemented by any object that wishes to be notified of + * blocking I/O operations that could be cancelled. + * + * @since 4.3 + */ +public interface HttpExecutionAware { + + boolean isAborted(); + + /** + * Sets {@link Cancellable} for the ongoing operation. + */ + void setCancellable(Cancellable cancellable); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpGet.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpGet.java new file mode 100644 index 000000000..33de1a8dc --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpGet.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.client.methods; + +import java.net.URI; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; + +/** + * HTTP GET method. + * <p> + * The HTTP GET method is defined in section 9.3 of + * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>: + * <blockquote> + * The GET method means retrieve whatever information (in the form of an + * entity) is identified by the Request-URI. If the Request-URI refers + * to a data-producing process, it is the produced data which shall be + * returned as the entity in the response and not the source text of the + * process, unless that text happens to be the output of the process. + * </blockquote> + * </p> + * + * @since 4.0 + */ +@NotThreadSafe +public class HttpGet extends HttpRequestBase { + + public final static String METHOD_NAME = "GET"; + + public HttpGet() { + super(); + } + + public HttpGet(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpGet(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpHead.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpHead.java new file mode 100644 index 000000000..58ab5b00b --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpHead.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.client.methods; + +import java.net.URI; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; + +/** + * HTTP HEAD method. + * <p> + * The HTTP HEAD method is defined in section 9.4 of + * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>: + * <blockquote> + * The HEAD method is identical to GET except that the server MUST NOT + * return a message-body in the response. The metainformation contained + * in the HTTP headers in response to a HEAD request SHOULD be identical + * to the information sent in response to a GET request. This method can + * be used for obtaining metainformation about the entity implied by the + * request without transferring the entity-body itself. This method is + * often used for testing hypertext links for validity, accessibility, + * and recent modification. + * </blockquote> + * </p> + * + * @since 4.0 + */ +@NotThreadSafe +public class HttpHead extends HttpRequestBase { + + public final static String METHOD_NAME = "HEAD"; + + public HttpHead() { + super(); + } + + public HttpHead(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpHead(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpOptions.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpOptions.java new file mode 100644 index 000000000..af3ee251b --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpOptions.java @@ -0,0 +1,100 @@ +/* + * ==================================================================== + * 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.client.methods; + +import java.net.URI; +import java.util.HashSet; +import java.util.Set; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HeaderElement; +import ch.boye.httpclientandroidlib.HeaderIterator; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * HTTP OPTIONS method. + * <p> + * The HTTP OPTIONS method is defined in section 9.2 of + * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>: + * <blockquote> + * The OPTIONS method represents a request for information about the + * communication options available on the request/response chain + * identified by the Request-URI. This method allows the client to + * determine the options and/or requirements associated with a resource, + * or the capabilities of a server, without implying a resource action + * or initiating a resource retrieval. + * </blockquote> + * </p> + * + * @since 4.0 + */ +@NotThreadSafe +public class HttpOptions extends HttpRequestBase { + + public final static String METHOD_NAME = "OPTIONS"; + + public HttpOptions() { + super(); + } + + public HttpOptions(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpOptions(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + + public Set<String> getAllowedMethods(final HttpResponse response) { + Args.notNull(response, "HTTP response"); + + final HeaderIterator it = response.headerIterator("Allow"); + final Set<String> methods = new HashSet<String>(); + while (it.hasNext()) { + final Header header = it.nextHeader(); + final HeaderElement[] elements = header.getElements(); + for (final HeaderElement element : elements) { + methods.add(element.getName()); + } + } + return methods; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpPatch.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpPatch.java new file mode 100644 index 000000000..8cfd29fbb --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpPatch.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.client.methods; + +import java.net.URI; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; + +/** + * HTTP PATCH method. + * <p> + * The HTTP PATCH method is defined in <a + * href="http://tools.ietf.org/html/rfc5789">RF5789</a>: <blockquote> The PATCH + * method requests that a set of changes described in the request entity be + * applied to the resource identified by the Request- URI. Differs from the PUT + * method in the way the server processes the enclosed entity to modify the + * resource identified by the Request-URI. In a PUT request, the enclosed entity + * origin server, and the client is requesting that the stored version be + * replaced. With PATCH, however, the enclosed entity contains a set of + * instructions describing how a resource currently residing on the origin + * server should be modified to produce a new version. </blockquote> + * </p> + * + * @since 4.2 + */ +@NotThreadSafe +public class HttpPatch extends HttpEntityEnclosingRequestBase { + + public final static String METHOD_NAME = "PATCH"; + + public HttpPatch() { + super(); + } + + public HttpPatch(final URI uri) { + super(); + setURI(uri); + } + + public HttpPatch(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpPost.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpPost.java new file mode 100644 index 000000000..f70538b80 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpPost.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.client.methods; + +import java.net.URI; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; + +/** + * HTTP POST method. + * <p> + * The HTTP POST method is defined in section 9.5 of + * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>: + * <blockquote> + * The POST method is used to request that the origin server accept the entity + * enclosed in the request as a new subordinate of the resource identified by + * the Request-URI in the Request-Line. POST is designed to allow a uniform + * method to cover the following functions: + * <ul> + * <li>Annotation of existing resources</li> + * <li>Posting a message to a bulletin board, newsgroup, mailing list, or + * similar group of articles</li> + * <li>Providing a block of data, such as the result of submitting a form, + * to a data-handling process</li> + * <li>Extending a database through an append operation</li> + * </ul> + * </blockquote> + * </p> + * + * @since 4.0 + */ +@NotThreadSafe +public class HttpPost extends HttpEntityEnclosingRequestBase { + + public final static String METHOD_NAME = "POST"; + + public HttpPost() { + super(); + } + + public HttpPost(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpPost(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpPut.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpPut.java new file mode 100644 index 000000000..4aab04b23 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpPut.java @@ -0,0 +1,76 @@ +/* + * ==================================================================== + * 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.client.methods; + +import java.net.URI; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; + +/** + * HTTP PUT method. + * <p> + * The HTTP PUT method is defined in section 9.6 of + * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>: + * <blockquote> + * The PUT method requests that the enclosed entity be stored under the + * supplied Request-URI. If the Request-URI refers to an already + * existing resource, the enclosed entity SHOULD be considered as a + * modified version of the one residing on the origin server. + * </blockquote> + * </p> + * + * @since 4.0 + */ +@NotThreadSafe +public class HttpPut extends HttpEntityEnclosingRequestBase { + + public final static String METHOD_NAME = "PUT"; + + public HttpPut() { + super(); + } + + public HttpPut(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpPut(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpRequestBase.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpRequestBase.java new file mode 100644 index 000000000..da3b01ef5 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpRequestBase.java @@ -0,0 +1,124 @@ +/* + * ==================================================================== + * 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.client.methods; + +import java.net.URI; + +import ch.boye.httpclientandroidlib.ProtocolVersion; +import ch.boye.httpclientandroidlib.RequestLine; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.client.config.RequestConfig; +import ch.boye.httpclientandroidlib.message.BasicRequestLine; +import ch.boye.httpclientandroidlib.params.HttpProtocolParams; + +/** + * Base implementation of {@link HttpUriRequest}. + * + * @since 4.0 + */ +@SuppressWarnings("deprecation") +@NotThreadSafe +public abstract class HttpRequestBase extends AbstractExecutionAwareRequest + implements HttpUriRequest, Configurable { + + private ProtocolVersion version; + private URI uri; + private RequestConfig config; + + public abstract String getMethod(); + + /** + * @since 4.3 + */ + public void setProtocolVersion(final ProtocolVersion version) { + this.version = version; + } + + public ProtocolVersion getProtocolVersion() { + return version != null ? version : HttpProtocolParams.getVersion(getParams()); + } + + /** + * Returns the original request URI. + * <p> + * Please note URI remains unchanged in the course of request execution and + * is not updated if the request is redirected to another location. + */ + public URI getURI() { + return this.uri; + } + + public RequestLine getRequestLine() { + final String method = getMethod(); + final ProtocolVersion ver = getProtocolVersion(); + final URI uri = getURI(); + String uritext = null; + if (uri != null) { + uritext = uri.toASCIIString(); + } + if (uritext == null || uritext.length() == 0) { + uritext = "/"; + } + return new BasicRequestLine(method, uritext, ver); + } + + + public RequestConfig getConfig() { + return config; + } + + public void setConfig(final RequestConfig config) { + this.config = config; + } + + public void setURI(final URI uri) { + this.uri = uri; + } + + /** + * @since 4.2 + */ + public void started() { + } + + /** + * A convenience method to simplify migration from HttpClient 3.1 API. This method is + * equivalent to {@link #reset()}. + * + * @since 4.2 + */ + public void releaseConnection() { + reset(); + } + + @Override + public String toString() { + return getMethod() + " " + getURI() + " " + getProtocolVersion(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpRequestWrapper.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpRequestWrapper.java new file mode 100644 index 000000000..72b7e2c55 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpRequestWrapper.java @@ -0,0 +1,171 @@ +/* + * ==================================================================== + * 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.client.methods; + +import java.net.URI; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.ProtocolVersion; +import ch.boye.httpclientandroidlib.RequestLine; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.message.AbstractHttpMessage; +import ch.boye.httpclientandroidlib.message.BasicRequestLine; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.protocol.HTTP; + +/** + * A wrapper class for {@link HttpRequest} that can be used to change properties of the current + * request without modifying the original object. + * + * @since 4.3 + */ +@SuppressWarnings("deprecation") +@NotThreadSafe +public class HttpRequestWrapper extends AbstractHttpMessage implements HttpUriRequest { + + private final HttpRequest original; + private final String method; + private ProtocolVersion version; + private URI uri; + + private HttpRequestWrapper(final HttpRequest request) { + super(); + this.original = request; + this.version = this.original.getRequestLine().getProtocolVersion(); + this.method = this.original.getRequestLine().getMethod(); + if (request instanceof HttpUriRequest) { + this.uri = ((HttpUriRequest) request).getURI(); + } else { + this.uri = null; + } + setHeaders(request.getAllHeaders()); + } + + public ProtocolVersion getProtocolVersion() { + return this.version != null ? this.version : this.original.getProtocolVersion(); + } + + public void setProtocolVersion(final ProtocolVersion version) { + this.version = version; + } + + public URI getURI() { + return this.uri; + } + + public void setURI(final URI uri) { + this.uri = uri; + } + + public String getMethod() { + return method; + } + + public void abort() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + public boolean isAborted() { + return false; + } + + public RequestLine getRequestLine() { + String requestUri = null; + if (this.uri != null) { + requestUri = this.uri.toASCIIString(); + } else { + requestUri = this.original.getRequestLine().getUri(); + } + if (requestUri == null || requestUri.length() == 0) { + requestUri = "/"; + } + return new BasicRequestLine(this.method, requestUri, getProtocolVersion()); + } + + public HttpRequest getOriginal() { + return this.original; + } + + @Override + public String toString() { + return getRequestLine() + " " + this.headergroup; + } + + static class HttpEntityEnclosingRequestWrapper extends HttpRequestWrapper + implements HttpEntityEnclosingRequest { + + private HttpEntity entity; + + public HttpEntityEnclosingRequestWrapper(final HttpEntityEnclosingRequest request) { + super(request); + this.entity = request.getEntity(); + } + + public HttpEntity getEntity() { + return this.entity; + } + + public void setEntity(final HttpEntity entity) { + this.entity = entity; + } + + public boolean expectContinue() { + final Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE); + return expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue()); + } + + } + + public static HttpRequestWrapper wrap(final HttpRequest request) { + if (request == null) { + return null; + } + if (request instanceof HttpEntityEnclosingRequest) { + return new HttpEntityEnclosingRequestWrapper((HttpEntityEnclosingRequest) request); + } else { + return new HttpRequestWrapper(request); + } + } + + /** + * @deprecated (4.3) use + * {@link ch.boye.httpclientandroidlib.client.config.RequestConfig}. + */ + @Override + @Deprecated + public HttpParams getParams() { + if (this.params == null) { + this.params = original.getParams().copy(); + } + return this.params; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpTrace.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpTrace.java new file mode 100644 index 000000000..1118ea181 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpTrace.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.client.methods; + +import java.net.URI; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; + +/** + * HTTP TRACE method. + * <p> + * The HTTP TRACE method is defined in section 9.6 of + * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>: + * <blockquote> + * The TRACE method is used to invoke a remote, application-layer loop- + * back of the request message. The final recipient of the request + * SHOULD reflect the message received back to the client as the + * entity-body of a 200 (OK) response. The final recipient is either the + * origin server or the first proxy or gateway to receive a Max-Forwards + * value of zero (0) in the request (see section 14.31). A TRACE request + * MUST NOT include an entity. + * </blockquote> + * </p> + * + * @since 4.0 + */ +@NotThreadSafe +public class HttpTrace extends HttpRequestBase { + + public final static String METHOD_NAME = "TRACE"; + + public HttpTrace() { + super(); + } + + public HttpTrace(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpTrace(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpUriRequest.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpUriRequest.java new file mode 100644 index 000000000..8ab14ef85 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/HttpUriRequest.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.client.methods; + +import java.net.URI; + +import ch.boye.httpclientandroidlib.HttpRequest; + +/** + * Extended version of the {@link HttpRequest} interface that provides + * convenience methods to access request properties such as request URI + * and method type. + * + * @since 4.0 + */ +public interface HttpUriRequest extends HttpRequest { + + /** + * Returns the HTTP method this request uses, such as <code>GET</code>, + * <code>PUT</code>, <code>POST</code>, or other. + */ + String getMethod(); + + /** + * Returns the URI this request uses, such as + * <code>http://example.org/path/to/file</code>. + * <br/> + * Note that the URI may be absolute URI (as above) or may be a relative URI. + * <p> + * Implementations are encouraged to return + * the URI that was initially requested. + * </p> + * <p> + * To find the final URI after any redirects have been processed, + * please see the section entitled + * <a href="http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html#d4e205">HTTP execution context</a> + * in the + * <a href="http://hc.apache.org/httpcomponents-client-ga/tutorial/html">HttpClient Tutorial</a> + * </p> + */ + URI getURI(); + + /** + * Aborts execution of the request. + * + * @throws UnsupportedOperationException if the abort operation + * is not supported / cannot be implemented. + */ + void abort() throws UnsupportedOperationException; + + /** + * Tests if the request execution has been aborted. + * + * @return <code>true</code> if the request execution has been aborted, + * <code>false</code> otherwise. + */ + boolean isAborted(); + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/RequestBuilder.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/RequestBuilder.java new file mode 100644 index 000000000..3a45dcd2f --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/RequestBuilder.java @@ -0,0 +1,351 @@ +/* + * ==================================================================== + * 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.client.methods; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HeaderIterator; +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.NameValuePair; +import ch.boye.httpclientandroidlib.ProtocolVersion; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.client.config.RequestConfig; +import ch.boye.httpclientandroidlib.client.entity.UrlEncodedFormEntity; +import ch.boye.httpclientandroidlib.client.utils.URIBuilder; +import ch.boye.httpclientandroidlib.message.BasicHeader; +import ch.boye.httpclientandroidlib.message.BasicNameValuePair; +import ch.boye.httpclientandroidlib.message.HeaderGroup; +import ch.boye.httpclientandroidlib.protocol.HTTP; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Builder for {@link HttpUriRequest} instances. + * <p/> + * Please note that this class treats parameters differently depending on composition + * of the request: if the request has a content entity explicitly set with + * {@link #setEntity(ch.boye.httpclientandroidlib.HttpEntity)} or it is not an entity enclosing method + * (such as POST or PUT), parameters will be added to the query component of the request URI. + * Otherwise, parameters will be added as a URL encoded {@link UrlEncodedFormEntity entity}. + * + * @since 4.3 + */ +@NotThreadSafe +public class RequestBuilder { + + private String method; + private ProtocolVersion version; + private URI uri; + private HeaderGroup headergroup; + private HttpEntity entity; + private LinkedList<NameValuePair> parameters; + private RequestConfig config; + + RequestBuilder(final String method) { + super(); + this.method = method; + } + + RequestBuilder() { + this(null); + } + + public static RequestBuilder create(final String method) { + Args.notBlank(method, "HTTP method"); + return new RequestBuilder(method); + } + + public static RequestBuilder get() { + return new RequestBuilder(HttpGet.METHOD_NAME); + } + + public static RequestBuilder head() { + return new RequestBuilder(HttpHead.METHOD_NAME); + } + + public static RequestBuilder post() { + return new RequestBuilder(HttpPost.METHOD_NAME); + } + + public static RequestBuilder put() { + return new RequestBuilder(HttpPut.METHOD_NAME); + } + + public static RequestBuilder delete() { + return new RequestBuilder(HttpDelete.METHOD_NAME); + } + + public static RequestBuilder trace() { + return new RequestBuilder(HttpTrace.METHOD_NAME); + } + + public static RequestBuilder options() { + return new RequestBuilder(HttpOptions.METHOD_NAME); + } + + public static RequestBuilder copy(final HttpRequest request) { + Args.notNull(request, "HTTP request"); + return new RequestBuilder().doCopy(request); + } + + private RequestBuilder doCopy(final HttpRequest request) { + if (request == null) { + return this; + } + method = request.getRequestLine().getMethod(); + version = request.getRequestLine().getProtocolVersion(); + if (request instanceof HttpUriRequest) { + uri = ((HttpUriRequest) request).getURI(); + } else { + uri = URI.create(request.getRequestLine().getUri()); + } + if (headergroup == null) { + headergroup = new HeaderGroup(); + } + headergroup.clear(); + headergroup.setHeaders(request.getAllHeaders()); + if (request instanceof HttpEntityEnclosingRequest) { + entity = ((HttpEntityEnclosingRequest) request).getEntity(); + } else { + entity = null; + } + if (request instanceof Configurable) { + this.config = ((Configurable) request).getConfig(); + } else { + this.config = null; + } + this.parameters = null; + return this; + } + + public String getMethod() { + return method; + } + + public ProtocolVersion getVersion() { + return version; + } + + public RequestBuilder setVersion(final ProtocolVersion version) { + this.version = version; + return this; + } + + public URI getUri() { + return uri; + } + + public RequestBuilder setUri(final URI uri) { + this.uri = uri; + return this; + } + + public RequestBuilder setUri(final String uri) { + this.uri = uri != null ? URI.create(uri) : null; + return this; + } + + public Header getFirstHeader(final String name) { + return headergroup != null ? headergroup.getFirstHeader(name) : null; + } + + public Header getLastHeader(final String name) { + return headergroup != null ? headergroup.getLastHeader(name) : null; + } + + public Header[] getHeaders(final String name) { + return headergroup != null ? headergroup.getHeaders(name) : null; + } + + public RequestBuilder addHeader(final Header header) { + if (headergroup == null) { + headergroup = new HeaderGroup(); + } + headergroup.addHeader(header); + return this; + } + + public RequestBuilder addHeader(final String name, final String value) { + if (headergroup == null) { + headergroup = new HeaderGroup(); + } + this.headergroup.addHeader(new BasicHeader(name, value)); + return this; + } + + public RequestBuilder removeHeader(final Header header) { + if (headergroup == null) { + headergroup = new HeaderGroup(); + } + headergroup.removeHeader(header); + return this; + } + + public RequestBuilder removeHeaders(final String name) { + if (name == null || headergroup == null) { + return this; + } + for (final HeaderIterator i = headergroup.iterator(); i.hasNext(); ) { + final Header header = i.nextHeader(); + if (name.equalsIgnoreCase(header.getName())) { + i.remove(); + } + } + return this; + } + + public RequestBuilder setHeader(final Header header) { + if (headergroup == null) { + headergroup = new HeaderGroup(); + } + this.headergroup.updateHeader(header); + return this; + } + + public RequestBuilder setHeader(final String name, final String value) { + if (headergroup == null) { + headergroup = new HeaderGroup(); + } + this.headergroup.updateHeader(new BasicHeader(name, value)); + return this; + } + + public HttpEntity getEntity() { + return entity; + } + + public RequestBuilder setEntity(final HttpEntity entity) { + this.entity = entity; + return this; + } + + public List<NameValuePair> getParameters() { + return parameters != null ? new ArrayList<NameValuePair>(parameters) : + new ArrayList<NameValuePair>(); + } + + public RequestBuilder addParameter(final NameValuePair nvp) { + Args.notNull(nvp, "Name value pair"); + if (parameters == null) { + parameters = new LinkedList<NameValuePair>(); + } + parameters.add(nvp); + return this; + } + + public RequestBuilder addParameter(final String name, final String value) { + return addParameter(new BasicNameValuePair(name, value)); + } + + public RequestBuilder addParameters(final NameValuePair... nvps) { + for (final NameValuePair nvp: nvps) { + addParameter(nvp); + } + return this; + } + + public RequestConfig getConfig() { + return config; + } + + public RequestBuilder setConfig(final RequestConfig config) { + this.config = config; + return this; + } + + public HttpUriRequest build() { + final HttpRequestBase result; + URI uri = this.uri != null ? this.uri : URI.create("/"); + HttpEntity entity = this.entity; + if (parameters != null && !parameters.isEmpty()) { + if (entity == null && (HttpPost.METHOD_NAME.equalsIgnoreCase(method) + || HttpPut.METHOD_NAME.equalsIgnoreCase(method))) { + entity = new UrlEncodedFormEntity(parameters, HTTP.DEF_CONTENT_CHARSET); + } else { + try { + uri = new URIBuilder(uri).addParameters(parameters).build(); + } catch (final URISyntaxException ex) { + // should never happen + } + } + } + if (entity == null) { + result = new InternalRequest(method); + } else { + final InternalEntityEclosingRequest request = new InternalEntityEclosingRequest(method); + request.setEntity(entity); + result = request; + } + result.setProtocolVersion(this.version); + result.setURI(uri); + if (this.headergroup != null) { + result.setHeaders(this.headergroup.getAllHeaders()); + } + result.setConfig(this.config); + return result; + } + + static class InternalRequest extends HttpRequestBase { + + private final String method; + + InternalRequest(final String method) { + super(); + this.method = method; + } + + @Override + public String getMethod() { + return this.method; + } + + } + + static class InternalEntityEclosingRequest extends HttpEntityEnclosingRequestBase { + + private final String method; + + InternalEntityEclosingRequest(final String method) { + super(); + this.method = method; + } + + @Override + public String getMethod() { + return this.method; + } + + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/package-info.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/package-info.java new file mode 100644 index 000000000..d8266b2e3 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/methods/package-info.java @@ -0,0 +1,31 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +/** + * Standard HTTP method implementations. + */ +package ch.boye.httpclientandroidlib.client.methods; diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/package-info.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/package-info.java new file mode 100644 index 000000000..2d49a2b99 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/package-info.java @@ -0,0 +1,31 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +/** + * Client HTTP communication APIs. + */ +package ch.boye.httpclientandroidlib.client; diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/AllClientPNames.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/AllClientPNames.java new file mode 100644 index 000000000..aaf591571 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/AllClientPNames.java @@ -0,0 +1,63 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.client.params; + +import ch.boye.httpclientandroidlib.auth.params.AuthPNames; +import ch.boye.httpclientandroidlib.conn.params.ConnConnectionPNames; +import ch.boye.httpclientandroidlib.conn.params.ConnManagerPNames; +import ch.boye.httpclientandroidlib.conn.params.ConnRoutePNames; +import ch.boye.httpclientandroidlib.cookie.params.CookieSpecPNames; +import ch.boye.httpclientandroidlib.params.CoreConnectionPNames; +import ch.boye.httpclientandroidlib.params.CoreProtocolPNames; + +/** + * Collected parameter names for the HttpClient module. + * This interface combines the parameter definitions of the HttpClient + * module and all dependency modules or informational units. + * It does not define additional parameter names, but references + * other interfaces defining parameter names. + * <br/> + * This interface is meant as a navigation aid for developers. + * When referring to parameter names, you should use the interfaces + * in which the respective constants are actually defined. + * + * @since 4.0 + * + * @deprecated (4.3) use + * {@link ch.boye.httpclientandroidlib.client.config.RequestConfig}, + * {@link ch.boye.httpclientandroidlib.config.ConnectionConfig}, + * {@link ch.boye.httpclientandroidlib.config.SocketConfig} + */ +@Deprecated +public interface AllClientPNames extends + CoreConnectionPNames, CoreProtocolPNames, + ClientPNames, AuthPNames, CookieSpecPNames, + ConnConnectionPNames, ConnManagerPNames, ConnRoutePNames { + + // no additional definitions +} + diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/AuthPolicy.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/AuthPolicy.java new file mode 100644 index 000000000..b677ee02f --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/AuthPolicy.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.client.params; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Standard authentication schemes supported by HttpClient. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link ch.boye.httpclientandroidlib.client.config.AuthSchemes}. + */ +@Deprecated +@Immutable +public final class AuthPolicy { + + private AuthPolicy() { + super(); + } + + /** + * The NTLM scheme is a proprietary Microsoft Windows Authentication + * protocol (considered to be the most secure among currently supported + * authentication schemes). + */ + public static final String NTLM = "NTLM"; + + /** + * Digest authentication scheme as defined in RFC2617. + */ + public static final String DIGEST = "Digest"; + + /** + * Basic authentication scheme as defined in RFC2617 (considered inherently + * insecure, but most widely supported) + */ + public static final String BASIC = "Basic"; + + /** + * SPNEGO Authentication scheme. + * + * @since 4.1 + */ + public static final String SPNEGO = "negotiate"; + + /** + * Kerberos Authentication scheme. + * + * @since 4.2 + */ + public static final String KERBEROS = "Kerberos"; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/ClientPNames.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/ClientPNames.java new file mode 100644 index 000000000..796ee40fb --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/ClientPNames.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.client.params; + +/** + * Parameter names for HTTP client parameters. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link ch.boye.httpclientandroidlib.client.config.RequestConfig}. + */ +@Deprecated +public interface ClientPNames { + + public static final String CONNECTION_MANAGER_FACTORY_CLASS_NAME = "http.connection-manager.factory-class-name"; + + /** + * Defines whether redirects should be handled automatically + * <p> + * This parameter expects a value of type {@link Boolean}. + * </p> + */ + public static final String HANDLE_REDIRECTS = "http.protocol.handle-redirects"; + + /** + * Defines whether relative redirects should be rejected. HTTP specification + * requires the location value be an absolute URI. + * <p> + * This parameter expects a value of type {@link Boolean}. + * </p> + */ + public static final String REJECT_RELATIVE_REDIRECT = "http.protocol.reject-relative-redirect"; + + /** + * Defines the maximum number of redirects to be followed. + * The limit on number of redirects is intended to prevent infinite loops. + * <p> + * This parameter expects a value of type {@link Integer}. + * </p> + */ + public static final String MAX_REDIRECTS = "http.protocol.max-redirects"; + + /** + * Defines whether circular redirects (redirects to the same location) should be allowed. + * The HTTP spec is not sufficiently clear whether circular redirects are permitted, + * therefore optionally they can be enabled + * <p> + * This parameter expects a value of type {@link Boolean}. + * </p> + */ + public static final String ALLOW_CIRCULAR_REDIRECTS = "http.protocol.allow-circular-redirects"; + + /** + * Defines whether authentication should be handled automatically. + * <p> + * This parameter expects a value of type {@link Boolean}. + * </p> + */ + public static final String HANDLE_AUTHENTICATION = "http.protocol.handle-authentication"; + + /** + * Defines the name of the cookie specification to be used for HTTP state management. + * <p> + * This parameter expects a value of type {@link String}. + * </p> + */ + public static final String COOKIE_POLICY = "http.protocol.cookie-policy"; + + /** + * Defines the virtual host to be used in the <code>Host</code> + * request header instead of the physical host. + * <p> + * This parameter expects a value of type {@link ch.boye.httpclientandroidlib.HttpHost}. + * </p> + * If a port is not provided, it will be derived from the request URL. + */ + public static final String VIRTUAL_HOST = "http.virtual-host"; + + /** + * Defines the request headers to be sent per default with each request. + * <p> + * This parameter expects a value of type {@link java.util.Collection}. The + * collection is expected to contain {@link ch.boye.httpclientandroidlib.Header}s. + * </p> + */ + public static final String DEFAULT_HEADERS = "http.default-headers"; + + /** + * Defines the default host. The default value will be used if the target host is + * not explicitly specified in the request URI. + * <p> + * This parameter expects a value of type {@link ch.boye.httpclientandroidlib.HttpHost}. + * </p> + */ + public static final String DEFAULT_HOST = "http.default-host"; + + /** + * Defines the timeout in milliseconds used when retrieving an instance of + * {@link ch.boye.httpclientandroidlib.conn.ManagedClientConnection} from the + * {@link ch.boye.httpclientandroidlib.conn.ClientConnectionManager}. + * <p> + * This parameter expects a value of type {@link Long}. + * <p> + * @since 4.2 + */ + public static final String CONN_MANAGER_TIMEOUT = "http.conn-manager.timeout"; + +} + diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/ClientParamBean.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/ClientParamBean.java new file mode 100644 index 000000000..315129d23 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/ClientParamBean.java @@ -0,0 +1,106 @@ +/* + * ==================================================================== + * 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.client.params; + +import java.util.Collection; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.params.HttpAbstractParamBean; +import ch.boye.httpclientandroidlib.params.HttpParams; + +/** + * This is a Java Bean class that can be used to wrap an instance of + * {@link HttpParams} and manipulate HTTP client parameters using + * Java Beans conventions. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link ch.boye.httpclientandroidlib.client.config.RequestConfig}. + */ +@Deprecated +@NotThreadSafe +public class ClientParamBean extends HttpAbstractParamBean { + + public ClientParamBean (final HttpParams params) { + super(params); + } + + /** + * @deprecated (4.2) do not use. + */ + @Deprecated + public void setConnectionManagerFactoryClassName (final String factory) { + params.setParameter(ClientPNames.CONNECTION_MANAGER_FACTORY_CLASS_NAME, factory); + } + + public void setHandleRedirects (final boolean handle) { + params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, handle); + } + + public void setRejectRelativeRedirect (final boolean reject) { + params.setBooleanParameter(ClientPNames.REJECT_RELATIVE_REDIRECT, reject); + } + + public void setMaxRedirects (final int maxRedirects) { + params.setIntParameter(ClientPNames.MAX_REDIRECTS, maxRedirects); + } + + public void setAllowCircularRedirects (final boolean allow) { + params.setBooleanParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, allow); + } + + public void setHandleAuthentication (final boolean handle) { + params.setBooleanParameter(ClientPNames.HANDLE_AUTHENTICATION, handle); + } + + public void setCookiePolicy (final String policy) { + params.setParameter(ClientPNames.COOKIE_POLICY, policy); + } + + public void setVirtualHost (final HttpHost host) { + params.setParameter(ClientPNames.VIRTUAL_HOST, host); + } + + public void setDefaultHeaders (final Collection <Header> headers) { + params.setParameter(ClientPNames.DEFAULT_HEADERS, headers); + } + + public void setDefaultHost (final HttpHost host) { + params.setParameter(ClientPNames.DEFAULT_HOST, host); + } + + /** + * @since 4.2 + */ + public void setConnectionManagerTimeout(final long timeout) { + params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, timeout); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/CookiePolicy.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/CookiePolicy.java new file mode 100644 index 000000000..5c6353b80 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/CookiePolicy.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.client.params; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Standard cookie specifications supported by HttpClient. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link ch.boye.httpclientandroidlib.client.config.CookieSpecs}. + */ +@Deprecated +@Immutable +public final class CookiePolicy { + + /** + * The policy that provides high degree of compatibilty + * with common cookie management of popular HTTP agents. + */ + public static final String BROWSER_COMPATIBILITY = "compatibility"; + + /** + * The Netscape cookie draft compliant policy. + */ + public static final String NETSCAPE = "netscape"; + + /** + * The RFC 2109 compliant policy. + */ + public static final String RFC_2109 = "rfc2109"; + + /** + * The RFC 2965 compliant policy. + */ + public static final String RFC_2965 = "rfc2965"; + + /** + * The default 'best match' policy. + */ + public static final String BEST_MATCH = "best-match"; + + /** + * The policy that ignores cookies. + * + * @since 4.1-beta1 + */ + public static final String IGNORE_COOKIES = "ignoreCookies"; + + private CookiePolicy() { + super(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/HttpClientParamConfig.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/HttpClientParamConfig.java new file mode 100644 index 000000000..515d92ca5 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/HttpClientParamConfig.java @@ -0,0 +1,88 @@ +/* + * ==================================================================== + * 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.client.params; + +import java.net.InetAddress; +import java.util.Collection; + +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.auth.params.AuthPNames; +import ch.boye.httpclientandroidlib.client.config.RequestConfig; +import ch.boye.httpclientandroidlib.conn.params.ConnRoutePNames; +import ch.boye.httpclientandroidlib.params.CoreConnectionPNames; +import ch.boye.httpclientandroidlib.params.CoreProtocolPNames; +import ch.boye.httpclientandroidlib.params.HttpParams; + +/** + * @deprecated (4.3) provided for compatibility with {@link HttpParams}. Do not use. + * + * @since 4.3 + */ +@Deprecated +public final class HttpClientParamConfig { + + private HttpClientParamConfig() { + } + + @SuppressWarnings("unchecked") + public static RequestConfig getRequestConfig(final HttpParams params) { + return RequestConfig.custom() + .setSocketTimeout(params.getIntParameter( + CoreConnectionPNames.SO_TIMEOUT, 0)) + .setStaleConnectionCheckEnabled(params.getBooleanParameter( + CoreConnectionPNames.STALE_CONNECTION_CHECK, true)) + .setConnectTimeout(params.getIntParameter( + CoreConnectionPNames.CONNECTION_TIMEOUT, 0)) + .setExpectContinueEnabled(params.getBooleanParameter( + CoreProtocolPNames.USE_EXPECT_CONTINUE, false)) + .setProxy((HttpHost) params.getParameter( + ConnRoutePNames.DEFAULT_PROXY)) + .setLocalAddress((InetAddress) params.getParameter( + ConnRoutePNames.LOCAL_ADDRESS)) + .setProxyPreferredAuthSchemes((Collection<String>) params.getParameter( + AuthPNames.PROXY_AUTH_PREF)) + .setTargetPreferredAuthSchemes((Collection<String>) params.getParameter( + AuthPNames.TARGET_AUTH_PREF)) + .setAuthenticationEnabled(params.getBooleanParameter( + ClientPNames.HANDLE_AUTHENTICATION, true)) + .setCircularRedirectsAllowed(params.getBooleanParameter( + ClientPNames.ALLOW_CIRCULAR_REDIRECTS, false)) + .setConnectionRequestTimeout((int) params.getLongParameter( + ClientPNames.CONN_MANAGER_TIMEOUT, 0)) + .setCookieSpec((String) params.getParameter( + ClientPNames.COOKIE_POLICY)) + .setMaxRedirects(params.getIntParameter( + ClientPNames.MAX_REDIRECTS, 50)) + .setRedirectsEnabled(params.getBooleanParameter( + ClientPNames.HANDLE_REDIRECTS, true)) + .setRelativeRedirectsAllowed(!params.getBooleanParameter( + ClientPNames.REJECT_RELATIVE_REDIRECT, false)) + .build(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/HttpClientParams.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/HttpClientParams.java new file mode 100644 index 000000000..b2b2a573e --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/HttpClientParams.java @@ -0,0 +1,116 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ +package ch.boye.httpclientandroidlib.client.params; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.params.HttpConnectionParams; +import ch.boye.httpclientandroidlib.params.HttpParams; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * An adaptor for manipulating HTTP client parameters in {@link HttpParams}. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link ch.boye.httpclientandroidlib.client.config.RequestConfig} + */ +@Deprecated +@Immutable +public class HttpClientParams { + + private HttpClientParams() { + super(); + } + + public static boolean isRedirecting(final HttpParams params) { + Args.notNull(params, "HTTP parameters"); + return params.getBooleanParameter + (ClientPNames.HANDLE_REDIRECTS, true); + } + + public static void setRedirecting(final HttpParams params, final boolean value) { + Args.notNull(params, "HTTP parameters"); + params.setBooleanParameter + (ClientPNames.HANDLE_REDIRECTS, value); + } + + public static boolean isAuthenticating(final HttpParams params) { + Args.notNull(params, "HTTP parameters"); + return params.getBooleanParameter + (ClientPNames.HANDLE_AUTHENTICATION, true); + } + + public static void setAuthenticating(final HttpParams params, final boolean value) { + Args.notNull(params, "HTTP parameters"); + params.setBooleanParameter + (ClientPNames.HANDLE_AUTHENTICATION, value); + } + + public static String getCookiePolicy(final HttpParams params) { + Args.notNull(params, "HTTP parameters"); + final String cookiePolicy = (String) + params.getParameter(ClientPNames.COOKIE_POLICY); + if (cookiePolicy == null) { + return CookiePolicy.BEST_MATCH; + } + return cookiePolicy; + } + + public static void setCookiePolicy(final HttpParams params, final String cookiePolicy) { + Args.notNull(params, "HTTP parameters"); + params.setParameter(ClientPNames.COOKIE_POLICY, cookiePolicy); + } + + /** + * Set the parameter {@code ClientPNames.CONN_MANAGER_TIMEOUT}. + * + * @since 4.2 + */ + public static void setConnectionManagerTimeout(final HttpParams params, final long timeout) { + Args.notNull(params, "HTTP parameters"); + params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, timeout); + } + + /** + * Get the connectiion manager timeout value. + * This is defined by the parameter {@code ClientPNames.CONN_MANAGER_TIMEOUT}. + * Failing that it uses the parameter {@code CoreConnectionPNames.CONNECTION_TIMEOUT} + * which defaults to 0 if not defined. + * + * @since 4.2 + * @return the timeout value + */ + public static long getConnectionManagerTimeout(final HttpParams params) { + Args.notNull(params, "HTTP parameters"); + final Long timeout = (Long) params.getParameter(ClientPNames.CONN_MANAGER_TIMEOUT); + if (timeout != null) { + return timeout.longValue(); + } + return HttpConnectionParams.getConnectionTimeout(params); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/package-info.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/package-info.java new file mode 100644 index 000000000..3450f368e --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/params/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/>. + * + */ + +/** + * Deprecated. + * @deprecated (4.3). + */ +package ch.boye.httpclientandroidlib.client.params; diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ClientContext.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ClientContext.java new file mode 100644 index 000000000..1409362f0 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ClientContext.java @@ -0,0 +1,132 @@ +/* + * ==================================================================== + * 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.client.protocol; + +/** + * {@link ch.boye.httpclientandroidlib.protocol.HttpContext} attribute names for + * client side HTTP protocol processing. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link HttpClientContext}. + */ +@Deprecated +public interface ClientContext { + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.conn.routing.RouteInfo} + * object that represents the actual connection route. + * + * @since 4.3 + */ + public static final String ROUTE = "http.route"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.conn.scheme.Scheme} + * object that represents the actual protocol scheme registry. + */ + @Deprecated + public static final String SCHEME_REGISTRY = "http.scheme-registry"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.config.Lookup} object that represents + * the actual {@link ch.boye.httpclientandroidlib.cookie.CookieSpecRegistry} registry. + */ + public static final String COOKIESPEC_REGISTRY = "http.cookiespec-registry"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.cookie.CookieSpec} + * object that represents the actual cookie specification. + */ + public static final String COOKIE_SPEC = "http.cookie-spec"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.cookie.CookieOrigin} + * object that represents the actual details of the origin server. + */ + public static final String COOKIE_ORIGIN = "http.cookie-origin"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.client.CookieStore} + * object that represents the actual cookie store. + */ + public static final String COOKIE_STORE = "http.cookie-store"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.client.CredentialsProvider} + * object that represents the actual credentials provider. + */ + public static final String CREDS_PROVIDER = "http.auth.credentials-provider"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.client.AuthCache} object + * that represents the auth scheme cache. + */ + public static final String AUTH_CACHE = "http.auth.auth-cache"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.auth.AuthState} + * object that represents the actual target authentication state. + */ + public static final String TARGET_AUTH_STATE = "http.auth.target-scope"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.auth.AuthState} + * object that represents the actual proxy authentication state. + */ + public static final String PROXY_AUTH_STATE = "http.auth.proxy-scope"; + + /** + * @deprecated (4.1) do not use + */ + @Deprecated + public static final String AUTH_SCHEME_PREF = "http.auth.scheme-pref"; + + /** + * Attribute name of a {@link java.lang.Object} object that represents + * the actual user identity such as user {@link java.security.Principal}. + */ + public static final String USER_TOKEN = "http.user-token"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.config.Lookup} object that represents + * the actual {@link ch.boye.httpclientandroidlib.auth.AuthSchemeRegistry} registry. + */ + public static final String AUTHSCHEME_REGISTRY = "http.authscheme-registry"; + + public static final String SOCKET_FACTORY_REGISTRY = "http.socket-factory-registry"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.client.config.RequestConfig} object that + * represents the actual request configuration. + * + * @since 4.3 + */ + public static final String REQUEST_CONFIG = "http.request-config"; + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ClientContextConfigurer.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ClientContextConfigurer.java new file mode 100644 index 000000000..29628a83d --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ClientContextConfigurer.java @@ -0,0 +1,72 @@ +/* + * ==================================================================== + * 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.client.protocol; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.auth.AuthSchemeRegistry; +import ch.boye.httpclientandroidlib.client.CookieStore; +import ch.boye.httpclientandroidlib.client.CredentialsProvider; +import ch.boye.httpclientandroidlib.cookie.CookieSpecRegistry; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Configuration facade for {@link HttpContext} instances. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link HttpClientContext} + */ +@NotThreadSafe +@Deprecated +public class ClientContextConfigurer implements ClientContext { + + private final HttpContext context; + + public ClientContextConfigurer (final HttpContext context) { + Args.notNull(context, "HTTP context"); + this.context = context; + } + + public void setCookieSpecRegistry(final CookieSpecRegistry registry) { + this.context.setAttribute(COOKIESPEC_REGISTRY, registry); + } + + public void setAuthSchemeRegistry(final AuthSchemeRegistry registry) { + this.context.setAttribute(AUTHSCHEME_REGISTRY, registry); + } + + public void setCookieStore(final CookieStore store) { + this.context.setAttribute(COOKIE_STORE, store); + } + + public void setCredentialsProvider(final CredentialsProvider provider) { + this.context.setAttribute(CREDS_PROVIDER, provider); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/HttpClientContext.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/HttpClientContext.java new file mode 100644 index 000000000..7b73e8d64 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/HttpClientContext.java @@ -0,0 +1,249 @@ +/* + * ==================================================================== + * 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.client.protocol; + +import java.net.URI; +import java.util.List; + +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.auth.AuthSchemeProvider; +import ch.boye.httpclientandroidlib.auth.AuthState; +import ch.boye.httpclientandroidlib.client.AuthCache; +import ch.boye.httpclientandroidlib.client.CookieStore; +import ch.boye.httpclientandroidlib.client.CredentialsProvider; +import ch.boye.httpclientandroidlib.client.config.RequestConfig; +import ch.boye.httpclientandroidlib.config.Lookup; +import ch.boye.httpclientandroidlib.conn.routing.HttpRoute; +import ch.boye.httpclientandroidlib.conn.routing.RouteInfo; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieSpec; +import ch.boye.httpclientandroidlib.cookie.CookieSpecProvider; +import ch.boye.httpclientandroidlib.protocol.BasicHttpContext; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.protocol.HttpCoreContext; + +/** + * Adaptor class that provides convenience type safe setters and getters + * for common {@link HttpContext} attributes used in the course + * of HTTP request execution. + * + * @since 4.3 + */ +@NotThreadSafe +public class HttpClientContext extends HttpCoreContext { + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.conn.routing.RouteInfo} + * object that represents the actual connection route. + */ + public static final String HTTP_ROUTE = "http.route"; + + /** + * Attribute name of a {@link List} object that represents a collection of all + * redirect locations received in the process of request execution. + */ + public static final String REDIRECT_LOCATIONS = "http.protocol.redirect-locations"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.config.Lookup} object that represents + * the actual {@link CookieSpecProvider} registry. + */ + public static final String COOKIESPEC_REGISTRY = "http.cookiespec-registry"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.cookie.CookieSpec} + * object that represents the actual cookie specification. + */ + public static final String COOKIE_SPEC = "http.cookie-spec"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.cookie.CookieOrigin} + * object that represents the actual details of the origin server. + */ + public static final String COOKIE_ORIGIN = "http.cookie-origin"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.client.CookieStore} + * object that represents the actual cookie store. + */ + public static final String COOKIE_STORE = "http.cookie-store"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.client.CredentialsProvider} + * object that represents the actual credentials provider. + */ + public static final String CREDS_PROVIDER = "http.auth.credentials-provider"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.client.AuthCache} object + * that represents the auth scheme cache. + */ + public static final String AUTH_CACHE = "http.auth.auth-cache"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.auth.AuthState} + * object that represents the actual target authentication state. + */ + public static final String TARGET_AUTH_STATE = "http.auth.target-scope"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.auth.AuthState} + * object that represents the actual proxy authentication state. + */ + public static final String PROXY_AUTH_STATE = "http.auth.proxy-scope"; + + /** + * Attribute name of a {@link java.lang.Object} object that represents + * the actual user identity such as user {@link java.security.Principal}. + */ + public static final String USER_TOKEN = "http.user-token"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.config.Lookup} object that represents + * the actual {@link AuthSchemeProvider} registry. + */ + public static final String AUTHSCHEME_REGISTRY = "http.authscheme-registry"; + + /** + * Attribute name of a {@link ch.boye.httpclientandroidlib.client.config.RequestConfig} object that + * represents the actual request configuration. + */ + public static final String REQUEST_CONFIG = "http.request-config"; + + public static HttpClientContext adapt(final HttpContext context) { + if (context instanceof HttpClientContext) { + return (HttpClientContext) context; + } else { + return new HttpClientContext(context); + } + } + + public static HttpClientContext create() { + return new HttpClientContext(new BasicHttpContext()); + } + + public HttpClientContext(final HttpContext context) { + super(context); + } + + public HttpClientContext() { + super(); + } + + public RouteInfo getHttpRoute() { + return getAttribute(HTTP_ROUTE, HttpRoute.class); + } + + @SuppressWarnings("unchecked") + public List<URI> getRedirectLocations() { + return getAttribute(REDIRECT_LOCATIONS, List.class); + } + + public CookieStore getCookieStore() { + return getAttribute(COOKIE_STORE, CookieStore.class); + } + + public void setCookieStore(final CookieStore cookieStore) { + setAttribute(COOKIE_STORE, cookieStore); + } + + public CookieSpec getCookieSpec() { + return getAttribute(COOKIE_SPEC, CookieSpec.class); + } + + public CookieOrigin getCookieOrigin() { + return getAttribute(COOKIE_ORIGIN, CookieOrigin.class); + } + + @SuppressWarnings("unchecked") + private <T> Lookup<T> getLookup(final String name, final Class<T> clazz) { + return getAttribute(name, Lookup.class); + } + + public Lookup<CookieSpecProvider> getCookieSpecRegistry() { + return getLookup(COOKIESPEC_REGISTRY, CookieSpecProvider.class); + } + + public void setCookieSpecRegistry(final Lookup<CookieSpecProvider> lookup) { + setAttribute(COOKIESPEC_REGISTRY, lookup); + } + + public Lookup<AuthSchemeProvider> getAuthSchemeRegistry() { + return getLookup(AUTHSCHEME_REGISTRY, AuthSchemeProvider.class); + } + + public void setAuthSchemeRegistry(final Lookup<AuthSchemeProvider> lookup) { + setAttribute(AUTHSCHEME_REGISTRY, lookup); + } + + public CredentialsProvider getCredentialsProvider() { + return getAttribute(CREDS_PROVIDER, CredentialsProvider.class); + } + + public void setCredentialsProvider(final CredentialsProvider credentialsProvider) { + setAttribute(CREDS_PROVIDER, credentialsProvider); + } + + public AuthCache getAuthCache() { + return getAttribute(AUTH_CACHE, AuthCache.class); + } + + public void setAuthCache(final AuthCache authCache) { + setAttribute(AUTH_CACHE, authCache); + } + + public AuthState getTargetAuthState() { + return getAttribute(TARGET_AUTH_STATE, AuthState.class); + } + + public AuthState getProxyAuthState() { + return getAttribute(PROXY_AUTH_STATE, AuthState.class); + } + + public <T> T getUserToken(final Class<T> clazz) { + return getAttribute(USER_TOKEN, clazz); + } + + public Object getUserToken() { + return getAttribute(USER_TOKEN); + } + + public void setUserToken(final Object obj) { + setAttribute(USER_TOKEN, obj); + } + + public RequestConfig getRequestConfig() { + final RequestConfig config = getAttribute(REQUEST_CONFIG, RequestConfig.class); + return config != null ? config : RequestConfig.DEFAULT; + } + + public void setRequestConfig(final RequestConfig config) { + setAttribute(REQUEST_CONFIG, config); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAcceptEncoding.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAcceptEncoding.java new file mode 100644 index 000000000..1c0d642d3 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAcceptEncoding.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.client.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.protocol.HttpContext; + +/** + * Class responsible for handling Content Encoding requests in HTTP. + * <p> + * Instances of this class are stateless, therefore they're thread-safe and immutable. + * + * @see "http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5" + * + * @since 4.1 + */ +@Immutable +public class RequestAcceptEncoding implements HttpRequestInterceptor { + + /** + * Adds the header {@code "Accept-Encoding: gzip,deflate"} to the request. + */ + public void process( + final HttpRequest request, + final HttpContext context) throws HttpException, IOException { + + /* Signal support for Accept-Encoding transfer encodings. */ + if (!request.containsHeader("Accept-Encoding")) { + request.addHeader("Accept-Encoding", "gzip,deflate"); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAddCookies.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAddCookies.java new file mode 100644 index 000000000..ad2768043 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAddCookies.java @@ -0,0 +1,204 @@ +/* + * ==================================================================== + * 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.client.protocol; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog; +/* LogFactory removed by HttpClient for Android script. */ +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.client.CookieStore; +import ch.boye.httpclientandroidlib.client.config.CookieSpecs; +import ch.boye.httpclientandroidlib.client.config.RequestConfig; +import ch.boye.httpclientandroidlib.client.methods.HttpUriRequest; +import ch.boye.httpclientandroidlib.config.Lookup; +import ch.boye.httpclientandroidlib.conn.routing.RouteInfo; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieSpec; +import ch.boye.httpclientandroidlib.cookie.CookieSpecProvider; +import ch.boye.httpclientandroidlib.cookie.SetCookie2; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.util.Args; +import ch.boye.httpclientandroidlib.util.TextUtils; + +/** + * Request interceptor that matches cookies available in the current + * {@link CookieStore} to the request being executed and generates + * corresponding <code>Cookie</code> request headers. + * + * @since 4.0 + */ +@Immutable +public class RequestAddCookies implements HttpRequestInterceptor { + + public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass()); + + public RequestAddCookies() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + Args.notNull(context, "HTTP context"); + + final String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase("CONNECT")) { + return; + } + + final HttpClientContext clientContext = HttpClientContext.adapt(context); + + // Obtain cookie store + final CookieStore cookieStore = clientContext.getCookieStore(); + if (cookieStore == null) { + this.log.debug("Cookie store not specified in HTTP context"); + return; + } + + // Obtain the registry of cookie specs + final Lookup<CookieSpecProvider> registry = clientContext.getCookieSpecRegistry(); + if (registry == null) { + this.log.debug("CookieSpec registry not specified in HTTP context"); + return; + } + + // Obtain the target host, possibly virtual (required) + final HttpHost targetHost = clientContext.getTargetHost(); + if (targetHost == null) { + this.log.debug("Target host not set in the context"); + return; + } + + // Obtain the route (required) + final RouteInfo route = clientContext.getHttpRoute(); + if (route == null) { + this.log.debug("Connection route not set in the context"); + return; + } + + final RequestConfig config = clientContext.getRequestConfig(); + String policy = config.getCookieSpec(); + if (policy == null) { + policy = CookieSpecs.BEST_MATCH; + } + if (this.log.isDebugEnabled()) { + this.log.debug("CookieSpec selected: " + policy); + } + + URI requestURI = null; + if (request instanceof HttpUriRequest) { + requestURI = ((HttpUriRequest) request).getURI(); + } else { + try { + requestURI = new URI(request.getRequestLine().getUri()); + } catch (final URISyntaxException ignore) { + } + } + final String path = requestURI != null ? requestURI.getPath() : null; + final String hostName = targetHost.getHostName(); + int port = targetHost.getPort(); + if (port < 0) { + port = route.getTargetHost().getPort(); + } + + final CookieOrigin cookieOrigin = new CookieOrigin( + hostName, + port >= 0 ? port : 0, + !TextUtils.isEmpty(path) ? path : "/", + route.isSecure()); + + // Get an instance of the selected cookie policy + final CookieSpecProvider provider = registry.lookup(policy); + if (provider == null) { + throw new HttpException("Unsupported cookie policy: " + policy); + } + final CookieSpec cookieSpec = provider.create(clientContext); + // Get all cookies available in the HTTP state + final List<Cookie> cookies = new ArrayList<Cookie>(cookieStore.getCookies()); + // Find cookies matching the given origin + final List<Cookie> matchedCookies = new ArrayList<Cookie>(); + final Date now = new Date(); + for (final Cookie cookie : cookies) { + if (!cookie.isExpired(now)) { + if (cookieSpec.match(cookie, cookieOrigin)) { + if (this.log.isDebugEnabled()) { + this.log.debug("Cookie " + cookie + " match " + cookieOrigin); + } + matchedCookies.add(cookie); + } + } else { + if (this.log.isDebugEnabled()) { + this.log.debug("Cookie " + cookie + " expired"); + } + } + } + // Generate Cookie request headers + if (!matchedCookies.isEmpty()) { + final List<Header> headers = cookieSpec.formatCookies(matchedCookies); + for (final Header header : headers) { + request.addHeader(header); + } + } + + final int ver = cookieSpec.getVersion(); + if (ver > 0) { + boolean needVersionHeader = false; + for (final Cookie cookie : matchedCookies) { + if (ver != cookie.getVersion() || !(cookie instanceof SetCookie2)) { + needVersionHeader = true; + } + } + + if (needVersionHeader) { + final Header header = cookieSpec.getVersionHeader(); + if (header != null) { + // Advertise cookie version support + request.addHeader(header); + } + } + } + + // Stick the CookieSpec and CookieOrigin instances to the HTTP context + // so they could be obtained by the response interceptor + context.setAttribute(HttpClientContext.COOKIE_SPEC, cookieSpec); + context.setAttribute(HttpClientContext.COOKIE_ORIGIN, cookieOrigin); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAuthCache.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAuthCache.java new file mode 100644 index 000000000..08102cfc8 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAuthCache.java @@ -0,0 +1,147 @@ +/* + * ==================================================================== + * 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.client.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog; +/* LogFactory removed by HttpClient for Android script. */ +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.auth.AuthProtocolState; +import ch.boye.httpclientandroidlib.auth.AuthScheme; +import ch.boye.httpclientandroidlib.auth.AuthScope; +import ch.boye.httpclientandroidlib.auth.AuthState; +import ch.boye.httpclientandroidlib.auth.Credentials; +import ch.boye.httpclientandroidlib.client.AuthCache; +import ch.boye.httpclientandroidlib.client.CredentialsProvider; +import ch.boye.httpclientandroidlib.conn.routing.RouteInfo; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Request interceptor that can preemptively authenticate against known hosts, + * if there is a cached {@link AuthScheme} instance in the local + * {@link AuthCache} associated with the given target or proxy host. + * + * @since 4.1 + */ +@Immutable +public class RequestAuthCache implements HttpRequestInterceptor { + + public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass()); + + public RequestAuthCache() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + Args.notNull(context, "HTTP context"); + + final HttpClientContext clientContext = HttpClientContext.adapt(context); + + final AuthCache authCache = clientContext.getAuthCache(); + if (authCache == null) { + this.log.debug("Auth cache not set in the context"); + return; + } + + final CredentialsProvider credsProvider = clientContext.getCredentialsProvider(); + if (credsProvider == null) { + this.log.debug("Credentials provider not set in the context"); + return; + } + + final RouteInfo route = clientContext.getHttpRoute(); + if (route == null) { + this.log.debug("Route info not set in the context"); + return; + } + + HttpHost target = clientContext.getTargetHost(); + if (target == null) { + this.log.debug("Target host not set in the context"); + return; + } + + if (target.getPort() < 0) { + target = new HttpHost( + target.getHostName(), + route.getTargetHost().getPort(), + target.getSchemeName()); + } + + final AuthState targetState = clientContext.getTargetAuthState(); + if (targetState != null && targetState.getState() == AuthProtocolState.UNCHALLENGED) { + final AuthScheme authScheme = authCache.get(target); + if (authScheme != null) { + doPreemptiveAuth(target, authScheme, targetState, credsProvider); + } + } + + final HttpHost proxy = route.getProxyHost(); + final AuthState proxyState = clientContext.getProxyAuthState(); + if (proxy != null && proxyState != null && proxyState.getState() == AuthProtocolState.UNCHALLENGED) { + final AuthScheme authScheme = authCache.get(proxy); + if (authScheme != null) { + doPreemptiveAuth(proxy, authScheme, proxyState, credsProvider); + } + } + } + + private void doPreemptiveAuth( + final HttpHost host, + final AuthScheme authScheme, + final AuthState authState, + final CredentialsProvider credsProvider) { + final String schemeName = authScheme.getSchemeName(); + if (this.log.isDebugEnabled()) { + this.log.debug("Re-using cached '" + schemeName + "' auth scheme for " + host); + } + + final AuthScope authScope = new AuthScope(host, AuthScope.ANY_REALM, schemeName); + final Credentials creds = credsProvider.getCredentials(authScope); + + if (creds != null) { + if ("BASIC".equalsIgnoreCase(authScheme.getSchemeName())) { + authState.setState(AuthProtocolState.CHALLENGED); + } else { + authState.setState(AuthProtocolState.SUCCESS); + } + authState.update(authScheme, creds); + } else { + this.log.debug("No credentials for preemptive authentication"); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAuthenticationBase.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAuthenticationBase.java new file mode 100644 index 000000000..19e07054b --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestAuthenticationBase.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.client.protocol; + +import java.util.Queue; + +import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog; +/* LogFactory removed by HttpClient for Android script. */ +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.HttpRequestInterceptor; +import ch.boye.httpclientandroidlib.auth.AuthOption; +import ch.boye.httpclientandroidlib.auth.AuthScheme; +import ch.boye.httpclientandroidlib.auth.AuthState; +import ch.boye.httpclientandroidlib.auth.AuthenticationException; +import ch.boye.httpclientandroidlib.auth.ContextAwareAuthScheme; +import ch.boye.httpclientandroidlib.auth.Credentials; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.util.Asserts; + +@Deprecated +abstract class RequestAuthenticationBase implements HttpRequestInterceptor { + + final HttpClientAndroidLog log = new HttpClientAndroidLog(getClass()); + + public RequestAuthenticationBase() { + super(); + } + + void process( + final AuthState authState, + final HttpRequest request, + final HttpContext context) { + AuthScheme authScheme = authState.getAuthScheme(); + Credentials creds = authState.getCredentials(); + switch (authState.getState()) { + case FAILURE: + return; + case SUCCESS: + ensureAuthScheme(authScheme); + if (authScheme.isConnectionBased()) { + return; + } + break; + case CHALLENGED: + final Queue<AuthOption> authOptions = authState.getAuthOptions(); + if (authOptions != null) { + while (!authOptions.isEmpty()) { + final AuthOption authOption = authOptions.remove(); + authScheme = authOption.getAuthScheme(); + creds = authOption.getCredentials(); + authState.update(authScheme, creds); + if (this.log.isDebugEnabled()) { + this.log.debug("Generating response to an authentication challenge using " + + authScheme.getSchemeName() + " scheme"); + } + try { + final Header header = authenticate(authScheme, creds, request, context); + request.addHeader(header); + break; + } catch (final AuthenticationException ex) { + if (this.log.isWarnEnabled()) { + this.log.warn(authScheme + " authentication error: " + ex.getMessage()); + } + } + } + return; + } else { + ensureAuthScheme(authScheme); + } + } + if (authScheme != null) { + try { + final Header header = authenticate(authScheme, creds, request, context); + request.addHeader(header); + } catch (final AuthenticationException ex) { + if (this.log.isErrorEnabled()) { + this.log.error(authScheme + " authentication error: " + ex.getMessage()); + } + } + } + } + + private void ensureAuthScheme(final AuthScheme authScheme) { + Asserts.notNull(authScheme, "Auth scheme"); + } + + private Header authenticate( + final AuthScheme authScheme, + final Credentials creds, + final HttpRequest request, + final HttpContext context) throws AuthenticationException { + Asserts.notNull(authScheme, "Auth scheme"); + if (authScheme instanceof ContextAwareAuthScheme) { + return ((ContextAwareAuthScheme) authScheme).authenticate(creds, request, context); + } else { + return authScheme.authenticate(creds, request); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestClientConnControl.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestClientConnControl.java new file mode 100644 index 000000000..714b2859b --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestClientConnControl.java @@ -0,0 +1,92 @@ +/* + * ==================================================================== + * 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.client.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog; +/* LogFactory removed by HttpClient for Android script. */ +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.conn.routing.RouteInfo; +import ch.boye.httpclientandroidlib.protocol.HTTP; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * This protocol interceptor is responsible for adding <code>Connection</code> + * or <code>Proxy-Connection</code> headers to the outgoing requests, which + * is essential for managing persistence of <code>HTTP/1.0</code> connections. + * + * @since 4.0 + */ +@Immutable +public class RequestClientConnControl implements HttpRequestInterceptor { + + public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass()); + + private static final String PROXY_CONN_DIRECTIVE = "Proxy-Connection"; + + public RequestClientConnControl() { + 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")) { + request.setHeader(PROXY_CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); + return; + } + + final HttpClientContext clientContext = HttpClientContext.adapt(context); + + // Obtain the client connection (required) + final RouteInfo route = clientContext.getHttpRoute(); + if (route == null) { + this.log.debug("Connection route not set in the context"); + return; + } + + if (route.getHopCount() == 1 || route.isTunnelled()) { + if (!request.containsHeader(HTTP.CONN_DIRECTIVE)) { + request.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); + } + } + if (route.getHopCount() == 2 && !route.isTunnelled()) { + if (!request.containsHeader(PROXY_CONN_DIRECTIVE)) { + request.addHeader(PROXY_CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); + } + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestDefaultHeaders.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestDefaultHeaders.java new file mode 100644 index 000000000..c4414f1f4 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestDefaultHeaders.java @@ -0,0 +1,89 @@ +/* + * ==================================================================== + * 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.client.protocol; + +import java.io.IOException; +import java.util.Collection; + +import ch.boye.httpclientandroidlib.Header; +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.client.params.ClientPNames; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Request interceptor that adds default request headers. + * + * @since 4.0 + */ +@SuppressWarnings("deprecation") +@Immutable +public class RequestDefaultHeaders implements HttpRequestInterceptor { + + private final Collection<? extends Header> defaultHeaders; + + /** + * @since 4.3 + */ + public RequestDefaultHeaders(final Collection<? extends Header> defaultHeaders) { + super(); + this.defaultHeaders = defaultHeaders; + } + + public RequestDefaultHeaders() { + this(null); + } + + 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; + } + + // Add default headers + @SuppressWarnings("unchecked") + Collection<? extends Header> defHeaders = (Collection<? extends Header>) + request.getParams().getParameter(ClientPNames.DEFAULT_HEADERS); + if (defHeaders == null) { + defHeaders = this.defaultHeaders; + } + + if (defHeaders != null) { + for (final Header defHeader : defHeaders) { + request.addHeader(defHeader); + } + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestExpectContinue.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestExpectContinue.java new file mode 100644 index 000000000..237004f0f --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestExpectContinue.java @@ -0,0 +1,82 @@ +/* + * ==================================================================== + * 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.client.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.client.config.RequestConfig; +import ch.boye.httpclientandroidlib.protocol.HTTP; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * RequestExpectContinue is responsible for enabling the 'expect-continue' + * handshake by adding <code>Expect</code> header. + * <p/> + * This interceptor takes into account {@link RequestConfig#isExpectContinueEnabled()} + * setting. + * + * @since 4.3 + */ +@Immutable +public class RequestExpectContinue implements HttpRequestInterceptor { + + public RequestExpectContinue() { + super(); + } + + 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 HttpClientContext clientContext = HttpClientContext.adapt(context); + final RequestConfig config = clientContext.getRequestConfig(); + if (config.isExpectContinueEnabled()) { + request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE); + } + } + } + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestProxyAuthentication.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestProxyAuthentication.java new file mode 100644 index 000000000..e67468ff8 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestProxyAuthentication.java @@ -0,0 +1,92 @@ +/* + * ==================================================================== + * 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.client.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.auth.AUTH; +import ch.boye.httpclientandroidlib.auth.AuthState; +import ch.boye.httpclientandroidlib.conn.HttpRoutedConnection; +import ch.boye.httpclientandroidlib.conn.routing.HttpRoute; +import ch.boye.httpclientandroidlib.protocol.ExecutionContext; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Generates authentication header for the proxy host, if required, + * based on the actual state of the HTTP authentication context. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link ch.boye.httpclientandroidlib.impl.auth.HttpAuthenticator}. + */ +@Deprecated +@Immutable +public class RequestProxyAuthentication extends RequestAuthenticationBase { + + public RequestProxyAuthentication() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + Args.notNull(context, "HTTP context"); + + if (request.containsHeader(AUTH.PROXY_AUTH_RESP)) { + return; + } + + final HttpRoutedConnection conn = (HttpRoutedConnection) context.getAttribute( + ExecutionContext.HTTP_CONNECTION); + if (conn == null) { + this.log.debug("HTTP connection not set in the context"); + return; + } + final HttpRoute route = conn.getRoute(); + if (route.isTunnelled()) { + return; + } + + // Obtain authentication state + final AuthState authState = (AuthState) context.getAttribute( + ClientContext.PROXY_AUTH_STATE); + if (authState == null) { + this.log.debug("Proxy auth state not set in the context"); + return; + } + if (this.log.isDebugEnabled()) { + this.log.debug("Proxy auth state: " + authState.getState()); + } + process(authState, request, context); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestTargetAuthentication.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestTargetAuthentication.java new file mode 100644 index 000000000..dd5c52597 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/RequestTargetAuthentication.java @@ -0,0 +1,83 @@ +/* + * ==================================================================== + * 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.client.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpRequest; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.auth.AUTH; +import ch.boye.httpclientandroidlib.auth.AuthState; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Generates authentication header for the target host, if required, + * based on the actual state of the HTTP authentication context. + * + * @since 4.0 + * + * @deprecated (4.3) use {@link ch.boye.httpclientandroidlib.impl.auth.HttpAuthenticator}. + */ +@Deprecated +@Immutable +public class RequestTargetAuthentication extends RequestAuthenticationBase { + + public RequestTargetAuthentication() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + Args.notNull(request, "HTTP request"); + Args.notNull(context, "HTTP context"); + + final String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase("CONNECT")) { + return; + } + + if (request.containsHeader(AUTH.WWW_AUTH_RESP)) { + return; + } + + // Obtain authentication state + final AuthState authState = (AuthState) context.getAttribute( + ClientContext.TARGET_AUTH_STATE); + if (authState == null) { + this.log.debug("Target auth state not set in the context"); + return; + } + if (this.log.isDebugEnabled()) { + this.log.debug("Target auth state: " + authState.getState()); + } + process(authState, request, context); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ResponseAuthCache.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ResponseAuthCache.java new file mode 100644 index 000000000..fc51012f6 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ResponseAuthCache.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.client.protocol; + +import java.io.IOException; + +import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog; +/* LogFactory removed by HttpClient for Android script. */ +import ch.boye.httpclientandroidlib.HttpException; +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.HttpResponseInterceptor; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.auth.AuthScheme; +import ch.boye.httpclientandroidlib.auth.AuthState; +import ch.boye.httpclientandroidlib.client.AuthCache; +import ch.boye.httpclientandroidlib.client.params.AuthPolicy; +import ch.boye.httpclientandroidlib.conn.scheme.Scheme; +import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry; +import ch.boye.httpclientandroidlib.impl.client.BasicAuthCache; +import ch.boye.httpclientandroidlib.protocol.ExecutionContext; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Response interceptor that adds successfully completed {@link AuthScheme}s + * to the local {@link AuthCache} instance. Cached {@link AuthScheme}s can be + * re-used when executing requests against known hosts, thus avoiding + * additional authentication round-trips. + * + * @since 4.1 + * + * @deprecated (4.2) use {@link ch.boye.httpclientandroidlib.client.AuthenticationStrategy} + */ +@Immutable +@Deprecated +public class ResponseAuthCache implements HttpResponseInterceptor { + + public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass()); + + public ResponseAuthCache() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + Args.notNull(response, "HTTP request"); + Args.notNull(context, "HTTP context"); + AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE); + + HttpHost target = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST); + final AuthState targetState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE); + if (target != null && targetState != null) { + if (this.log.isDebugEnabled()) { + this.log.debug("Target auth state: " + targetState.getState()); + } + if (isCachable(targetState)) { + final SchemeRegistry schemeRegistry = (SchemeRegistry) context.getAttribute( + ClientContext.SCHEME_REGISTRY); + if (target.getPort() < 0) { + final Scheme scheme = schemeRegistry.getScheme(target); + target = new HttpHost(target.getHostName(), + scheme.resolvePort(target.getPort()), target.getSchemeName()); + } + if (authCache == null) { + authCache = new BasicAuthCache(); + context.setAttribute(ClientContext.AUTH_CACHE, authCache); + } + switch (targetState.getState()) { + case CHALLENGED: + cache(authCache, target, targetState.getAuthScheme()); + break; + case FAILURE: + uncache(authCache, target, targetState.getAuthScheme()); + } + } + } + + final HttpHost proxy = (HttpHost) context.getAttribute(ExecutionContext.HTTP_PROXY_HOST); + final AuthState proxyState = (AuthState) context.getAttribute(ClientContext.PROXY_AUTH_STATE); + if (proxy != null && proxyState != null) { + if (this.log.isDebugEnabled()) { + this.log.debug("Proxy auth state: " + proxyState.getState()); + } + if (isCachable(proxyState)) { + if (authCache == null) { + authCache = new BasicAuthCache(); + context.setAttribute(ClientContext.AUTH_CACHE, authCache); + } + switch (proxyState.getState()) { + case CHALLENGED: + cache(authCache, proxy, proxyState.getAuthScheme()); + break; + case FAILURE: + uncache(authCache, proxy, proxyState.getAuthScheme()); + } + } + } + } + + private boolean isCachable(final AuthState authState) { + final AuthScheme authScheme = authState.getAuthScheme(); + if (authScheme == null || !authScheme.isComplete()) { + return false; + } + final String schemeName = authScheme.getSchemeName(); + return schemeName.equalsIgnoreCase(AuthPolicy.BASIC) || + schemeName.equalsIgnoreCase(AuthPolicy.DIGEST); + } + + private void cache(final AuthCache authCache, final HttpHost host, final AuthScheme authScheme) { + if (this.log.isDebugEnabled()) { + this.log.debug("Caching '" + authScheme.getSchemeName() + + "' auth scheme for " + host); + } + authCache.put(host, authScheme); + } + + private void uncache(final AuthCache authCache, final HttpHost host, final AuthScheme authScheme) { + if (this.log.isDebugEnabled()) { + this.log.debug("Removing from cache '" + authScheme.getSchemeName() + + "' auth scheme for " + host); + } + authCache.remove(host); + } +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ResponseContentEncoding.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ResponseContentEncoding.java new file mode 100644 index 000000000..df3ee4457 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ResponseContentEncoding.java @@ -0,0 +1,110 @@ +/* + * ==================================================================== + * 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.client.protocol; + +import java.io.IOException; +import java.util.Locale; + +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HeaderElement; +import ch.boye.httpclientandroidlib.HttpEntity; +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.client.entity.DeflateDecompressingEntity; +import ch.boye.httpclientandroidlib.client.entity.GzipDecompressingEntity; +import ch.boye.httpclientandroidlib.protocol.HttpContext; + +/** + * {@link HttpResponseInterceptor} responsible for processing Content-Encoding + * responses. + * <p> + * Instances of this class are stateless and immutable, therefore threadsafe. + * + * @since 4.1 + * + */ +@Immutable +public class ResponseContentEncoding implements HttpResponseInterceptor { + + public static final String UNCOMPRESSED = "http.client.response.uncompressed"; + + /** + * Handles the following {@code Content-Encoding}s by + * using the appropriate decompressor to wrap the response Entity: + * <ul> + * <li>gzip - see {@link GzipDecompressingEntity}</li> + * <li>deflate - see {@link DeflateDecompressingEntity}</li> + * <li>identity - no action needed</li> + * </ul> + * + * @param response the response which contains the entity + * @param context not currently used + * + * @throws HttpException if the {@code Content-Encoding} is none of the above + */ + public void process( + final HttpResponse response, + final HttpContext context) throws HttpException, IOException { + final HttpEntity entity = response.getEntity(); + + // entity can be null in case of 304 Not Modified, 204 No Content or similar + // check for zero length entity. + if (entity != null && entity.getContentLength() != 0) { + final Header ceheader = entity.getContentEncoding(); + if (ceheader != null) { + final HeaderElement[] codecs = ceheader.getElements(); + boolean uncompressed = false; + for (final HeaderElement codec : codecs) { + final String codecname = codec.getName().toLowerCase(Locale.ENGLISH); + if ("gzip".equals(codecname) || "x-gzip".equals(codecname)) { + response.setEntity(new GzipDecompressingEntity(response.getEntity())); + uncompressed = true; + break; + } else if ("deflate".equals(codecname)) { + response.setEntity(new DeflateDecompressingEntity(response.getEntity())); + uncompressed = true; + break; + } else if ("identity".equals(codecname)) { + + /* Don't need to transform the content - no-op */ + return; + } else { + throw new HttpException("Unsupported Content-Coding: " + codec.getName()); + } + } + if (uncompressed) { + response.removeHeaders("Content-Length"); + response.removeHeaders("Content-Encoding"); + response.removeHeaders("Content-MD5"); + } + } + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ResponseProcessCookies.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ResponseProcessCookies.java new file mode 100644 index 000000000..06827bfdc --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/ResponseProcessCookies.java @@ -0,0 +1,156 @@ +/* + * ==================================================================== + * 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.client.protocol; + +import java.io.IOException; +import java.util.List; + +import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog; +/* LogFactory removed by HttpClient for Android script. */ +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HeaderIterator; +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.client.CookieStore; +import ch.boye.httpclientandroidlib.cookie.Cookie; +import ch.boye.httpclientandroidlib.cookie.CookieOrigin; +import ch.boye.httpclientandroidlib.cookie.CookieSpec; +import ch.boye.httpclientandroidlib.cookie.MalformedCookieException; +import ch.boye.httpclientandroidlib.cookie.SM; +import ch.boye.httpclientandroidlib.protocol.HttpContext; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * Response interceptor that populates the current {@link CookieStore} with data + * contained in response cookies received in the given the HTTP response. + * + * @since 4.0 + */ +@Immutable +public class ResponseProcessCookies implements HttpResponseInterceptor { + + public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass()); + + public ResponseProcessCookies() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + Args.notNull(response, "HTTP request"); + Args.notNull(context, "HTTP context"); + + final HttpClientContext clientContext = HttpClientContext.adapt(context); + + // Obtain actual CookieSpec instance + final CookieSpec cookieSpec = clientContext.getCookieSpec(); + if (cookieSpec == null) { + this.log.debug("Cookie spec not specified in HTTP context"); + return; + } + // Obtain cookie store + final CookieStore cookieStore = clientContext.getCookieStore(); + if (cookieStore == null) { + this.log.debug("Cookie store not specified in HTTP context"); + return; + } + // Obtain actual CookieOrigin instance + final CookieOrigin cookieOrigin = clientContext.getCookieOrigin(); + if (cookieOrigin == null) { + this.log.debug("Cookie origin not specified in HTTP context"); + return; + } + HeaderIterator it = response.headerIterator(SM.SET_COOKIE); + processCookies(it, cookieSpec, cookieOrigin, cookieStore); + + // see if the cookie spec supports cookie versioning. + if (cookieSpec.getVersion() > 0) { + // process set-cookie2 headers. + // Cookie2 will replace equivalent Cookie instances + it = response.headerIterator(SM.SET_COOKIE2); + processCookies(it, cookieSpec, cookieOrigin, cookieStore); + } + } + + private void processCookies( + final HeaderIterator iterator, + final CookieSpec cookieSpec, + final CookieOrigin cookieOrigin, + final CookieStore cookieStore) { + while (iterator.hasNext()) { + final Header header = iterator.nextHeader(); + try { + final List<Cookie> cookies = cookieSpec.parse(header, cookieOrigin); + for (final Cookie cookie : cookies) { + try { + cookieSpec.validate(cookie, cookieOrigin); + cookieStore.addCookie(cookie); + + if (this.log.isDebugEnabled()) { + this.log.debug("Cookie accepted [" + formatCooke(cookie) + "]"); + } + } catch (final MalformedCookieException ex) { + if (this.log.isWarnEnabled()) { + this.log.warn("Cookie rejected [" + formatCooke(cookie) + "] " + + ex.getMessage()); + } + } + } + } catch (final MalformedCookieException ex) { + if (this.log.isWarnEnabled()) { + this.log.warn("Invalid cookie header: \"" + + header + "\". " + ex.getMessage()); + } + } + } + } + + private static String formatCooke(final Cookie cookie) { + final StringBuilder buf = new StringBuilder(); + buf.append(cookie.getName()); + buf.append("=\""); + String v = cookie.getValue(); + if (v.length() > 100) { + v = v.substring(0, 100) + "..."; + } + buf.append(v); + buf.append("\""); + buf.append(", version:"); + buf.append(Integer.toString(cookie.getVersion())); + buf.append(", domain:"); + buf.append(cookie.getDomain()); + buf.append(", path:"); + buf.append(cookie.getPath()); + buf.append(", expiry:"); + buf.append(cookie.getExpiryDate()); + return buf.toString(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/package-info.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/package-info.java new file mode 100644 index 000000000..a585e614d --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/protocol/package-info.java @@ -0,0 +1,31 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +/** + * Client specific HTTP protocol handlers. + */ +package ch.boye.httpclientandroidlib.client.protocol; diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/CloneUtils.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/CloneUtils.java new file mode 100644 index 000000000..67f70ee07 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/CloneUtils.java @@ -0,0 +1,86 @@ +/* + * ==================================================================== + * 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.client.utils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * A collection of utilities to workaround limitations of Java clone framework. + * + * @since 4.0 + */ +@Immutable +public class CloneUtils { + + /** + * @since 4.3 + */ + public static <T> T cloneObject(final T obj) throws CloneNotSupportedException { + if (obj == null) { + return null; + } + if (obj instanceof Cloneable) { + final Class<?> clazz = obj.getClass (); + final Method m; + try { + m = clazz.getMethod("clone", (Class[]) null); + } catch (final NoSuchMethodException ex) { + throw new NoSuchMethodError(ex.getMessage()); + } + try { + @SuppressWarnings("unchecked") // OK because clone() preserves the class + final T result = (T) m.invoke(obj, (Object []) null); + return result; + } catch (final InvocationTargetException ex) { + final Throwable cause = ex.getCause(); + if (cause instanceof CloneNotSupportedException) { + throw ((CloneNotSupportedException) cause); + } else { + throw new Error("Unexpected exception", cause); + } + } catch (final IllegalAccessException ex) { + throw new IllegalAccessError(ex.getMessage()); + } + } else { + throw new CloneNotSupportedException(); + } + } + + public static Object clone(final Object obj) throws CloneNotSupportedException { + return cloneObject(obj); + } + + /** + * This class should not be instantiated. + */ + private CloneUtils() { + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/DateUtils.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/DateUtils.java new file mode 100644 index 000000000..e337923d3 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/DateUtils.java @@ -0,0 +1,250 @@ +/* + * ==================================================================== + * 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.client.utils; + +import java.lang.ref.SoftReference; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.util.Args; + +/** + * A utility class for parsing and formatting HTTP dates as used in cookies and + * other headers. This class handles dates as defined by RFC 2616 section + * 3.3.1 as well as some other common non-standard formats. + * + * @since 4.3 + */ +@Immutable +public final class DateUtils { + + /** + * Date format pattern used to parse HTTP date headers in RFC 1123 format. + */ + public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"; + + /** + * Date format pattern used to parse HTTP date headers in RFC 1036 format. + */ + public static final String PATTERN_RFC1036 = "EEE, dd-MMM-yy HH:mm:ss zzz"; + + /** + * Date format pattern used to parse HTTP date headers in ANSI C + * <code>asctime()</code> format. + */ + public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy"; + + private static final String[] DEFAULT_PATTERNS = new String[] { + PATTERN_RFC1123, + PATTERN_RFC1036, + PATTERN_ASCTIME + }; + + private static final Date DEFAULT_TWO_DIGIT_YEAR_START; + + public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + + static { + final Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(GMT); + calendar.set(2000, Calendar.JANUARY, 1, 0, 0, 0); + calendar.set(Calendar.MILLISECOND, 0); + DEFAULT_TWO_DIGIT_YEAR_START = calendar.getTime(); + } + + /** + * Parses a date value. The formats used for parsing the date value are retrieved from + * the default http params. + * + * @param dateValue the date value to parse + * + * @return the parsed date or null if input could not be parsed + */ + public static Date parseDate(final String dateValue) { + return parseDate(dateValue, null, null); + } + + /** + * Parses the date value using the given date formats. + * + * @param dateValue the date value to parse + * @param dateFormats the date formats to use + * + * @return the parsed date or null if input could not be parsed + */ + public static Date parseDate(final String dateValue, final String[] dateFormats) { + return parseDate(dateValue, dateFormats, null); + } + + /** + * Parses the date value using the given date formats. + * + * @param dateValue the date value to parse + * @param dateFormats the date formats to use + * @param startDate During parsing, two digit years will be placed in the range + * <code>startDate</code> to <code>startDate + 100 years</code>. This value may + * be <code>null</code>. When <code>null</code> is given as a parameter, year + * <code>2000</code> will be used. + * + * @return the parsed date or null if input could not be parsed + */ + public static Date parseDate( + final String dateValue, + final String[] dateFormats, + final Date startDate) { + Args.notNull(dateValue, "Date value"); + final String[] localDateFormats = dateFormats != null ? dateFormats : DEFAULT_PATTERNS; + final Date localStartDate = startDate != null ? startDate : DEFAULT_TWO_DIGIT_YEAR_START; + String v = dateValue; + // trim single quotes around date if present + // see issue #5279 + if (v.length() > 1 && v.startsWith("'") && v.endsWith("'")) { + v = v.substring (1, v.length() - 1); + } + + for (final String dateFormat : localDateFormats) { + final SimpleDateFormat dateParser = DateFormatHolder.formatFor(dateFormat); + dateParser.set2DigitYearStart(localStartDate); + final ParsePosition pos = new ParsePosition(0); + final Date result = dateParser.parse(v, pos); + if (pos.getIndex() != 0) { + return result; + } + } + return null; + } + + /** + * Formats the given date according to the RFC 1123 pattern. + * + * @param date The date to format. + * @return An RFC 1123 formatted date string. + * + * @see #PATTERN_RFC1123 + */ + public static String formatDate(final Date date) { + return formatDate(date, PATTERN_RFC1123); + } + + /** + * Formats the given date according to the specified pattern. The pattern + * must conform to that used by the {@link SimpleDateFormat simple date + * format} class. + * + * @param date The date to format. + * @param pattern The pattern to use for formatting the date. + * @return A formatted date string. + * + * @throws IllegalArgumentException If the given date pattern is invalid. + * + * @see SimpleDateFormat + */ + public static String formatDate(final Date date, final String pattern) { + Args.notNull(date, "Date"); + Args.notNull(pattern, "Pattern"); + final SimpleDateFormat formatter = DateFormatHolder.formatFor(pattern); + return formatter.format(date); + } + + /** + * Clears thread-local variable containing {@link java.text.DateFormat} cache. + * + * @since 4.3 + */ + public static void clearThreadLocal() { + DateFormatHolder.clearThreadLocal(); + } + + /** This class should not be instantiated. */ + private DateUtils() { + } + + /** + * A factory for {@link SimpleDateFormat}s. The instances are stored in a + * threadlocal way because SimpleDateFormat is not threadsafe as noted in + * {@link SimpleDateFormat its javadoc}. + * + */ + final static class DateFormatHolder { + + private static final ThreadLocal<SoftReference<Map<String, SimpleDateFormat>>> + THREADLOCAL_FORMATS = new ThreadLocal<SoftReference<Map<String, SimpleDateFormat>>>() { + + @Override + protected SoftReference<Map<String, SimpleDateFormat>> initialValue() { + return new SoftReference<Map<String, SimpleDateFormat>>( + new HashMap<String, SimpleDateFormat>()); + } + + }; + + /** + * creates a {@link SimpleDateFormat} for the requested format string. + * + * @param pattern + * a non-<code>null</code> format String according to + * {@link SimpleDateFormat}. The format is not checked against + * <code>null</code> since all paths go through + * {@link DateUtils}. + * @return the requested format. This simple dateformat should not be used + * to {@link SimpleDateFormat#applyPattern(String) apply} to a + * different pattern. + */ + public static SimpleDateFormat formatFor(final String pattern) { + final SoftReference<Map<String, SimpleDateFormat>> ref = THREADLOCAL_FORMATS.get(); + Map<String, SimpleDateFormat> formats = ref.get(); + if (formats == null) { + formats = new HashMap<String, SimpleDateFormat>(); + THREADLOCAL_FORMATS.set( + new SoftReference<Map<String, SimpleDateFormat>>(formats)); + } + + SimpleDateFormat format = formats.get(pattern); + if (format == null) { + format = new SimpleDateFormat(pattern, Locale.US); + format.setTimeZone(TimeZone.getTimeZone("GMT")); + formats.put(pattern, format); + } + + return format; + } + + public static void clearThreadLocal() { + THREADLOCAL_FORMATS.remove(); + } + + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/HttpClientUtils.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/HttpClientUtils.java new file mode 100644 index 000000000..3c7769c2a --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/HttpClientUtils.java @@ -0,0 +1,149 @@ +/* + * ==================================================================== + * 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.client.utils; + +import java.io.Closeable; +import java.io.IOException; + +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.client.HttpClient; +import ch.boye.httpclientandroidlib.client.methods.CloseableHttpResponse; +import ch.boye.httpclientandroidlib.util.EntityUtils; + +/** + * Convenience methods for closing response and client objects. + * + * @since 4.2 + */ +public class HttpClientUtils { + + private HttpClientUtils() { + } + + /** + * Unconditionally close a response. + * <p> + * Example Code: + * + * <pre> + * HttpResponse httpResponse = null; + * try { + * httpResponse = httpClient.execute(httpGet); + * } catch (Exception e) { + * // error handling + * } finally { + * HttpClientUtils.closeQuietly(httpResponse); + * } + * </pre> + * + * @param response + * the HttpResponse to release resources, may be null or already + * closed. + * + * @since 4.2 + */ + public static void closeQuietly(final HttpResponse response) { + if (response != null) { + final HttpEntity entity = response.getEntity(); + if (entity != null) { + try { + EntityUtils.consume(entity); + } catch (final IOException ex) { + } + } + } + } + + /** + * Unconditionally close a response. + * <p> + * Example Code: + * + * <pre> + * HttpResponse httpResponse = null; + * try { + * httpResponse = httpClient.execute(httpGet); + * } catch (Exception e) { + * // error handling + * } finally { + * HttpClientUtils.closeQuietly(httpResponse); + * } + * </pre> + * + * @param response + * the HttpResponse to release resources, may be null or already + * closed. + * + * @since 4.3 + */ + public static void closeQuietly(final CloseableHttpResponse response) { + if (response != null) { + try { + try { + EntityUtils.consume(response.getEntity()); + } finally { + response.close(); + } + } catch (final IOException ignore) { + } + } + } + + /** + * Unconditionally close a httpClient. Shuts down the underlying connection + * manager and releases the resources. + * <p> + * Example Code: + * + * <pre> + * HttpClient httpClient = HttpClients.createDefault(); + * try { + * httpClient.execute(request); + * } catch (Exception e) { + * // error handling + * } finally { + * HttpClientUtils.closeQuietly(httpClient); + * } + * </pre> + * + * @param httpClient + * the HttpClient to close, may be null or already closed. + * @since 4.2 + */ + public static void closeQuietly(final HttpClient httpClient) { + if (httpClient != null) { + if (httpClient instanceof Closeable) { + try { + ((Closeable) httpClient).close(); + } catch (final IOException ignore) { + } + } + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/Idn.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/Idn.java new file mode 100644 index 000000000..a2b5bd036 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/Idn.java @@ -0,0 +1,42 @@ +/* + * ==================================================================== + * 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.client.utils; + +/** + * Abstraction of international domain name (IDN) conversion. + * + * @since 4.0 + */ +public interface Idn { + /** + * Converts a name from its punycode representation to Unicode. + * The name may be a single hostname or a dot-separated qualified domain name. + * @param punycode the Punycode representation + * @return the Unicode domain name + */ + String toUnicode(String punycode); +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/JdkIdn.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/JdkIdn.java new file mode 100644 index 000000000..53d46fe23 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/JdkIdn.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.client.utils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Uses the java.net.IDN class through reflection. + * + * @since 4.0 + */ +@Immutable +public class JdkIdn implements Idn { + private final Method toUnicode; + + /** + * + * @throws ClassNotFoundException if java.net.IDN is not available + */ + public JdkIdn() throws ClassNotFoundException { + final Class<?> clazz = Class.forName("java.net.IDN"); + try { + toUnicode = clazz.getMethod("toUnicode", String.class); + } catch (final SecurityException e) { + // doesn't happen + throw new IllegalStateException(e.getMessage(), e); + } catch (final NoSuchMethodException e) { + // doesn't happen + throw new IllegalStateException(e.getMessage(), e); + } + } + + public String toUnicode(final String punycode) { + try { + return (String) toUnicode.invoke(null, punycode); + } catch (final IllegalAccessException e) { + throw new IllegalStateException(e.getMessage(), e); + } catch (final InvocationTargetException e) { + final Throwable t = e.getCause(); + throw new RuntimeException(t.getMessage(), t); + } + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/Punycode.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/Punycode.java new file mode 100644 index 000000000..fa4872c41 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/Punycode.java @@ -0,0 +1,54 @@ +/* + * ==================================================================== + * 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.client.utils; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Facade that provides conversion between Unicode and Punycode domain names. + * It will use an appropriate implementation. + * + * @since 4.0 + */ +@Immutable +public class Punycode { + private static final Idn impl; + static { + Idn _impl; + try { + _impl = new JdkIdn(); + } catch (final Exception e) { + _impl = new Rfc3492Idn(); + } + impl = _impl; + } + + public static String toUnicode(final String punycode) { + return impl.toUnicode(punycode); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/Rfc3492Idn.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/Rfc3492Idn.java new file mode 100644 index 000000000..ccf980050 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/Rfc3492Idn.java @@ -0,0 +1,141 @@ +/* + * ==================================================================== + * 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.client.utils; + +import java.util.StringTokenizer; + +import ch.boye.httpclientandroidlib.annotation.Immutable; + +/** + * Implementation from pseudo code in RFC 3492. + * + * @since 4.0 + */ +@Immutable +public class Rfc3492Idn implements Idn { + private static final int base = 36; + private static final int tmin = 1; + private static final int tmax = 26; + private static final int skew = 38; + private static final int damp = 700; + private static final int initial_bias = 72; + private static final int initial_n = 128; + private static final char delimiter = '-'; + private static final String ACE_PREFIX = "xn--"; + + private int adapt(final int delta, final int numpoints, final boolean firsttime) { + int d = delta; + if (firsttime) { + d = d / damp; + } else { + d = d / 2; + } + d = d + (d / numpoints); + int k = 0; + while (d > ((base - tmin) * tmax) / 2) { + d = d / (base - tmin); + k = k + base; + } + return k + (((base - tmin + 1) * d) / (d + skew)); + } + + private int digit(final char c) { + if ((c >= 'A') && (c <= 'Z')) { + return (c - 'A'); + } + if ((c >= 'a') && (c <= 'z')) { + return (c - 'a'); + } + if ((c >= '0') && (c <= '9')) { + return (c - '0') + 26; + } + throw new IllegalArgumentException("illegal digit: "+ c); + } + + public String toUnicode(final String punycode) { + final StringBuilder unicode = new StringBuilder(punycode.length()); + final StringTokenizer tok = new StringTokenizer(punycode, "."); + while (tok.hasMoreTokens()) { + String t = tok.nextToken(); + if (unicode.length() > 0) { + unicode.append('.'); + } + if (t.startsWith(ACE_PREFIX)) { + t = decode(t.substring(4)); + } + unicode.append(t); + } + return unicode.toString(); + } + + protected String decode(final String s) { + String input = s; + int n = initial_n; + int i = 0; + int bias = initial_bias; + final StringBuilder output = new StringBuilder(input.length()); + final int lastdelim = input.lastIndexOf(delimiter); + if (lastdelim != -1) { + output.append(input.subSequence(0, lastdelim)); + input = input.substring(lastdelim + 1); + } + + while (input.length() > 0) { + final int oldi = i; + int w = 1; + for (int k = base;; k += base) { + if (input.length() == 0) { + break; + } + final char c = input.charAt(0); + input = input.substring(1); + final int digit = digit(c); + i = i + digit * w; // FIXME fail on overflow + final int t; + if (k <= bias + tmin) { + t = tmin; + } else if (k >= bias + tmax) { + t = tmax; + } else { + t = k - bias; + } + if (digit < t) { + break; + } + w = w * (base - t); // FIXME fail on overflow + } + bias = adapt(i - oldi, output.length() + 1, (oldi == 0)); + n = n + i / (output.length() + 1); // FIXME fail on overflow + i = i % (output.length() + 1); + // {if n is a basic code point then fail} + output.insert(i, (char) n); + i++; + } + return output.toString(); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/URIBuilder.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/URIBuilder.java new file mode 100644 index 000000000..e41958f7f --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/URIBuilder.java @@ -0,0 +1,490 @@ +/* + * ==================================================================== + * 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.client.utils; + +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import ch.boye.httpclientandroidlib.Consts; +import ch.boye.httpclientandroidlib.NameValuePair; +import ch.boye.httpclientandroidlib.annotation.NotThreadSafe; +import ch.boye.httpclientandroidlib.conn.util.InetAddressUtils; +import ch.boye.httpclientandroidlib.message.BasicNameValuePair; + +/** + * Builder for {@link URI} instances. + * + * @since 4.2 + */ +@NotThreadSafe +public class URIBuilder { + + private String scheme; + private String encodedSchemeSpecificPart; + private String encodedAuthority; + private String userInfo; + private String encodedUserInfo; + private String host; + private int port; + private String path; + private String encodedPath; + private String encodedQuery; + private List<NameValuePair> queryParams; + private String query; + private String fragment; + private String encodedFragment; + + /** + * Constructs an empty instance. + */ + public URIBuilder() { + super(); + this.port = -1; + } + + /** + * Construct an instance from the string which must be a valid URI. + * + * @param string a valid URI in string form + * @throws URISyntaxException if the input is not a valid URI + */ + public URIBuilder(final String string) throws URISyntaxException { + super(); + digestURI(new URI(string)); + } + + /** + * Construct an instance from the provided URI. + * @param uri + */ + public URIBuilder(final URI uri) { + super(); + digestURI(uri); + } + + private List <NameValuePair> parseQuery(final String query, final Charset charset) { + if (query != null && query.length() > 0) { + return URLEncodedUtils.parse(query, charset); + } + return null; + } + + /** + * Builds a {@link URI} instance. + */ + public URI build() throws URISyntaxException { + return new URI(buildString()); + } + + private String buildString() { + final StringBuilder sb = new StringBuilder(); + if (this.scheme != null) { + sb.append(this.scheme).append(':'); + } + if (this.encodedSchemeSpecificPart != null) { + sb.append(this.encodedSchemeSpecificPart); + } else { + if (this.encodedAuthority != null) { + sb.append("//").append(this.encodedAuthority); + } else if (this.host != null) { + sb.append("//"); + if (this.encodedUserInfo != null) { + sb.append(this.encodedUserInfo).append("@"); + } else if (this.userInfo != null) { + sb.append(encodeUserInfo(this.userInfo)).append("@"); + } + if (InetAddressUtils.isIPv6Address(this.host)) { + sb.append("[").append(this.host).append("]"); + } else { + sb.append(this.host); + } + if (this.port >= 0) { + sb.append(":").append(this.port); + } + } + if (this.encodedPath != null) { + sb.append(normalizePath(this.encodedPath)); + } else if (this.path != null) { + sb.append(encodePath(normalizePath(this.path))); + } + if (this.encodedQuery != null) { + sb.append("?").append(this.encodedQuery); + } else if (this.queryParams != null) { + sb.append("?").append(encodeUrlForm(this.queryParams)); + } else if (this.query != null) { + sb.append("?").append(encodeUric(this.query)); + } + } + if (this.encodedFragment != null) { + sb.append("#").append(this.encodedFragment); + } else if (this.fragment != null) { + sb.append("#").append(encodeUric(this.fragment)); + } + return sb.toString(); + } + + private void digestURI(final URI uri) { + this.scheme = uri.getScheme(); + this.encodedSchemeSpecificPart = uri.getRawSchemeSpecificPart(); + this.encodedAuthority = uri.getRawAuthority(); + this.host = uri.getHost(); + this.port = uri.getPort(); + this.encodedUserInfo = uri.getRawUserInfo(); + this.userInfo = uri.getUserInfo(); + this.encodedPath = uri.getRawPath(); + this.path = uri.getPath(); + this.encodedQuery = uri.getRawQuery(); + this.queryParams = parseQuery(uri.getRawQuery(), Consts.UTF_8); + this.encodedFragment = uri.getRawFragment(); + this.fragment = uri.getFragment(); + } + + private String encodeUserInfo(final String userInfo) { + return URLEncodedUtils.encUserInfo(userInfo, Consts.UTF_8); + } + + private String encodePath(final String path) { + return URLEncodedUtils.encPath(path, Consts.UTF_8); + } + + private String encodeUrlForm(final List<NameValuePair> params) { + return URLEncodedUtils.format(params, Consts.UTF_8); + } + + private String encodeUric(final String fragment) { + return URLEncodedUtils.encUric(fragment, Consts.UTF_8); + } + + /** + * Sets URI scheme. + */ + public URIBuilder setScheme(final String scheme) { + this.scheme = scheme; + return this; + } + + /** + * Sets URI user info. The value is expected to be unescaped and may contain non ASCII + * characters. + */ + public URIBuilder setUserInfo(final String userInfo) { + this.userInfo = userInfo; + this.encodedSchemeSpecificPart = null; + this.encodedAuthority = null; + this.encodedUserInfo = null; + return this; + } + + /** + * Sets URI user info as a combination of username and password. These values are expected to + * be unescaped and may contain non ASCII characters. + */ + public URIBuilder setUserInfo(final String username, final String password) { + return setUserInfo(username + ':' + password); + } + + /** + * Sets URI host. + */ + public URIBuilder setHost(final String host) { + this.host = host; + this.encodedSchemeSpecificPart = null; + this.encodedAuthority = null; + return this; + } + + /** + * Sets URI port. + */ + public URIBuilder setPort(final int port) { + this.port = port < 0 ? -1 : port; + this.encodedSchemeSpecificPart = null; + this.encodedAuthority = null; + return this; + } + + /** + * Sets URI path. The value is expected to be unescaped and may contain non ASCII characters. + */ + public URIBuilder setPath(final String path) { + this.path = path; + this.encodedSchemeSpecificPart = null; + this.encodedPath = null; + return this; + } + + /** + * Removes URI query. + */ + public URIBuilder removeQuery() { + this.queryParams = null; + this.query = null; + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + return this; + } + + /** + * Sets URI query. + * <p> + * The value is expected to be encoded form data. + * + * @deprecated (4.3) use {@link #setParameters(List)} or {@link #setParameters(NameValuePair...)} + * + * @see URLEncodedUtils#parse + */ + @Deprecated + public URIBuilder setQuery(final String query) { + this.queryParams = parseQuery(query, Consts.UTF_8); + this.query = null; + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + return this; + } + + /** + * Sets URI query parameters. The parameter name / values are expected to be unescaped + * and may contain non ASCII characters. + * <p/> + * Please note query parameters and custom query component are mutually exclusive. This method + * will remove custom query if present. + * + * @since 4.3 + */ + public URIBuilder setParameters(final List <NameValuePair> nvps) { + if (this.queryParams == null) { + this.queryParams = new ArrayList<NameValuePair>(); + } else { + this.queryParams.clear(); + } + this.queryParams.addAll(nvps); + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + this.query = null; + return this; + } + + /** + * Adds URI query parameters. The parameter name / values are expected to be unescaped + * and may contain non ASCII characters. + * <p/> + * Please note query parameters and custom query component are mutually exclusive. This method + * will remove custom query if present. + * + * @since 4.3 + */ + public URIBuilder addParameters(final List <NameValuePair> nvps) { + if (this.queryParams == null) { + this.queryParams = new ArrayList<NameValuePair>(); + } + this.queryParams.addAll(nvps); + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + this.query = null; + return this; + } + + /** + * Sets URI query parameters. The parameter name / values are expected to be unescaped + * and may contain non ASCII characters. + * <p/> + * Please note query parameters and custom query component are mutually exclusive. This method + * will remove custom query if present. + * + * @since 4.3 + */ + public URIBuilder setParameters(final NameValuePair... nvps) { + if (this.queryParams == null) { + this.queryParams = new ArrayList<NameValuePair>(); + } else { + this.queryParams.clear(); + } + for (final NameValuePair nvp: nvps) { + this.queryParams.add(nvp); + } + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + this.query = null; + return this; + } + + /** + * Adds parameter to URI query. The parameter name and value are expected to be unescaped + * and may contain non ASCII characters. + * <p/> + * Please note query parameters and custom query component are mutually exclusive. This method + * will remove custom query if present. + */ + public URIBuilder addParameter(final String param, final String value) { + if (this.queryParams == null) { + this.queryParams = new ArrayList<NameValuePair>(); + } + this.queryParams.add(new BasicNameValuePair(param, value)); + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + this.query = null; + return this; + } + + /** + * Sets parameter of URI query overriding existing value if set. The parameter name and value + * are expected to be unescaped and may contain non ASCII characters. + * <p/> + * Please note query parameters and custom query component are mutually exclusive. This method + * will remove custom query if present. + */ + public URIBuilder setParameter(final String param, final String value) { + if (this.queryParams == null) { + this.queryParams = new ArrayList<NameValuePair>(); + } + if (!this.queryParams.isEmpty()) { + for (final Iterator<NameValuePair> it = this.queryParams.iterator(); it.hasNext(); ) { + final NameValuePair nvp = it.next(); + if (nvp.getName().equals(param)) { + it.remove(); + } + } + } + this.queryParams.add(new BasicNameValuePair(param, value)); + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + this.query = null; + return this; + } + + /** + * Clears URI query parameters. + * + * @since 4.3 + */ + public URIBuilder clearParameters() { + this.queryParams = null; + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + return this; + } + + /** + * Sets custom URI query. The value is expected to be unescaped and may contain non ASCII + * characters. + * <p/> + * Please note query parameters and custom query component are mutually exclusive. This method + * will remove query parameters if present. + * + * @since 4.3 + */ + public URIBuilder setCustomQuery(final String query) { + this.query = query; + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + this.queryParams = null; + return this; + } + + /** + * Sets URI fragment. The value is expected to be unescaped and may contain non ASCII + * characters. + */ + public URIBuilder setFragment(final String fragment) { + this.fragment = fragment; + this.encodedFragment = null; + return this; + } + + /** + * @since 4.3 + */ + public boolean isAbsolute() { + return this.scheme != null; + } + + /** + * @since 4.3 + */ + public boolean isOpaque() { + return this.path == null; + } + + public String getScheme() { + return this.scheme; + } + + public String getUserInfo() { + return this.userInfo; + } + + public String getHost() { + return this.host; + } + + public int getPort() { + return this.port; + } + + public String getPath() { + return this.path; + } + + public List<NameValuePair> getQueryParams() { + if (this.queryParams != null) { + return new ArrayList<NameValuePair>(this.queryParams); + } else { + return new ArrayList<NameValuePair>(); + } + } + + public String getFragment() { + return this.fragment; + } + + @Override + public String toString() { + return buildString(); + } + + private static String normalizePath(final String path) { + String s = path; + if (s == null) { + return null; + } + int n = 0; + for (; n < s.length(); n++) { + if (s.charAt(n) != '/') { + break; + } + } + if (n > 1) { + s = s.substring(n - 1); + } + return s; + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/URIUtils.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/URIUtils.java new file mode 100644 index 000000000..73619c90a --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/URIUtils.java @@ -0,0 +1,428 @@ +/* + * ==================================================================== + * 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.client.utils; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Locale; +import java.util.Stack; + +import ch.boye.httpclientandroidlib.HttpHost; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.util.Args; +import ch.boye.httpclientandroidlib.util.TextUtils; + +/** + * A collection of utilities for {@link URI URIs}, to workaround + * bugs within the class or for ease-of-use features. + * + * @since 4.0 + */ +@Immutable +public class URIUtils { + + /** + * Constructs a {@link URI} using all the parameters. This should be + * used instead of + * {@link URI#URI(String, String, String, int, String, String, String)} + * or any of the other URI multi-argument URI constructors. + * + * @param scheme + * Scheme name + * @param host + * Host name + * @param port + * Port number + * @param path + * Path + * @param query + * Query + * @param fragment + * Fragment + * + * @throws URISyntaxException + * If both a scheme and a path are given but the path is + * relative, if the URI string constructed from the given + * components violates RFC 2396, or if the authority + * component of the string is present but cannot be parsed + * as a server-based authority + * + * @deprecated (4.2) use {@link URIBuilder}. + */ + @Deprecated + public static URI createURI( + final String scheme, + final String host, + final int port, + final String path, + final String query, + final String fragment) throws URISyntaxException { + final StringBuilder buffer = new StringBuilder(); + if (host != null) { + if (scheme != null) { + buffer.append(scheme); + buffer.append("://"); + } + buffer.append(host); + if (port > 0) { + buffer.append(':'); + buffer.append(port); + } + } + if (path == null || !path.startsWith("/")) { + buffer.append('/'); + } + if (path != null) { + buffer.append(path); + } + if (query != null) { + buffer.append('?'); + buffer.append(query); + } + if (fragment != null) { + buffer.append('#'); + buffer.append(fragment); + } + return new URI(buffer.toString()); + } + + /** + * A convenience method for creating a new {@link URI} whose scheme, host + * and port are taken from the target host, but whose path, query and + * fragment are taken from the existing URI. The fragment is only used if + * dropFragment is false. The path is set to "/" if not explicitly specified. + * + * @param uri + * Contains the path, query and fragment to use. + * @param target + * Contains the scheme, host and port to use. + * @param dropFragment + * True if the fragment should not be copied. + * + * @throws URISyntaxException + * If the resulting URI is invalid. + */ + public static URI rewriteURI( + final URI uri, + final HttpHost target, + final boolean dropFragment) throws URISyntaxException { + Args.notNull(uri, "URI"); + if (uri.isOpaque()) { + return uri; + } + final URIBuilder uribuilder = new URIBuilder(uri); + if (target != null) { + uribuilder.setScheme(target.getSchemeName()); + uribuilder.setHost(target.getHostName()); + uribuilder.setPort(target.getPort()); + } else { + uribuilder.setScheme(null); + uribuilder.setHost(null); + uribuilder.setPort(-1); + } + if (dropFragment) { + uribuilder.setFragment(null); + } + if (TextUtils.isEmpty(uribuilder.getPath())) { + uribuilder.setPath("/"); + } + return uribuilder.build(); + } + + /** + * A convenience method for + * {@link URIUtils#rewriteURI(URI, HttpHost, boolean)} that always keeps the + * fragment. + */ + public static URI rewriteURI( + final URI uri, + final HttpHost target) throws URISyntaxException { + return rewriteURI(uri, target, false); + } + + /** + * A convenience method that creates a new {@link URI} whose scheme, host, port, path, + * query are taken from the existing URI, dropping any fragment or user-information. + * The path is set to "/" if not explicitly specified. The existing URI is returned + * unmodified if it has no fragment or user-information and has a path. + * + * @param uri + * original URI. + * @throws URISyntaxException + * If the resulting URI is invalid. + */ + public static URI rewriteURI(final URI uri) throws URISyntaxException { + Args.notNull(uri, "URI"); + if (uri.isOpaque()) { + return uri; + } + final URIBuilder uribuilder = new URIBuilder(uri); + if (uribuilder.getUserInfo() != null) { + uribuilder.setUserInfo(null); + } + if (TextUtils.isEmpty(uribuilder.getPath())) { + uribuilder.setPath("/"); + } + if (uribuilder.getHost() != null) { + uribuilder.setHost(uribuilder.getHost().toLowerCase(Locale.ENGLISH)); + } + uribuilder.setFragment(null); + return uribuilder.build(); + } + + /** + * Resolves a URI reference against a base URI. Work-around for bug in + * java.net.URI (<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4708535>) + * + * @param baseURI the base URI + * @param reference the URI reference + * @return the resulting URI + */ + public static URI resolve(final URI baseURI, final String reference) { + return URIUtils.resolve(baseURI, URI.create(reference)); + } + + /** + * Resolves a URI reference against a base URI. Work-around for bugs in + * java.net.URI (e.g. <http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4708535>) + * + * @param baseURI the base URI + * @param reference the URI reference + * @return the resulting URI + */ + public static URI resolve(final URI baseURI, final URI reference){ + Args.notNull(baseURI, "Base URI"); + Args.notNull(reference, "Reference URI"); + URI ref = reference; + final String s = ref.toString(); + if (s.startsWith("?")) { + return resolveReferenceStartingWithQueryString(baseURI, ref); + } + final boolean emptyReference = s.length() == 0; + if (emptyReference) { + ref = URI.create("#"); + } + URI resolved = baseURI.resolve(ref); + if (emptyReference) { + final String resolvedString = resolved.toString(); + resolved = URI.create(resolvedString.substring(0, + resolvedString.indexOf('#'))); + } + return normalizeSyntax(resolved); + } + + /** + * Resolves a reference starting with a query string. + * + * @param baseURI the base URI + * @param reference the URI reference starting with a query string + * @return the resulting URI + */ + private static URI resolveReferenceStartingWithQueryString( + final URI baseURI, final URI reference) { + String baseUri = baseURI.toString(); + baseUri = baseUri.indexOf('?') > -1 ? + baseUri.substring(0, baseUri.indexOf('?')) : baseUri; + return URI.create(baseUri + reference.toString()); + } + + /** + * Removes dot segments according to RFC 3986, section 5.2.4 and + * Syntax-Based Normalization according to RFC 3986, section 6.2.2. + * + * @param uri the original URI + * @return the URI without dot segments + */ + private static URI normalizeSyntax(final URI uri) { + if (uri.isOpaque() || uri.getAuthority() == null) { + // opaque and file: URIs + return uri; + } + Args.check(uri.isAbsolute(), "Base URI must be absolute"); + final String path = uri.getPath() == null ? "" : uri.getPath(); + final String[] inputSegments = path.split("/"); + final Stack<String> outputSegments = new Stack<String>(); + for (final String inputSegment : inputSegments) { + if ((inputSegment.length() == 0) + || (".".equals(inputSegment))) { + // Do nothing + } else if ("..".equals(inputSegment)) { + if (!outputSegments.isEmpty()) { + outputSegments.pop(); + } + } else { + outputSegments.push(inputSegment); + } + } + final StringBuilder outputBuffer = new StringBuilder(); + for (final String outputSegment : outputSegments) { + outputBuffer.append('/').append(outputSegment); + } + if (path.lastIndexOf('/') == path.length() - 1) { + // path.endsWith("/") || path.equals("") + outputBuffer.append('/'); + } + try { + final String scheme = uri.getScheme().toLowerCase(Locale.ENGLISH); + final String auth = uri.getAuthority().toLowerCase(Locale.ENGLISH); + final URI ref = new URI(scheme, auth, outputBuffer.toString(), + null, null); + if (uri.getQuery() == null && uri.getFragment() == null) { + return ref; + } + final StringBuilder normalized = new StringBuilder( + ref.toASCIIString()); + if (uri.getQuery() != null) { + // query string passed through unchanged + normalized.append('?').append(uri.getRawQuery()); + } + if (uri.getFragment() != null) { + // fragment passed through unchanged + normalized.append('#').append(uri.getRawFragment()); + } + return URI.create(normalized.toString()); + } catch (final URISyntaxException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * Extracts target host from the given {@link URI}. + * + * @param uri + * @return the target host if the URI is absolute or <code>null</null> if the URI is + * relative or does not contain a valid host name. + * + * @since 4.1 + */ + public static HttpHost extractHost(final URI uri) { + if (uri == null) { + return null; + } + HttpHost target = null; + if (uri.isAbsolute()) { + int port = uri.getPort(); // may be overridden later + String host = uri.getHost(); + if (host == null) { // normal parse failed; let's do it ourselves + // authority does not seem to care about the valid character-set for host names + host = uri.getAuthority(); + if (host != null) { + // Strip off any leading user credentials + final int at = host.indexOf('@'); + if (at >= 0) { + if (host.length() > at+1 ) { + host = host.substring(at+1); + } else { + host = null; // @ on its own + } + } + // Extract the port suffix, if present + if (host != null) { + final int colon = host.indexOf(':'); + if (colon >= 0) { + final int pos = colon + 1; + int len = 0; + for (int i = pos; i < host.length(); i++) { + if (Character.isDigit(host.charAt(i))) { + len++; + } else { + break; + } + } + if (len > 0) { + try { + port = Integer.parseInt(host.substring(pos, pos + len)); + } catch (final NumberFormatException ex) { + } + } + host = host.substring(0, colon); + } + } + } + } + final String scheme = uri.getScheme(); + if (!TextUtils.isBlank(host)) { + target = new HttpHost(host, port, scheme); + } + } + return target; + } + + /** + * Derives the interpreted (absolute) URI that was used to generate the last + * request. This is done by extracting the request-uri and target origin for + * the last request and scanning all the redirect locations for the last + * fragment identifier, then combining the result into a {@link URI}. + * + * @param originalURI + * original request before any redirects + * @param target + * if the last URI is relative, it is resolved against this target, + * or <code>null</code> if not available. + * @param redirects + * collection of redirect locations since the original request + * or <code>null</code> if not available. + * @return interpreted (absolute) URI + */ + public static URI resolve( + final URI originalURI, + final HttpHost target, + final List<URI> redirects) throws URISyntaxException { + Args.notNull(originalURI, "Request URI"); + final URIBuilder uribuilder; + if (redirects == null || redirects.isEmpty()) { + uribuilder = new URIBuilder(originalURI); + } else { + uribuilder = new URIBuilder(redirects.get(redirects.size() - 1)); + String frag = uribuilder.getFragment(); + // read interpreted fragment identifier from redirect locations + for (int i = redirects.size() - 1; frag == null && i >= 0; i--) { + frag = redirects.get(i).getFragment(); + } + uribuilder.setFragment(frag); + } + // read interpreted fragment identifier from original request + if (uribuilder.getFragment() == null) { + uribuilder.setFragment(originalURI.getFragment()); + } + // last target origin + if (target != null && !uribuilder.isAbsolute()) { + uribuilder.setScheme(target.getSchemeName()); + uribuilder.setHost(target.getHostName()); + uribuilder.setPort(target.getPort()); + } + return uribuilder.build(); + } + + /** + * This class should not be instantiated. + */ + private URIUtils() { + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/URLEncodedUtils.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/URLEncodedUtils.java new file mode 100644 index 000000000..97465401f --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/URLEncodedUtils.java @@ -0,0 +1,628 @@ +/* + * ==================================================================== + * 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.client.utils; + +import java.io.IOException; +import java.net.URI; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Collections; +import java.util.List; +import java.util.Scanner; + +import ch.boye.httpclientandroidlib.Consts; +import ch.boye.httpclientandroidlib.Header; +import ch.boye.httpclientandroidlib.HeaderElement; +import ch.boye.httpclientandroidlib.HttpEntity; +import ch.boye.httpclientandroidlib.NameValuePair; +import ch.boye.httpclientandroidlib.annotation.Immutable; +import ch.boye.httpclientandroidlib.entity.ContentType; +import ch.boye.httpclientandroidlib.message.BasicHeaderValueParser; +import ch.boye.httpclientandroidlib.message.BasicNameValuePair; +import ch.boye.httpclientandroidlib.message.ParserCursor; +import ch.boye.httpclientandroidlib.protocol.HTTP; +import ch.boye.httpclientandroidlib.util.CharArrayBuffer; +import ch.boye.httpclientandroidlib.util.EntityUtils; + +/** + * A collection of utilities for encoding URLs. + * + * @since 4.0 + */ +@Immutable +public class URLEncodedUtils { + + /** + * The default HTML form content type. + */ + public static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; + + private static final char QP_SEP_A = '&'; + private static final char QP_SEP_S = ';'; + private static final String NAME_VALUE_SEPARATOR = "="; + + /** + * Returns a list of {@link NameValuePair NameValuePairs} as built from the URI's query portion. For example, a URI + * of http://example.org/path/to/file?a=1&b=2&c=3 would return a list of three NameValuePairs, one for a=1, one for + * b=2, and one for c=3. By convention, {@code '&'} and {@code ';'} are accepted as parameter separators. + * <p> + * This is typically useful while parsing an HTTP PUT. + * + * This API is currently only used for testing. + * + * @param uri + * URI to parse + * @param charset + * Charset name to use while parsing the query + * @return a list of {@link NameValuePair} as built from the URI's query portion. + */ + public static List <NameValuePair> parse(final URI uri, final String charset) { + final String query = uri.getRawQuery(); + if (query != null && query.length() > 0) { + final List<NameValuePair> result = new ArrayList<NameValuePair>(); + final Scanner scanner = new Scanner(query); + parse(result, scanner, QP_SEP_PATTERN, charset); + return result; + } + return Collections.emptyList(); + } + + /** + * Returns a list of {@link NameValuePair NameValuePairs} as parsed from an {@link HttpEntity}. The encoding is + * taken from the entity's Content-Encoding header. + * <p> + * This is typically used while parsing an HTTP POST. + * + * @param entity + * The entity to parse + * @return a list of {@link NameValuePair} as built from the URI's query portion. + * @throws IOException + * If there was an exception getting the entity's data. + */ + public static List <NameValuePair> parse( + final HttpEntity entity) throws IOException { + final ContentType contentType = ContentType.get(entity); + if (contentType != null && contentType.getMimeType().equalsIgnoreCase(CONTENT_TYPE)) { + final String content = EntityUtils.toString(entity, Consts.ASCII); + if (content != null && content.length() > 0) { + Charset charset = contentType.getCharset(); + if (charset == null) { + charset = HTTP.DEF_CONTENT_CHARSET; + } + return parse(content, charset, QP_SEPS); + } + } + return Collections.emptyList(); + } + + /** + * Returns true if the entity's Content-Type header is + * <code>application/x-www-form-urlencoded</code>. + */ + public static boolean isEncoded(final HttpEntity entity) { + final Header h = entity.getContentType(); + if (h != null) { + final HeaderElement[] elems = h.getElements(); + if (elems.length > 0) { + final String contentType = elems[0].getName(); + return contentType.equalsIgnoreCase(CONTENT_TYPE); + } + } + return false; + } + + /** + * Adds all parameters within the Scanner to the list of <code>parameters</code>, as encoded by + * <code>encoding</code>. For example, a scanner containing the string <code>a=1&b=2&c=3</code> would add the + * {@link NameValuePair NameValuePairs} a=1, b=2, and c=3 to the list of parameters. By convention, {@code '&'} and + * {@code ';'} are accepted as parameter separators. + * + * @param parameters + * List to add parameters to. + * @param scanner + * Input that contains the parameters to parse. + * @param charset + * Encoding to use when decoding the parameters. + */ + public static void parse( + final List <NameValuePair> parameters, + final Scanner scanner, + final String charset) { + parse(parameters, scanner, QP_SEP_PATTERN, charset); + } + + /** + * Adds all parameters within the Scanner to the list of + * <code>parameters</code>, as encoded by <code>encoding</code>. For + * example, a scanner containing the string <code>a=1&b=2&c=3</code> would + * add the {@link NameValuePair NameValuePairs} a=1, b=2, and c=3 to the + * list of parameters. + * + * @param parameters + * List to add parameters to. + * @param scanner + * Input that contains the parameters to parse. + * @param parameterSepartorPattern + * The Pattern string for parameter separators, by convention {@code "[&;]"} + * @param charset + * Encoding to use when decoding the parameters. + */ + public static void parse( + final List <NameValuePair> parameters, + final Scanner scanner, + final String parameterSepartorPattern, + final String charset) { + scanner.useDelimiter(parameterSepartorPattern); + while (scanner.hasNext()) { + String name = null; + String value = null; + final String token = scanner.next(); + final int i = token.indexOf(NAME_VALUE_SEPARATOR); + if (i != -1) { + name = decodeFormFields(token.substring(0, i).trim(), charset); + value = decodeFormFields(token.substring(i + 1).trim(), charset); + } else { + name = decodeFormFields(token.trim(), charset); + } + parameters.add(new BasicNameValuePair(name, value)); + } + } + + /** + * Query parameter separators. + */ + private static final char[] QP_SEPS = new char[] { QP_SEP_A, QP_SEP_S }; + + /** + * Query parameter separator pattern. + */ + private static final String QP_SEP_PATTERN = "[" + new String(QP_SEPS) + "]"; + + /** + * Returns a list of {@link NameValuePair NameValuePairs} as parsed from the given string using the given character + * encoding. By convention, {@code '&'} and {@code ';'} are accepted as parameter separators. + * + * @param s + * text to parse. + * @param charset + * Encoding to use when decoding the parameters. + * @return a list of {@link NameValuePair} as built from the URI's query portion. + * + * @since 4.2 + */ + public static List<NameValuePair> parse(final String s, final Charset charset) { + return parse(s, charset, QP_SEPS); + } + + /** + * Returns a list of {@link NameValuePair NameValuePairs} as parsed from the given string using the given character + * encoding. + * + * @param s + * text to parse. + * @param charset + * Encoding to use when decoding the parameters. + * @param parameterSeparator + * The characters used to separate parameters, by convention, {@code '&'} and {@code ';'}. + * @return a list of {@link NameValuePair} as built from the URI's query portion. + * + * @since 4.3 + */ + public static List<NameValuePair> parse(final String s, final Charset charset, final char... parameterSeparator) { + if (s == null) { + return Collections.emptyList(); + } + final BasicHeaderValueParser parser = BasicHeaderValueParser.INSTANCE; + final CharArrayBuffer buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + final ParserCursor cursor = new ParserCursor(0, buffer.length()); + final List<NameValuePair> list = new ArrayList<NameValuePair>(); + while (!cursor.atEnd()) { + final NameValuePair nvp = parser.parseNameValuePair(buffer, cursor, parameterSeparator); + if (nvp.getName().length() > 0) { + list.add(new BasicNameValuePair( + decodeFormFields(nvp.getName(), charset), + decodeFormFields(nvp.getValue(), charset))); + } + } + return list; + } + + /** + * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded} + * list of parameters in an HTTP PUT or HTTP POST. + * + * @param parameters The parameters to include. + * @param charset The encoding to use. + * @return An {@code application/x-www-form-urlencoded} string + */ + public static String format( + final List <? extends NameValuePair> parameters, + final String charset) { + return format(parameters, QP_SEP_A, charset); + } + + /** + * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded} + * list of parameters in an HTTP PUT or HTTP POST. + * + * @param parameters The parameters to include. + * @param parameterSeparator The parameter separator, by convention, {@code '&'} or {@code ';'}. + * @param charset The encoding to use. + * @return An {@code application/x-www-form-urlencoded} string + * + * @since 4.3 + */ + public static String format( + final List <? extends NameValuePair> parameters, + final char parameterSeparator, + final String charset) { + final StringBuilder result = new StringBuilder(); + for (final NameValuePair parameter : parameters) { + final String encodedName = encodeFormFields(parameter.getName(), charset); + final String encodedValue = encodeFormFields(parameter.getValue(), charset); + if (result.length() > 0) { + result.append(parameterSeparator); + } + result.append(encodedName); + if (encodedValue != null) { + result.append(NAME_VALUE_SEPARATOR); + result.append(encodedValue); + } + } + return result.toString(); + } + + /** + * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded} + * list of parameters in an HTTP PUT or HTTP POST. + * + * @param parameters The parameters to include. + * @param charset The encoding to use. + * @return An {@code application/x-www-form-urlencoded} string + * + * @since 4.2 + */ + public static String format( + final Iterable<? extends NameValuePair> parameters, + final Charset charset) { + return format(parameters, QP_SEP_A, charset); + } + + /** + * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded} + * list of parameters in an HTTP PUT or HTTP POST. + * + * @param parameters The parameters to include. + * @param parameterSeparator The parameter separator, by convention, {@code '&'} or {@code ';'}. + * @param charset The encoding to use. + * @return An {@code application/x-www-form-urlencoded} string + * + * @since 4.3 + */ + public static String format( + final Iterable<? extends NameValuePair> parameters, + final char parameterSeparator, + final Charset charset) { + final StringBuilder result = new StringBuilder(); + for (final NameValuePair parameter : parameters) { + final String encodedName = encodeFormFields(parameter.getName(), charset); + final String encodedValue = encodeFormFields(parameter.getValue(), charset); + if (result.length() > 0) { + result.append(parameterSeparator); + } + result.append(encodedName); + if (encodedValue != null) { + result.append(NAME_VALUE_SEPARATOR); + result.append(encodedValue); + } + } + return result.toString(); + } + + /** + * Unreserved characters, i.e. alphanumeric, plus: {@code _ - ! . ~ ' ( ) *} + * <p> + * This list is the same as the {@code unreserved} list in + * <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a> + */ + private static final BitSet UNRESERVED = new BitSet(256); + /** + * Punctuation characters: , ; : $ & + = + * <p> + * These are the additional characters allowed by userinfo. + */ + private static final BitSet PUNCT = new BitSet(256); + /** Characters which are safe to use in userinfo, + * i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation */ + private static final BitSet USERINFO = new BitSet(256); + /** Characters which are safe to use in a path, + * i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation plus / @ */ + private static final BitSet PATHSAFE = new BitSet(256); + /** Characters which are safe to use in a query or a fragment, + * i.e. {@link #RESERVED} plus {@link #UNRESERVED} */ + private static final BitSet URIC = new BitSet(256); + + /** + * Reserved characters, i.e. {@code ;/?:@&=+$,[]} + * <p> + * This list is the same as the {@code reserved} list in + * <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a> + * as augmented by + * <a href="http://www.ietf.org/rfc/rfc2732.txt">RFC 2732</a> + */ + private static final BitSet RESERVED = new BitSet(256); + + + /** + * Safe characters for x-www-form-urlencoded data, as per java.net.URLEncoder and browser behaviour, + * i.e. alphanumeric plus {@code "-", "_", ".", "*"} + */ + private static final BitSet URLENCODER = new BitSet(256); + + static { + // unreserved chars + // alpha characters + for (int i = 'a'; i <= 'z'; i++) { + UNRESERVED.set(i); + } + for (int i = 'A'; i <= 'Z'; i++) { + UNRESERVED.set(i); + } + // numeric characters + for (int i = '0'; i <= '9'; i++) { + UNRESERVED.set(i); + } + UNRESERVED.set('_'); // these are the charactes of the "mark" list + UNRESERVED.set('-'); + UNRESERVED.set('.'); + UNRESERVED.set('*'); + URLENCODER.or(UNRESERVED); // skip remaining unreserved characters + UNRESERVED.set('!'); + UNRESERVED.set('~'); + UNRESERVED.set('\''); + UNRESERVED.set('('); + UNRESERVED.set(')'); + // punct chars + PUNCT.set(','); + PUNCT.set(';'); + PUNCT.set(':'); + PUNCT.set('$'); + PUNCT.set('&'); + PUNCT.set('+'); + PUNCT.set('='); + // Safe for userinfo + USERINFO.or(UNRESERVED); + USERINFO.or(PUNCT); + + // URL path safe + PATHSAFE.or(UNRESERVED); + PATHSAFE.set('/'); // segment separator + PATHSAFE.set(';'); // param separator + PATHSAFE.set(':'); // rest as per list in 2396, i.e. : @ & = + $ , + PATHSAFE.set('@'); + PATHSAFE.set('&'); + PATHSAFE.set('='); + PATHSAFE.set('+'); + PATHSAFE.set('$'); + PATHSAFE.set(','); + + RESERVED.set(';'); + RESERVED.set('/'); + RESERVED.set('?'); + RESERVED.set(':'); + RESERVED.set('@'); + RESERVED.set('&'); + RESERVED.set('='); + RESERVED.set('+'); + RESERVED.set('$'); + RESERVED.set(','); + RESERVED.set('['); // added by RFC 2732 + RESERVED.set(']'); // added by RFC 2732 + + URIC.or(RESERVED); + URIC.or(UNRESERVED); + } + + private static final int RADIX = 16; + + private static String urlEncode( + final String content, + final Charset charset, + final BitSet safechars, + final boolean blankAsPlus) { + if (content == null) { + return null; + } + final StringBuilder buf = new StringBuilder(); + final ByteBuffer bb = charset.encode(content); + while (bb.hasRemaining()) { + final int b = bb.get() & 0xff; + if (safechars.get(b)) { + buf.append((char) b); + } else if (blankAsPlus && b == ' ') { + buf.append('+'); + } else { + buf.append("%"); + final char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, RADIX)); + final char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, RADIX)); + buf.append(hex1); + buf.append(hex2); + } + } + return buf.toString(); + } + + /** + * Decode/unescape a portion of a URL, to use with the query part ensure {@code plusAsBlank} is true. + * + * @param content the portion to decode + * @param charset the charset to use + * @param plusAsBlank if {@code true}, then convert '+' to space (e.g. for www-url-form-encoded content), otherwise leave as is. + * @return encoded string + */ + private static String urlDecode( + final String content, + final Charset charset, + final boolean plusAsBlank) { + if (content == null) { + return null; + } + final ByteBuffer bb = ByteBuffer.allocate(content.length()); + final CharBuffer cb = CharBuffer.wrap(content); + while (cb.hasRemaining()) { + final char c = cb.get(); + if (c == '%' && cb.remaining() >= 2) { + final char uc = cb.get(); + final char lc = cb.get(); + final int u = Character.digit(uc, 16); + final int l = Character.digit(lc, 16); + if (u != -1 && l != -1) { + bb.put((byte) ((u << 4) + l)); + } else { + bb.put((byte) '%'); + bb.put((byte) uc); + bb.put((byte) lc); + } + } else if (plusAsBlank && c == '+') { + bb.put((byte) ' '); + } else { + bb.put((byte) c); + } + } + bb.flip(); + return charset.decode(bb).toString(); + } + + /** + * Decode/unescape www-url-form-encoded content. + * + * @param content the content to decode, will decode '+' as space + * @param charset the charset to use + * @return encoded string + */ + private static String decodeFormFields (final String content, final String charset) { + if (content == null) { + return null; + } + return urlDecode(content, charset != null ? Charset.forName(charset) : Consts.UTF_8, true); + } + + /** + * Decode/unescape www-url-form-encoded content. + * + * @param content the content to decode, will decode '+' as space + * @param charset the charset to use + * @return encoded string + */ + private static String decodeFormFields (final String content, final Charset charset) { + if (content == null) { + return null; + } + return urlDecode(content, charset != null ? charset : Consts.UTF_8, true); + } + + /** + * Encode/escape www-url-form-encoded content. + * <p> + * Uses the {@link #URLENCODER} set of characters, rather than + * the {@link #UNRSERVED} set; this is for compatibilty with previous + * releases, URLEncoder.encode() and most browsers. + * + * @param content the content to encode, will convert space to '+' + * @param charset the charset to use + * @return encoded string + */ + private static String encodeFormFields(final String content, final String charset) { + if (content == null) { + return null; + } + return urlEncode(content, charset != null ? Charset.forName(charset) : Consts.UTF_8, URLENCODER, true); + } + + /** + * Encode/escape www-url-form-encoded content. + * <p> + * Uses the {@link #URLENCODER} set of characters, rather than + * the {@link #UNRSERVED} set; this is for compatibilty with previous + * releases, URLEncoder.encode() and most browsers. + * + * @param content the content to encode, will convert space to '+' + * @param charset the charset to use + * @return encoded string + */ + private static String encodeFormFields (final String content, final Charset charset) { + if (content == null) { + return null; + } + return urlEncode(content, charset != null ? charset : Consts.UTF_8, URLENCODER, true); + } + + /** + * Encode a String using the {@link #USERINFO} set of characters. + * <p> + * Used by URIBuilder to encode the userinfo segment. + * + * @param content the string to encode, does not convert space to '+' + * @param charset the charset to use + * @return the encoded string + */ + static String encUserInfo(final String content, final Charset charset) { + return urlEncode(content, charset, USERINFO, false); + } + + /** + * Encode a String using the {@link #URIC} set of characters. + * <p> + * Used by URIBuilder to encode the query and fragment segments. + * + * @param content the string to encode, does not convert space to '+' + * @param charset the charset to use + * @return the encoded string + */ + static String encUric(final String content, final Charset charset) { + return urlEncode(content, charset, URIC, false); + } + + /** + * Encode a String using the {@link #PATHSAFE} set of characters. + * <p> + * Used by URIBuilder to encode path segments. + * + * @param content the string to encode, does not convert space to '+' + * @param charset the charset to use + * @return the encoded string + */ + static String encPath(final String content, final Charset charset) { + return urlEncode(content, charset, PATHSAFE, false); + } + +} diff --git a/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/package-info.java b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/package-info.java new file mode 100644 index 000000000..7f5671654 --- /dev/null +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/package-info.java @@ -0,0 +1,31 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +/** + * Client utility classes. + */ +package ch.boye.httpclientandroidlib.client.utils; |