1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.apache.commons.httpclient;
31
32 import java.io.IOException;
33 import java.util.Collection;
34 import java.util.HashSet;
35 import java.util.Iterator;
36 import java.util.Map;
37 import java.util.Set;
38
39 import org.apache.commons.httpclient.auth.AuthChallengeException;
40 import org.apache.commons.httpclient.auth.AuthChallengeParser;
41 import org.apache.commons.httpclient.auth.AuthChallengeProcessor;
42 import org.apache.commons.httpclient.auth.AuthScheme;
43 import org.apache.commons.httpclient.auth.AuthState;
44 import org.apache.commons.httpclient.auth.AuthenticationException;
45 import org.apache.commons.httpclient.auth.CredentialsProvider;
46 import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
47 import org.apache.commons.httpclient.auth.AuthScope;
48 import org.apache.commons.httpclient.auth.MalformedChallengeException;
49 import org.apache.commons.httpclient.params.HostParams;
50 import org.apache.commons.httpclient.params.HttpClientParams;
51 import org.apache.commons.httpclient.params.HttpConnectionParams;
52 import org.apache.commons.httpclient.params.HttpMethodParams;
53 import org.apache.commons.httpclient.params.HttpParams;
54 import org.apache.commons.logging.Log;
55 import org.apache.commons.logging.LogFactory;
56
57 /***
58 * Handles the process of executing a method including authentication, redirection and retries.
59 *
60 * @since 3.0
61 */
62 class HttpMethodDirector {
63
64 /*** The www authenticate challange header. */
65 public static final String WWW_AUTH_CHALLENGE = "WWW-Authenticate";
66
67 /*** The www authenticate response header. */
68 public static final String WWW_AUTH_RESP = "Authorization";
69
70 /*** The proxy authenticate challange header. */
71 public static final String PROXY_AUTH_CHALLENGE = "Proxy-Authenticate";
72
73 /*** The proxy authenticate response header. */
74 public static final String PROXY_AUTH_RESP = "Proxy-Authorization";
75
76 private static final Log LOG = LogFactory.getLog(HttpMethodDirector.class);
77
78 private ConnectMethod connectMethod;
79
80 private HttpState state;
81
82 private HostConfiguration hostConfiguration;
83
84 private HttpConnectionManager connectionManager;
85
86 private HttpClientParams params;
87
88 private HttpConnection conn;
89
90 /*** A flag to indicate if the connection should be released after the method is executed. */
91 private boolean releaseConnection = false;
92
93 /*** Authentication processor */
94 private AuthChallengeProcessor authProcessor = null;
95
96 private Set redirectLocations = null;
97
98 public HttpMethodDirector(
99 final HttpConnectionManager connectionManager,
100 final HostConfiguration hostConfiguration,
101 final HttpClientParams params,
102 final HttpState state
103 ) {
104 super();
105 this.connectionManager = connectionManager;
106 this.hostConfiguration = hostConfiguration;
107 this.params = params;
108 this.state = state;
109 this.authProcessor = new AuthChallengeProcessor(this.params);
110 }
111
112
113 /***
114 * Executes the method associated with this method director.
115 *
116 * @throws IOException
117 * @throws HttpException
118 */
119 public void executeMethod(final HttpMethod method) throws IOException, HttpException {
120 if (method == null) {
121 throw new IllegalArgumentException("Method may not be null");
122 }
123
124
125 this.hostConfiguration.getParams().setDefaults(this.params);
126 method.getParams().setDefaults(this.hostConfiguration.getParams());
127
128
129 Collection defaults = (Collection)this.hostConfiguration.getParams().
130 getParameter(HostParams.DEFAULT_HEADERS);
131 if (defaults != null) {
132 Iterator i = defaults.iterator();
133 while (i.hasNext()) {
134 method.addRequestHeader((Header)i.next());
135 }
136 }
137
138 try {
139 int maxRedirects = this.params.getIntParameter(HttpClientParams.MAX_REDIRECTS, 100);
140
141 for (int redirectCount = 0;;) {
142
143
144 if (this.conn != null && !hostConfiguration.hostEquals(this.conn)) {
145 this.conn.setLocked(false);
146 this.conn.releaseConnection();
147 this.conn = null;
148 }
149
150
151 if (this.conn == null) {
152 this.conn = connectionManager.getConnectionWithTimeout(
153 hostConfiguration,
154 this.params.getConnectionManagerTimeout()
155 );
156 this.conn.setLocked(true);
157 if (this.params.isAuthenticationPreemptive()
158 || this.state.isAuthenticationPreemptive())
159 {
160 LOG.debug("Preemptively sending default basic credentials");
161 method.getHostAuthState().setPreemptive();
162 if (this.conn.isProxied()) {
163 method.getProxyAuthState().setPreemptive();
164 }
165 }
166 }
167 authenticate(method);
168 executeWithRetry(method);
169 if (this.connectMethod != null) {
170 fakeResponse(method);
171 break;
172 }
173
174 boolean retry = false;
175 if (isRedirectNeeded(method)) {
176 if (processRedirectResponse(method)) {
177 retry = true;
178 ++redirectCount;
179 if (redirectCount >= maxRedirects) {
180 LOG.error("Narrowly avoided an infinite loop in execute");
181 throw new RedirectException("Maximum redirects ("
182 + maxRedirects + ") exceeded");
183 }
184 if (LOG.isDebugEnabled()) {
185 LOG.debug("Execute redirect " + redirectCount + " of " + maxRedirects);
186 }
187 }
188 }
189 if (isAuthenticationNeeded(method)) {
190 if (processAuthenticationResponse(method)) {
191 retry = true;
192 }
193 }
194 if (!retry) {
195 break;
196 }
197
198
199
200 if (method.getResponseBodyAsStream() != null) {
201 method.getResponseBodyAsStream().close();
202 }
203
204 }
205 } finally {
206 if (this.conn != null) {
207 this.conn.setLocked(false);
208 }
209
210
211
212
213
214 if (
215 (releaseConnection || method.getResponseBodyAsStream() == null)
216 && this.conn != null
217 ) {
218 this.conn.releaseConnection();
219 }
220 }
221
222 }
223
224
225 private void authenticate(final HttpMethod method) {
226 try {
227 authenticateProxy(method);
228 authenticateHost(method);
229 } catch (AuthenticationException e) {
230 LOG.error(e.getMessage(), e);
231 }
232 }
233
234
235 private boolean cleanAuthHeaders(final HttpMethod method, final String name) {
236 Header[] authheaders = method.getRequestHeaders(name);
237 boolean clean = true;
238 for (int i = 0; i < authheaders.length; i++) {
239 Header authheader = authheaders[i];
240 if (authheader.isAutogenerated()) {
241 method.removeRequestHeader(authheader);
242 } else {
243 clean = false;
244 }
245 }
246 return clean;
247 }
248
249
250 private void authenticateHost(final HttpMethod method) throws AuthenticationException {
251
252 if (!cleanAuthHeaders(method, WWW_AUTH_RESP)) {
253
254 return;
255 }
256 AuthState authstate = method.getHostAuthState();
257 AuthScheme authscheme = authstate.getAuthScheme();
258 if (authscheme == null) {
259 return;
260 }
261 if (authstate.isAuthRequested() || !authscheme.isConnectionBased()) {
262 String host = method.getParams().getVirtualHost();
263 if (host == null) {
264 host = conn.getHost();
265 }
266 int port = conn.getPort();
267 AuthScope authscope = new AuthScope(
268 host, port,
269 authscheme.getRealm(),
270 authscheme.getSchemeName());
271 if (LOG.isDebugEnabled()) {
272 LOG.debug("Authenticating with " + authscope);
273 }
274 Credentials credentials = this.state.getCredentials(authscope);
275 if (credentials != null) {
276 String authstring = authscheme.authenticate(credentials, method);
277 if (authstring != null) {
278 method.addRequestHeader(new Header(WWW_AUTH_RESP, authstring, true));
279 }
280 } else {
281 if (LOG.isWarnEnabled()) {
282 LOG.warn("Required credentials not available for " + authscope);
283 if (method.getHostAuthState().isPreemptive()) {
284 LOG.warn("Preemptive authentication requested but no default " +
285 "credentials available");
286 }
287 }
288 }
289 }
290 }
291
292
293 private void authenticateProxy(final HttpMethod method) throws AuthenticationException {
294
295 if (!cleanAuthHeaders(method, PROXY_AUTH_RESP)) {
296
297 return;
298 }
299 AuthState authstate = method.getProxyAuthState();
300 AuthScheme authscheme = authstate.getAuthScheme();
301 if (authscheme == null) {
302 return;
303 }
304 if (authstate.isAuthRequested() || !authscheme.isConnectionBased()) {
305 AuthScope authscope = new AuthScope(
306 conn.getProxyHost(), conn.getProxyPort(),
307 authscheme.getRealm(),
308 authscheme.getSchemeName());
309 if (LOG.isDebugEnabled()) {
310 LOG.debug("Authenticating with " + authscope);
311 }
312 Credentials credentials = this.state.getProxyCredentials(authscope);
313 if (credentials != null) {
314 String authstring = authscheme.authenticate(credentials, method);
315 if (authstring != null) {
316 method.addRequestHeader(new Header(PROXY_AUTH_RESP, authstring, true));
317 }
318 } else {
319 if (LOG.isWarnEnabled()) {
320 LOG.warn("Required proxy credentials not available for " + authscope);
321 if (method.getProxyAuthState().isPreemptive()) {
322 LOG.warn("Preemptive authentication requested but no default " +
323 "proxy credentials available");
324 }
325 }
326 }
327 }
328 }
329
330
331 /***
332 * Executes a method with the current hostConfiguration.
333 *
334 * @throws IOException if an I/O (transport) error occurs. Some transport exceptions
335 * can be recovered from.
336 * @throws HttpException if a protocol exception occurs. Usually protocol exceptions
337 * cannot be recovered from.
338 */
339 private void executeWithRetry(final HttpMethod method)
340 throws IOException, HttpException {
341
342 /*** How many times did this transparently handle a recoverable exception? */
343 int execCount = 0;
344
345
346 try {
347 while (true) {
348 execCount++;
349
350 if (LOG.isTraceEnabled()) {
351 LOG.trace("Attempt number " + execCount + " to process request");
352 }
353 if (this.conn.getParams().isStaleCheckingEnabled()) {
354 this.conn.closeIfStale();
355 }
356 if (!this.conn.isOpen()) {
357
358
359 this.conn.open();
360 if (this.conn.isProxied() && this.conn.isSecure()
361 && !(method instanceof ConnectMethod)) {
362
363 if (!executeConnect()) {
364
365 return;
366 }
367 }
368 }
369 int timeout = 0;
370
371 Object param = method.getParams().getParameter(HttpMethodParams.SO_TIMEOUT);
372 if (param == null) {
373
374 param = this.conn.getParams().getParameter(HttpConnectionParams.SO_TIMEOUT);
375 }
376 if (param != null) {
377 timeout = ((Integer)param).intValue();
378 }
379 this.conn.setSocketTimeout(timeout);
380
381 try {
382 method.execute(state, this.conn);
383 break;
384 } catch (HttpException e) {
385
386 throw e;
387 } catch (IOException e) {
388 LOG.debug("Closing the connection.");
389 this.conn.close();
390
391
392
393
394 if (method instanceof HttpMethodBase) {
395 MethodRetryHandler handler =
396 ((HttpMethodBase)method).getMethodRetryHandler();
397 if (handler != null) {
398 if (!handler.retryMethod(
399 method,
400 this.conn,
401 new HttpRecoverableException(e.getMessage()),
402 execCount,
403 method.isRequestSent())) {
404 LOG.debug("Method retry handler returned false. "
405 + "Automatic recovery will not be attempted");
406 throw e;
407 }
408 }
409 }
410
411 HttpMethodRetryHandler handler =
412 (HttpMethodRetryHandler)method.getParams().getParameter(
413 HttpMethodParams.RETRY_HANDLER);
414 if (handler == null) {
415 handler = new DefaultHttpMethodRetryHandler();
416 }
417 if (!handler.retryMethod(method, e, execCount)) {
418 LOG.debug("Method retry handler returned false. "
419 + "Automatic recovery will not be attempted");
420 throw e;
421 }
422 if (LOG.isInfoEnabled()) {
423 LOG.info("I/O exception caught when processing request: "
424 + e.getMessage());
425 }
426 if (LOG.isDebugEnabled()) {
427 LOG.debug(e.getMessage(), e);
428 }
429 LOG.info("Retrying request");
430 }
431 }
432 } catch (IOException e) {
433 if (this.conn.isOpen()) {
434 LOG.debug("Closing the connection.");
435 this.conn.close();
436 }
437 releaseConnection = true;
438 throw e;
439 } catch (RuntimeException e) {
440 if (this.conn.isOpen) {
441 LOG.debug("Closing the connection.");
442 this.conn.close();
443 }
444 releaseConnection = true;
445 throw e;
446 }
447 }
448
449 /***
450 * Executes a ConnectMethod to establish a tunneled connection.
451 *
452 * @return <code>true</code> if the connect was successful
453 *
454 * @throws IOException
455 * @throws HttpException
456 */
457 private boolean executeConnect()
458 throws IOException, HttpException {
459
460 this.connectMethod = new ConnectMethod();
461 this.connectMethod.getParams().setDefaults(this.params);
462
463 int code;
464 for (;;) {
465 try {
466 authenticateProxy(this.connectMethod);
467 } catch (AuthenticationException e) {
468 LOG.error(e.getMessage(), e);
469 }
470 executeWithRetry(this.connectMethod);
471 code = this.connectMethod.getStatusCode();
472 boolean retry = false;
473 AuthState authstate = this.connectMethod.getProxyAuthState();
474 authstate.setAuthRequested(code == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
475 if (authstate.isAuthRequested()) {
476 if (processAuthenticationResponse(this.connectMethod)) {
477 retry = true;
478 }
479 }
480 if (!retry) {
481 break;
482 }
483 if (this.connectMethod.getResponseBodyAsStream() != null) {
484 this.connectMethod.getResponseBodyAsStream().close();
485 }
486 }
487 if ((code >= 200) && (code < 300)) {
488 this.conn.tunnelCreated();
489
490 this.connectMethod = null;
491 return true;
492 } else {
493 return false;
494 }
495 }
496
497 /***
498 * Fake response
499 * @param method
500 * @return
501 */
502
503 private void fakeResponse(final HttpMethod method)
504 throws IOException, HttpException {
505
506
507
508
509
510
511
512
513
514
515 LOG.debug("CONNECT failed, fake the response for the original method");
516
517
518
519
520
521
522
523 if (method instanceof HttpMethodBase) {
524 ((HttpMethodBase) method).fakeResponse(
525 this.connectMethod.getStatusLine(),
526 this.connectMethod.getResponseHeaderGroup(),
527 this.connectMethod.getResponseBodyAsStream()
528 );
529 method.getProxyAuthState().setAuthScheme(
530 this.connectMethod.getProxyAuthState().getAuthScheme());
531 this.connectMethod = null;
532 } else {
533 releaseConnection = true;
534 LOG.warn(
535 "Unable to fake response on method as it is not derived from HttpMethodBase.");
536 }
537 }
538
539 /***
540 * Process the redirect response.
541 *
542 * @return <code>true</code> if the redirect was successful
543 */
544 private boolean processRedirectResponse(final HttpMethod method)
545 throws RedirectException
546 {
547
548 Header locationHeader = method.getResponseHeader("location");
549 if (locationHeader == null) {
550
551 LOG.error("Received redirect response " + method.getStatusCode()
552 + " but no location header");
553 return false;
554 }
555 String location = locationHeader.getValue();
556 if (LOG.isDebugEnabled()) {
557 LOG.debug("Redirect requested to location '" + location + "'");
558 }
559
560
561
562 URI redirectUri = null;
563 URI currentUri = null;
564
565 try {
566 currentUri = new URI(
567 this.conn.getProtocol().getScheme(),
568 null,
569 this.conn.getHost(),
570 this.conn.getPort(),
571 method.getPath()
572 );
573 redirectUri = new URI(location, true);
574 if (redirectUri.isRelativeURI()) {
575 if (this.params.isParameterTrue(HttpClientParams.REJECT_RELATIVE_REDIRECT)) {
576 LOG.warn("Relative redirect location '" + location + "' not allowed");
577 return false;
578 } else {
579
580 LOG.debug("Redirect URI is not absolute - parsing as relative");
581 redirectUri = new URI(currentUri, redirectUri);
582 }
583 }
584 method.setURI(redirectUri);
585 hostConfiguration.setHost(redirectUri);
586 } catch (URIException e) {
587 LOG.warn("Redirected location '" + location + "' is malformed");
588 return false;
589 }
590
591 if (this.params.isParameterFalse(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS)) {
592 if (this.redirectLocations == null) {
593 this.redirectLocations = new HashSet();
594 }
595 this.redirectLocations.add(currentUri);
596 try {
597 if(redirectUri.hasQuery()) {
598 redirectUri.setQuery(null);
599 }
600 } catch (URIException e) {
601
602 return false;
603 }
604
605 if (this.redirectLocations.contains(redirectUri)) {
606 throw new CircularRedirectException("Circular redirect to '" +
607 redirectUri + "'");
608 }
609 }
610
611 if (LOG.isDebugEnabled()) {
612 LOG.debug("Redirecting from '" + currentUri.getEscapedURI()
613 + "' to '" + redirectUri.getEscapedURI());
614 }
615
616 method.getHostAuthState().invalidate();
617 return true;
618 }
619
620 /***
621 * Processes a response that requires authentication
622 *
623 * @param method the current {@link HttpMethod HTTP method}
624 *
625 * @return <tt>true</tt> if the authentication challenge can be responsed to,
626 * (that is, at least one of the requested authentication scheme is supported,
627 * and matching credentials have been found), <tt>false</tt> otherwise.
628 */
629 private boolean processAuthenticationResponse(final HttpMethod method) {
630 LOG.trace("enter HttpMethodBase.processAuthenticationResponse("
631 + "HttpState, HttpConnection)");
632
633 try {
634 switch (method.getStatusCode()) {
635 case HttpStatus.SC_UNAUTHORIZED:
636 return processWWWAuthChallenge(method);
637 case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
638 return processProxyAuthChallenge(method);
639 default:
640 return false;
641 }
642 } catch (Exception e) {
643 if (LOG.isErrorEnabled()) {
644 LOG.error(e.getMessage(), e);
645 }
646 return false;
647 }
648 }
649
650 private boolean processWWWAuthChallenge(final HttpMethod method)
651 throws MalformedChallengeException, AuthenticationException
652 {
653 AuthState authstate = method.getHostAuthState();
654 if (authstate.isPreemptive()) {
655 authstate.invalidate();
656 }
657 Map challenges = AuthChallengeParser.parseChallenges(
658 method.getResponseHeaders(WWW_AUTH_CHALLENGE));
659 if (challenges.isEmpty()) {
660 return false;
661 }
662 AuthScheme authscheme = null;
663 try {
664 authscheme = this.authProcessor.processChallenge(authstate, challenges);
665 } catch (AuthChallengeException e) {
666 if (LOG.isWarnEnabled()) {
667 LOG.warn(e.getMessage());
668 }
669 }
670 if (authscheme == null) {
671 return false;
672 }
673 String host = method.getParams().getVirtualHost();
674 if (host == null) {
675 host = conn.getHost();
676 }
677 int port = conn.getPort();
678 AuthScope authscope = new AuthScope(
679 host, port,
680 authscheme.getRealm(),
681 authscheme.getSchemeName());
682
683 if (authstate.isAuthAttempted() && authscheme.isComplete()) {
684
685 Credentials credentials = promptForCredentials(
686 authscheme, method.getParams(), authscope);
687 if (credentials == null) {
688 if (LOG.isInfoEnabled()) {
689 LOG.info("Failure authenticating with " + authscope);
690 }
691 return false;
692 } else {
693 return true;
694 }
695 } else {
696 authstate.setAuthAttempted(true);
697 Credentials credentials = this.state.getCredentials(authscope);
698 if (credentials == null) {
699 credentials = promptForCredentials(
700 authscheme, method.getParams(), authscope);
701 }
702 if (credentials == null) {
703 if (LOG.isInfoEnabled()) {
704 LOG.info("No credentials available for " + authscope);
705 }
706 return false;
707 } else {
708 return true;
709 }
710 }
711 }
712
713 private boolean processProxyAuthChallenge(final HttpMethod method)
714 throws MalformedChallengeException, AuthenticationException
715 {
716 AuthState authstate = method.getProxyAuthState();
717 if (authstate.isPreemptive()) {
718 authstate.invalidate();
719 }
720 Map proxyChallenges = AuthChallengeParser.parseChallenges(
721 method.getResponseHeaders(PROXY_AUTH_CHALLENGE));
722 if (proxyChallenges.isEmpty()) {
723 return false;
724 }
725 AuthScheme authscheme = null;
726 try {
727 authscheme = this.authProcessor.processChallenge(authstate, proxyChallenges);
728 } catch (AuthChallengeException e) {
729 if (LOG.isWarnEnabled()) {
730 LOG.warn(e.getMessage());
731 }
732 }
733 if (authscheme == null) {
734 return false;
735 }
736 AuthScope authscope = new AuthScope(
737 conn.getProxyHost(), conn.getProxyPort(),
738 authscheme.getRealm(),
739 authscheme.getSchemeName());
740
741 if (authstate.isAuthAttempted() && authscheme.isComplete()) {
742
743 Credentials credentials = promptForProxyCredentials(
744 authscheme, method.getParams(), authscope);
745 if (credentials == null) {
746 if (LOG.isInfoEnabled()) {
747 LOG.info("Failure authenticating with " + authscope);
748 }
749 return false;
750 } else {
751 return true;
752 }
753 } else {
754 authstate.setAuthAttempted(true);
755 Credentials credentials = this.state.getProxyCredentials(authscope);
756 if (credentials == null) {
757 credentials = promptForProxyCredentials(
758 authscheme, method.getParams(), authscope);
759 }
760 if (credentials == null) {
761 if (LOG.isInfoEnabled()) {
762 LOG.info("No credentials available for " + authscope);
763 }
764 return false;
765 } else {
766 return true;
767 }
768 }
769 }
770
771 /***
772 * Tests if the {@link HttpMethod method} requires a redirect to another location.
773 *
774 * @param method HTTP method
775 *
776 * @return boolean <tt>true</tt> if a retry is needed, <tt>false</tt> otherwise.
777 */
778 private boolean isRedirectNeeded(final HttpMethod method) {
779 switch (method.getStatusCode()) {
780 case HttpStatus.SC_MOVED_TEMPORARILY:
781 case HttpStatus.SC_MOVED_PERMANENTLY:
782 case HttpStatus.SC_SEE_OTHER:
783 case HttpStatus.SC_TEMPORARY_REDIRECT:
784 LOG.debug("Redirect required");
785 if (method.getFollowRedirects()) {
786 return true;
787 } else {
788 LOG.info("Redirect requested but followRedirects is "
789 + "disabled");
790 return false;
791 }
792 default:
793 return false;
794 }
795 }
796
797 /***
798 * Tests if the {@link HttpMethod method} requires authentication.
799 *
800 * @param method HTTP method
801 *
802 * @return boolean <tt>true</tt> if a retry is needed, <tt>false</tt> otherwise.
803 */
804 private boolean isAuthenticationNeeded(final HttpMethod method) {
805 method.getHostAuthState().setAuthRequested(
806 method.getStatusCode() == HttpStatus.SC_UNAUTHORIZED);
807 method.getProxyAuthState().setAuthRequested(
808 method.getStatusCode() == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
809 if (method.getHostAuthState().isAuthRequested() ||
810 method.getProxyAuthState().isAuthRequested()) {
811 LOG.debug("Authorization required");
812 if (method.getDoAuthentication()) {
813 return true;
814 } else {
815 LOG.info("Authentication requested but doAuthentication is "
816 + "disabled");
817 return false;
818 }
819 } else {
820 return false;
821 }
822 }
823
824 private Credentials promptForCredentials(
825 final AuthScheme authScheme,
826 final HttpParams params,
827 final AuthScope authscope)
828 {
829 Credentials creds = null;
830 CredentialsProvider credProvider =
831 (CredentialsProvider)params.getParameter(CredentialsProvider.PROVIDER);
832 if (credProvider != null) {
833 try {
834 creds = credProvider.getCredentials(
835 authScheme, authscope.getHost(), authscope.getPort(), false);
836 } catch (CredentialsNotAvailableException e) {
837 LOG.warn(e.getMessage());
838 }
839 if (creds != null) {
840 this.state.setCredentials(authscope, creds);
841 if (LOG.isDebugEnabled()) {
842 LOG.debug(authscope + " new credentials given");
843 }
844 }
845 }
846 return creds;
847 }
848
849 private Credentials promptForProxyCredentials(
850 final AuthScheme authScheme,
851 final HttpParams params,
852 final AuthScope authscope)
853 {
854 Credentials creds = null;
855 CredentialsProvider credProvider =
856 (CredentialsProvider)params.getParameter(CredentialsProvider.PROVIDER);
857 if (credProvider != null) {
858 try {
859 creds = credProvider.getCredentials(
860 authScheme, authscope.getHost(), authscope.getPort(), true);
861 } catch (CredentialsNotAvailableException e) {
862 LOG.warn(e.getMessage());
863 }
864 if (creds != null) {
865 this.state.setProxyCredentials(authscope, creds);
866 if (LOG.isDebugEnabled()) {
867 LOG.debug(authscope + " new credentials given");
868 }
869 }
870 }
871 return creds;
872 }
873
874 /***
875 * @return
876 */
877 public HostConfiguration getHostConfiguration() {
878 return hostConfiguration;
879 }
880
881 /***
882 * @return
883 */
884 public HttpState getState() {
885 return state;
886 }
887
888 /***
889 * @return
890 */
891 public HttpConnectionManager getConnectionManager() {
892 return connectionManager;
893 }
894
895 /***
896 * @return
897 */
898 public HttpParams getParams() {
899 return this.params;
900 }
901 }