pt 1 in reviving the android build (copied from pm 28a1, wish me luck)

This commit is contained in:
wuggy 2026-04-08 15:43:25 -07:00
commit d7788a6d6d
4249 changed files with 468189 additions and 0 deletions

View file

@ -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";
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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");
}
}
}

View file

@ -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);
}
}

View file

@ -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");
}
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}
}

View file

@ -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);
}
}
}
}

View file

@ -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);
}
}
}
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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");
}
}
}
}
}

View file

@ -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();
}
}

View file

@ -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;