/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/HttpMethodDirector.java,v 1.34 2005/01/14 19:40:39 olegk Exp $
* $Revision: 486658 $
* $Date: 2006-12-13 15:05:50 +0100 (Wed, 13 Dec 2006) $
*
* ====================================================================
*
* 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 org.apache.commons.httpclient;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.commons.httpclient.auth.AuthChallengeException;
import org.apache.commons.httpclient.auth.AuthChallengeParser;
import org.apache.commons.httpclient.auth.AuthChallengeProcessor;
import org.apache.commons.httpclient.auth.AuthScheme;
import org.apache.commons.httpclient.auth.AuthState;
import org.apache.commons.httpclient.auth.AuthenticationException;
import org.apache.commons.httpclient.auth.CredentialsProvider;
import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.auth.MalformedChallengeException;
import org.apache.commons.httpclient.params.HostParams;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.params.HttpParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Handles the process of executing a method including authentication, redirection and retries.
*
* @since 3.0
*/
class HttpMethodDirector {
/** The www authenticate challange header. */
public static final String WWW_AUTH_CHALLENGE = "WWW-Authenticate";
/** The www authenticate response header. */
public static final String WWW_AUTH_RESP = "Authorization";
/** The proxy authenticate challange header. */
public static final String PROXY_AUTH_CHALLENGE = "Proxy-Authenticate";
/** The proxy authenticate response header. */
public static final String PROXY_AUTH_RESP = "Proxy-Authorization";
private static final Log LOG = LogFactory.getLog(HttpMethodDirector.class);
private ConnectMethod connectMethod;
private HttpState state;
private HostConfiguration hostConfiguration;
private HttpConnectionManager connectionManager;
private HttpClientParams params;
private HttpConnection conn;
/** A flag to indicate if the connection should be released after the method is executed. */
private boolean releaseConnection = false;
/** Authentication processor */
private AuthChallengeProcessor authProcessor = null;
private Set redirectLocations = null;
public HttpMethodDirector(
final HttpConnectionManager connectionManager,
final HostConfiguration hostConfiguration,
final HttpClientParams params,
final HttpState state
) {
super();
this.connectionManager = connectionManager;
this.hostConfiguration = hostConfiguration;
this.params = params;
this.state = state;
this.authProcessor = new AuthChallengeProcessor(this.params);
}
/**
* Executes the method associated with this method director.
*
* @throws IOException
* @throws HttpException
*/
public void executeMethod(final HttpMethod method) throws IOException, HttpException {
if (method == null) {
throw new IllegalArgumentException("Method may not be null");
}
// Link all parameter collections to form the hierarchy:
// Global -> HttpClient -> HostConfiguration -> HttpMethod
this.hostConfiguration.getParams().setDefaults(this.params);
method.getParams().setDefaults(this.hostConfiguration.getParams());
// Generate default request headers
Collection defaults = (Collection)this.hostConfiguration.getParams().
getParameter(HostParams.DEFAULT_HEADERS);
if (defaults != null) {
Iterator i = defaults.iterator();
while (i.hasNext()) {
method.addRequestHeader((Header)i.next());
}
}
try {
int maxRedirects = this.params.getIntParameter(HttpClientParams.MAX_REDIRECTS, 100);
for (int redirectCount = 0;;) {
// make sure the connection we have is appropriate
if (this.conn != null && !hostConfiguration.hostEquals(this.conn)) {
this.conn.setLocked(false);
this.conn.releaseConnection();
this.conn = null;
}
// get a connection, if we need one
if (this.conn == null) {
this.conn = connectionManager.getConnectionWithTimeout(
hostConfiguration,
this.params.getConnectionManagerTimeout()
);
this.conn.setLocked(true);
if (this.params.isAuthenticationPreemptive()
|| this.state.isAuthenticationPreemptive())
{
LOG.debug("Preemptively sending default basic credentials");
method.getHostAuthState().setPreemptive();
method.getHostAuthState().setAuthAttempted(true);
if (this.conn.isProxied() && !this.conn.isSecure()) {
method.getProxyAuthState().setPreemptive();
method.getProxyAuthState().setAuthAttempted(true);
}
}
}
authenticate(method);
executeWithRetry(method);
if (this.connectMethod != null) {
fakeResponse(method);
break;
}
boolean retry = false;
if (isRedirectNeeded(method)) {
if (processRedirectResponse(method)) {
retry = true;
++redirectCount;
if (redirectCount >= maxRedirects) {
LOG.error("Narrowly avoided an infinite loop in execute");
throw new RedirectException("Maximum redirects ("
+ maxRedirects + ") exceeded");
}
if (LOG.isDebugEnabled()) {
LOG.debug("Execute redirect " + redirectCount + " of " + maxRedirects);
}
}
}
if (isAuthenticationNeeded(method)) {
if (processAuthenticationResponse(method)) {
LOG.debug("Retry authentication");
retry = true;
}
}
if (!retry) {
break;
}
// retry - close previous stream. Caution - this causes
// responseBodyConsumed to be called, which may also close the
// connection.
if (method.getResponseBodyAsStream() != null) {
method.getResponseBodyAsStream().close();
}
} //end of retry loop
} finally {
if (this.conn != null) {
this.conn.setLocked(false);
}
// If the response has been fully processed, return the connection
// to the pool. Use this flag, rather than other tests (like
// responseStream == null), as subclasses, might reset the stream,
// for example, reading the entire response into a file and then
// setting the file as the stream.
if (
(releaseConnection || method.getResponseBodyAsStream() == null)
&& this.conn != null
) {
this.conn.releaseConnection();
}
}
}
private void authenticate(final HttpMethod method) {
try {
if (this.conn.isProxied() && !this.conn.isSecure()) {
authenticateProxy(method);
}
authenticateHost(method);
} catch (AuthenticationException e) {
LOG.error(e.getMessage(), e);
}
}
private boolean cleanAuthHeaders(final HttpMethod method, final String name) {
Header[] authheaders = method.getRequestHeaders(name);
boolean clean = true;
for (int i = 0; i < authheaders.length; i++) {
Header authheader = authheaders[i];
if (authheader.isAutogenerated()) {
method.removeRequestHeader(authheader);
} else {
clean = false;
}
}
return clean;
}
private void authenticateHost(final HttpMethod method) throws AuthenticationException {
// Clean up existing authentication headers
if (!cleanAuthHeaders(method, WWW_AUTH_RESP)) {
// User defined authentication header(s) present
return;
}
AuthState authstate = method.getHostAuthState();
AuthScheme authscheme = authstate.getAuthScheme();
if (authscheme == null) {
return;
}
if (authstate.isAuthRequested() || !authscheme.isConnectionBased()) {
String host = method.getParams().getVirtualHost();
if (host == null) {
host = conn.getHost();
}
int port = conn.getPort();
AuthScope authscope = new AuthScope(
host, port,
authscheme.getRealm(),
authscheme.getSchemeName());
if (LOG.isDebugEnabled()) {
LOG.debug("Authenticating with " + authscope);
}
Credentials credentials = this.state.getCredentials(authscope);
if (credentials != null) {
String authstring = authscheme.authenticate(credentials, method);
if (authstring != null) {
method.addRequestHeader(new Header(WWW_AUTH_RESP, authstring, true));
}
} else {
if (LOG.isWarnEnabled()) {
LOG.warn("Required credentials not available for " + authscope);
if (method.getHostAuthState().isPreemptive()) {
LOG.warn("Preemptive authentication requested but no default " +
"credentials available");
}
}
}
}
}
private void authenticateProxy(final HttpMethod method) throws AuthenticationException {
// Clean up existing authentication headers
if (!cleanAuthHeaders(method, PROXY_AUTH_RESP)) {
// User defined authentication header(s) present
return;
}
AuthState authstate = method.getProxyAuthState();
AuthScheme authscheme = authstate.getAuthScheme();
if (authscheme == null) {
return;
}
if (authstate.isAuthRequested() || !authscheme.isConnectionBased()) {
AuthScope authscope = new AuthScope(
conn.getProxyHost(), conn.getProxyPort(),
authscheme.getRealm(),
authscheme.getSchemeName());
if (LOG.isDebugEnabled()) {
LOG.debug("Authenticating with " + authscope);
}
Credentials credentials = this.state.getProxyCredentials(authscope);
if (credentials != null) {
String authstring = authscheme.authenticate(credentials, method);
if (authstring != null) {
method.addRequestHeader(new Header(PROXY_AUTH_RESP, authstring, true));
}
} else {
if (LOG.isWarnEnabled()) {
LOG.warn("Required proxy credentials not available for " + authscope);
if (method.getProxyAuthState().isPreemptive()) {
LOG.warn("Preemptive authentication requested but no default " +
"proxy credentials available");
}
}
}
}
}
/**
* Applies connection parameters specified for a given method
*
* @param method HTTP method
*
* @throws IOException if an I/O occurs setting connection parameters
*/
private void applyConnectionParams(final HttpMethod method) throws IOException {
int timeout = 0;
// see if a timeout is given for this method
Object param = method.getParams().getParameter(HttpMethodParams.SO_TIMEOUT);
if (param == null) {
// if not, use the default value
param = this.conn.getParams().getParameter(HttpConnectionParams.SO_TIMEOUT);
}
if (param != null) {
timeout = ((Integer)param).intValue();
}
this.conn.setSocketTimeout(timeout);
}
/**
* Executes a method with the current hostConfiguration.
*
* @throws IOException if an I/O (transport) error occurs. Some transport exceptions
* can be recovered from.
* @throws HttpException if a protocol exception occurs. Usually protocol exceptions
* cannot be recovered from.
*/
private void executeWithRetry(final HttpMethod method)
throws IOException, HttpException {
/** How many times did this transparently handle a recoverable exception? */
int execCount = 0;
// loop until the method is successfully processed, the retryHandler
// returns false or a non-recoverable exception is thrown
try {
while (true) {
execCount++;
try {
if (LOG.isTraceEnabled()) {
LOG.trace("Attempt number " + execCount + " to process request");
}
if (this.conn.getParams().isStaleCheckingEnabled()) {
this.conn.closeIfStale();
}
if (!this.conn.isOpen()) {
// this connection must be opened before it can be used
// This has nothing to do with opening a secure tunnel
this.conn.open();
if (this.conn.isProxied() && this.conn.isSecure()
&& !(method instanceof ConnectMethod)) {
// we need to create a secure tunnel before we can execute the real method
if (!executeConnect()) {
// abort, the connect method failed
return;
}
}
}
applyConnectionParams(method);
method.execute(state, this.conn);
break;
} catch (HttpException e) {
// filter out protocol exceptions which cannot be recovered from
throw e;
} catch (IOException e) {
LOG.debug("Closing the connection.");
this.conn.close();
// test if this method should be retried
// ========================================
// this code is provided for backward compatibility with 2.0
// will be removed in the next major release
if (method instanceof HttpMethodBase) {
MethodRetryHandler handler =
((HttpMethodBase)method).getMethodRetryHandler();
if (handler != null) {
if (!handler.retryMethod(
method,
this.conn,
new HttpRecoverableException(e.getMessage()),
execCount,
method.isRequestSent())) {
LOG.debug("Method retry handler returned false. "
+ "Automatic recovery will not be attempted");
throw e;
}
}
}
// ========================================
HttpMethodRetryHandler handler =
(HttpMethodRetryHandler)method.getParams().getParameter(
HttpMethodParams.RETRY_HANDLER);
if (handler == null) {
handler = new DefaultHttpMethodRetryHandler();
}
if (!handler.retryMethod(method, e, execCount)) {
LOG.debug("Method retry handler returned false. "
+ "Automatic recovery will not be attempted");
throw e;
}
if (LOG.isInfoEnabled()) {
LOG.info("I/O exception ("+ e.getClass().getName() +") caught when processing request: "
+ e.getMessage());
}
if (LOG.isDebugEnabled()) {
LOG.debug(e.getMessage(), e);
}
LOG.info("Retrying request");
}
}
} catch (IOException e) {
if (this.conn.isOpen()) {
LOG.debug("Closing the connection.");
this.conn.close();
}
releaseConnection = true;
throw e;
} catch (RuntimeException e) {
if (this.conn.isOpen()) {
LOG.debug("Closing the connection.");
this.conn.close();
}
releaseConnection = true;
throw e;
}
}
/**
* Executes a ConnectMethod to establish a tunneled connection.
*
* @return <code>true</code> if the connect was successful
*
* @throws IOException
* @throws HttpException
*/
private boolean executeConnect()
throws IOException, HttpException {
this.connectMethod = new ConnectMethod(this.hostConfiguration);
this.connectMethod.getParams().setDefaults(this.hostConfiguration.getParams());
int code;
for (;;) {
if (!this.conn.isOpen()) {
this.conn.open();
}
if (this.params.isAuthenticationPreemptive()
|| this.state.isAuthenticationPreemptive()) {
LOG.debug("Preemptively sending default basic credentials");
this.connectMethod.getProxyAuthState().setPreemptive();
this.connectMethod.getProxyAuthState().setAuthAttempted(true);
}
try {
authenticateProxy(this.connectMethod);
} catch (AuthenticationException e) {
LOG.error(e.getMessage(), e);
}
applyConnectionParams(this.connectMethod);
this.connectMethod.execute(state, this.conn);
code = this.connectMethod.getStatusCode();
boolean retry = false;
AuthState authstate = this.connectMethod.getProxyAuthState();
authstate.setAuthRequested(code == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
if (authstate.isAuthRequested()) {
if (processAuthenticationResponse(this.connectMethod)) {
retry = true;
}
}
if (!retry) {
break;
}
if (this.connectMethod.getResponseBodyAsStream() != null) {
this.connectMethod.getResponseBodyAsStream().close();
}
}
if ((code >= 200) && (code < 300)) {
this.conn.tunnelCreated();
// Drop the connect method, as it is no longer needed
this.connectMethod = null;
return true;
} else {
this.conn.close();
return false;
}
}
/**
* Fake response
* @param method
* @return
*/
private void fakeResponse(final HttpMethod method)
throws IOException, HttpException {
// What is to follow is an ugly hack.
// I REALLY hate having to resort to such
// an appalling trick
// The only feasible solution is to split monolithic
// HttpMethod into HttpRequest/HttpResponse pair.
// That would allow to execute CONNECT method
// behind the scene and return CONNECT HttpResponse
// object in response to the original request that
// contains the correct status line, headers &
// response body.
LOG.debug("CONNECT failed, fake the response for the original method");
// Pass the status, headers and response stream to the wrapped
// method.
// To ensure that the connection is not released more than once
// this method is still responsible for releasing the connection.
// This will happen when the response body is consumed, or when
// the wrapped method closes the response connection in
// releaseConnection().
if (method instanceof HttpMethodBase) {
((HttpMethodBase) method).fakeResponse(
this.connectMethod.getStatusLine(),
this.connectMethod.getResponseHeaderGroup(),
this.connectMethod.getResponseBodyAsStream()
);
method.getProxyAuthState().setAuthScheme(
this.connectMethod.getProxyAuthState().getAuthScheme());
this.connectMethod = null;
} else {
releaseConnection = true;
LOG.warn(
"Unable to fake response on method as it is not derived from HttpMethodBase.");
}
}
/**
* Process the redirect response.
*
* @return <code>true</code> if the redirect was successful
*/
private boolean processRedirectResponse(final HttpMethod method)
throws RedirectException {
//get the location header to find out where to redirect to
Header locationHeader = method.getResponseHeader("location");
if (locationHeader == null) {
// got a redirect response, but no location header
LOG.error("Received redirect response " + method.getStatusCode()
+ " but no location header");
return false;
}
String location = locationHeader.getValue();
if (LOG.isDebugEnabled()) {
LOG.debug("Redirect requested to location '" + location + "'");
}
//rfc2616 demands the location value be a complete URI
//Location = "Location" ":" absoluteURI
URI redirectUri = null;
URI currentUri = null;
try {
currentUri = new URI(
this.conn.getProtocol().getScheme(),
null,
this.conn.getHost(),
this.conn.getPort(),
method.getPath()
);
String charset = method.getParams().getUriCharset();
redirectUri = new URI(location, true, charset);
if (redirectUri.isRelativeURI()) {
if (this.params.isParameterTrue(HttpClientParams.REJECT_RELATIVE_REDIRECT)) {
LOG.warn("Relative redirect location '" + location + "' not allowed");
return false;
} else {
//location is incomplete, use current values for defaults
LOG.debug("Redirect URI is not absolute - parsing as relative");
redirectUri = new URI(currentUri, redirectUri);
}
} else {
// Reset the default params
method.getParams().setDefaults(this.params);
}
method.setURI(redirectUri);
hostConfiguration.setHost(redirectUri);
} catch (URIException ex) {
throw new InvalidRedirectLocationException(
"Invalid redirect location: " + location, location, ex);
}
if (this.params.isParameterFalse(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS)) {
if (this.redirectLocations == null) {
this.redirectLocations = new HashSet();
}
this.redirectLocations.add(currentUri);
try {
if(redirectUri.hasQuery()) {
redirectUri.setQuery(null);
}
} catch (URIException e) {
// Should never happen
return false;
}
if (this.redirectLocations.contains(redirectUri)) {
throw new CircularRedirectException("Circular redirect to '" +
redirectUri + "'");
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("Redirecting from '" + currentUri.getEscapedURI()
+ "' to '" + redirectUri.getEscapedURI());
}
//And finally invalidate the actual authentication scheme
method.getHostAuthState().invalidate();
return true;
}
/**
* Processes a response that requires authentication
*
* @param method the current {@link HttpMethod HTTP method}
*
* @return <tt>true</tt> if the authentication challenge can be responsed to,
* (that is, at least one of the requested authentication scheme is supported,
* and matching credentials have been found), <tt>false</tt> otherwise.
*/
private boolean processAuthenticationResponse(final HttpMethod method) {
LOG.trace("enter HttpMethodBase.processAuthenticationResponse("
+ "HttpState, HttpConnection)");
try {
switch (method.getStatusCode()) {
case HttpStatus.SC_UNAUTHORIZED:
return processWWWAuthChallenge(method);
case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
return processProxyAuthChallenge(method);
default:
return false;
}
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error(e.getMessage(), e);
}
return false;
}
}
private boolean processWWWAuthChallenge(final HttpMethod method)
throws MalformedChallengeException, AuthenticationException
{
AuthState authstate = method.getHostAuthState();
Map challenges = AuthChallengeParser.parseChallenges(
method.getResponseHeaders(WWW_AUTH_CHALLENGE));
if (challenges.isEmpty()) {
LOG.debug("Authentication challenge(s) not found");
return false;
}
AuthScheme authscheme = null;
try {
authscheme = this.authProcessor.processChallenge(authstate, challenges);
} catch (AuthChallengeException e) {
if (LOG.isWarnEnabled()) {
LOG.warn(e.getMessage());
}
}
if (authscheme == null) {
return false;
}
String host = method.getParams().getVirtualHost();
if (host == null) {
host = conn.getHost();
}
int port = conn.getPort();
AuthScope authscope = new AuthScope(
host, port,
authscheme.getRealm(),
authscheme.getSchemeName());
if (LOG.isDebugEnabled()) {
LOG.debug("Authentication scope: " + authscope);
}
if (authstate.isAuthAttempted() && authscheme.isComplete()) {
// Already tried and failed
Credentials credentials = promptForCredentials(
authscheme, method.getParams(), authscope);
if (credentials == null) {
if (LOG.isInfoEnabled()) {
LOG.info("Failure authenticating with " + authscope);
}
return false;
} else {
return true;
}
} else {
authstate.setAuthAttempted(true);
Credentials credentials = this.state.getCredentials(authscope);
if (credentials == null) {
credentials = promptForCredentials(
authscheme, method.getParams(), authscope);
}
if (credentials == null) {
if (LOG.isInfoEnabled()) {
LOG.info("No credentials available for " + authscope);
}
return false;
} else {
return true;
}
}
}
private boolean processProxyAuthChallenge(final HttpMethod method)
throws MalformedChallengeException, AuthenticationException
{
AuthState authstate = method.getProxyAuthState();
Map proxyChallenges = AuthChallengeParser.parseChallenges(
method.getResponseHeaders(PROXY_AUTH_CHALLENGE));
if (proxyChallenges.isEmpty()) {
LOG.debug("Proxy authentication challenge(s) not found");
return false;
}
AuthScheme authscheme = null;
try {
authscheme = this.authProcessor.processChallenge(authstate, proxyChallenges);
} catch (AuthChallengeException e) {
if (LOG.isWarnEnabled()) {
LOG.warn(e.getMessage());
}
}
if (authscheme == null) {
return false;
}
AuthScope authscope = new AuthScope(
conn.getProxyHost(), conn.getProxyPort(),
authscheme.getRealm(),
authscheme.getSchemeName());
if (LOG.isDebugEnabled()) {
LOG.debug("Proxy authentication scope: " + authscope);
}
if (authstate.isAuthAttempted() && authscheme.isComplete()) {
// Already tried and failed
Credentials credentials = promptForProxyCredentials(
authscheme, method.getParams(), authscope);
if (credentials == null) {
if (LOG.isInfoEnabled()) {
LOG.info("Failure authenticating with " + authscope);
}
return false;
} else {
return true;
}
} else {
authstate.setAuthAttempted(true);
Credentials credentials = this.state.getProxyCredentials(authscope);
if (credentials == null) {
credentials = promptForProxyCredentials(
authscheme, method.getParams(), authscope);
}
if (credentials == null) {
if (LOG.isInfoEnabled()) {
LOG.info("No credentials available for " + authscope);
}
return false;
} else {
return true;
}
}
}
/**
* Tests if the {@link HttpMethod method} requires a redirect to another location.
*
* @param method HTTP method
*
* @return boolean <tt>true</tt> if a retry is needed, <tt>false</tt> otherwise.
*/
private boolean isRedirectNeeded(final HttpMethod method) {
switch (method.getStatusCode()) {
case HttpStatus.SC_MOVED_TEMPORARILY:
case HttpStatus.SC_MOVED_PERMANENTLY:
case HttpStatus.SC_SEE_OTHER:
case HttpStatus.SC_TEMPORARY_REDIRECT:
LOG.debug("Redirect required");
if (method.getFollowRedirects()) {
return true;
} else {
return false;
}
default:
return false;
} //end of switch
}
/**
* Tests if the {@link HttpMethod method} requires authentication.
*
* @param method HTTP method
*
* @return boolean <tt>true</tt> if a retry is needed, <tt>false</tt> otherwise.
*/
private boolean isAuthenticationNeeded(final HttpMethod method) {
method.getHostAuthState().setAuthRequested(
method.getStatusCode() == HttpStatus.SC_UNAUTHORIZED);
method.getProxyAuthState().setAuthRequested(
method.getStatusCode() == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
if (method.getHostAuthState().isAuthRequested() ||
method.getProxyAuthState().isAuthRequested()) {
LOG.debug("Authorization required");
if (method.getDoAuthentication()) { //process authentication response
return true;
} else { //let the client handle the authenticaiton
LOG.info("Authentication requested but doAuthentication is "
+ "disabled");
return false;
}
} else {
return false;
}
}
private Credentials promptForCredentials(
final AuthScheme authScheme,
final HttpParams params,
final AuthScope authscope)
{
LOG.debug("Credentials required");
Credentials creds = null;
CredentialsProvider credProvider =
(CredentialsProvider)params.getParameter(CredentialsProvider.PROVIDER);
if (credProvider != null) {
try {
creds = credProvider.getCredentials(
authScheme, authscope.getHost(), authscope.getPort(), false);
} catch (CredentialsNotAvailableException e) {
LOG.warn(e.getMessage());
}
if (creds != null) {
this.state.setCredentials(authscope, creds);
if (LOG.isDebugEnabled()) {
LOG.debug(authscope + " new credentials given");
}
}
} else {
LOG.debug("Credentials provider not available");
}
return creds;
}
private Credentials promptForProxyCredentials(
final AuthScheme authScheme,
final HttpParams params,
final AuthScope authscope)
{
LOG.debug("Proxy credentials required");
Credentials creds = null;
CredentialsProvider credProvider =
(CredentialsProvider)params.getParameter(CredentialsProvider.PROVIDER);
if (credProvider != null) {
try {
creds = credProvider.getCredentials(
authScheme, authscope.getHost(), authscope.getPort(), true);
} catch (CredentialsNotAvailableException e) {
LOG.warn(e.getMessage());
}
if (creds != null) {
this.state.setProxyCredentials(authscope, creds);
if (LOG.isDebugEnabled()) {
LOG.debug(authscope + " new credentials given");
}
}
} else {
LOG.debug("Proxy credentials provider not available");
}
return creds;
}
/**
* @return
*/
public HostConfiguration getHostConfiguration() {
return hostConfiguration;
}
/**
* @return
*/
public HttpState getState() {
return state;
}
/**
* @return
*/
public HttpConnectionManager getConnectionManager() {
return connectionManager;
}
/**
* @return
*/
public HttpParams getParams() {
return this.params;
}
}
|