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 = this.params.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 if (this.redirectLocations.contains(redirectUri)) {
597 throw new RedirectException("Circular redirect to '" +
598 redirectUri + "'");
599 }
600 }
601
602 if (LOG.isDebugEnabled()) {
603 LOG.debug("Redirecting from '" + currentUri.getEscapedURI()
604 + "' to '" + redirectUri.getEscapedURI());
605 }
606
607
608 method.getHostAuthState().invalidate();
609 return true;
610 }
611
612 /***
613 * Processes a response that requires authentication
614 *
615 * @param method the current {@link HttpMethod HTTP method}
616 *
617 * @return <tt>true</tt> if the authentication challenge can be responsed to,
618 * (that is, at least one of the requested authentication scheme is supported,
619 * and matching credentials have been found), <tt>false</tt> otherwise.
620 */
621 private boolean processAuthenticationResponse(final HttpMethod method) {
622 LOG.trace("enter HttpMethodBase.processAuthenticationResponse("
623 + "HttpState, HttpConnection)");
624
625 try {
626 switch (method.getStatusCode()) {
627 case HttpStatus.SC_UNAUTHORIZED:
628 return processWWWAuthChallenge(method);
629 case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
630 return processProxyAuthChallenge(method);
631 default:
632 return false;
633 }
634 } catch (Exception e) {
635 if (LOG.isErrorEnabled()) {
636 LOG.error(e.getMessage(), e);
637 }
638 return false;
639 }
640 }
641
642 private boolean processWWWAuthChallenge(final HttpMethod method)
643 throws MalformedChallengeException, AuthenticationException
644 {
645 AuthState authstate = method.getHostAuthState();
646 if (authstate.isPreemptive()) {
647 authstate.invalidate();
648 }
649 Map challenges = AuthChallengeParser.parseChallenges(
650 method.getResponseHeaders(WWW_AUTH_CHALLENGE));
651 if (challenges.isEmpty()) {
652 return false;
653 }
654 AuthScheme authscheme = null;
655 try {
656 authscheme = this.authProcessor.processChallenge(authstate, challenges);
657 } catch (AuthChallengeException e) {
658 if (LOG.isWarnEnabled()) {
659 LOG.warn(e.getMessage());
660 }
661 }
662 if (authscheme == null) {
663 return false;
664 }
665 String host = method.getParams().getVirtualHost();
666 if (host == null) {
667 host = conn.getHost();
668 }
669 int port = conn.getPort();
670 AuthScope authscope = new AuthScope(
671 host, port,
672 authscheme.getRealm(),
673 authscheme.getSchemeName());
674
675 if (authstate.isAuthAttempted() && authscheme.isComplete()) {
676
677 Credentials credentials = promptForCredentials(
678 authscheme, method.getParams(), authscope);
679 if (credentials == null) {
680 if (LOG.isInfoEnabled()) {
681 LOG.info("Failure authenticating with " + authscope);
682 }
683 return false;
684 } else {
685 return true;
686 }
687 } else {
688 authstate.setAuthAttempted(true);
689 Credentials credentials = this.state.getCredentials(authscope);
690 if (credentials == null) {
691 credentials = promptForCredentials(
692 authscheme, method.getParams(), authscope);
693 }
694 if (credentials == null) {
695 if (LOG.isInfoEnabled()) {
696 LOG.info("No credentials available for " + authscope);
697 }
698 return false;
699 } else {
700 return true;
701 }
702 }
703 }
704
705 private boolean processProxyAuthChallenge(final HttpMethod method)
706 throws MalformedChallengeException, AuthenticationException
707 {
708 AuthState authstate = method.getProxyAuthState();
709 if (authstate.isPreemptive()) {
710 authstate.invalidate();
711 }
712 Map proxyChallenges = AuthChallengeParser.parseChallenges(
713 method.getResponseHeaders(PROXY_AUTH_CHALLENGE));
714 if (proxyChallenges.isEmpty()) {
715 return false;
716 }
717 AuthScheme authscheme = null;
718 try {
719 authscheme = this.authProcessor.processChallenge(authstate, proxyChallenges);
720 } catch (AuthChallengeException e) {
721 if (LOG.isWarnEnabled()) {
722 LOG.warn(e.getMessage());
723 }
724 }
725 if (authscheme == null) {
726 return false;
727 }
728 AuthScope authscope = new AuthScope(
729 conn.getProxyHost(), conn.getProxyPort(),
730 authscheme.getRealm(),
731 authscheme.getSchemeName());
732
733 if (authstate.isAuthAttempted() && authscheme.isComplete()) {
734
735 Credentials credentials = promptForProxyCredentials(
736 authscheme, method.getParams(), authscope);
737 if (credentials == null) {
738 if (LOG.isInfoEnabled()) {
739 LOG.info("Failure authenticating with " + authscope);
740 }
741 return false;
742 } else {
743 return true;
744 }
745 } else {
746 authstate.setAuthAttempted(true);
747 Credentials credentials = this.state.getProxyCredentials(authscope);
748 if (credentials == null) {
749 credentials = promptForProxyCredentials(
750 authscheme, method.getParams(), authscope);
751 }
752 if (credentials == null) {
753 if (LOG.isInfoEnabled()) {
754 LOG.info("No credentials available for " + authscope);
755 }
756 return false;
757 } else {
758 return true;
759 }
760 }
761 }
762
763 /***
764 * Tests if the {@link HttpMethod method} requires a redirect to another location.
765 *
766 * @param method HTTP method
767 *
768 * @return boolean <tt>true</tt> if a retry is needed, <tt>false</tt> otherwise.
769 */
770 private boolean isRedirectNeeded(final HttpMethod method) {
771 switch (method.getStatusCode()) {
772 case HttpStatus.SC_MOVED_TEMPORARILY:
773 case HttpStatus.SC_MOVED_PERMANENTLY:
774 case HttpStatus.SC_SEE_OTHER:
775 case HttpStatus.SC_TEMPORARY_REDIRECT:
776 LOG.debug("Redirect required");
777 if (method.getFollowRedirects()) {
778 return true;
779 } else {
780 LOG.info("Redirect requested but followRedirects is "
781 + "disabled");
782 return false;
783 }
784 default:
785 return false;
786 }
787 }
788
789 /***
790 * Tests if the {@link HttpMethod method} requires authentication.
791 *
792 * @param method HTTP method
793 *
794 * @return boolean <tt>true</tt> if a retry is needed, <tt>false</tt> otherwise.
795 */
796 private boolean isAuthenticationNeeded(final HttpMethod method) {
797 method.getHostAuthState().setAuthRequested(
798 method.getStatusCode() == HttpStatus.SC_UNAUTHORIZED);
799 method.getProxyAuthState().setAuthRequested(
800 method.getStatusCode() == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
801 if (method.getHostAuthState().isAuthRequested() ||
802 method.getProxyAuthState().isAuthRequested()) {
803 LOG.debug("Authorization required");
804 if (method.getDoAuthentication()) {
805 return true;
806 } else {
807 LOG.info("Authentication requested but doAuthentication is "
808 + "disabled");
809 return false;
810 }
811 } else {
812 return false;
813 }
814 }
815
816 private Credentials promptForCredentials(
817 final AuthScheme authScheme,
818 final HttpParams params,
819 final AuthScope authscope)
820 {
821 Credentials creds = null;
822 CredentialsProvider credProvider =
823 (CredentialsProvider)params.getParameter(CredentialsProvider.PROVIDER);
824 if (credProvider != null) {
825 try {
826 creds = credProvider.getCredentials(
827 authScheme, authscope.getHost(), authscope.getPort(), false);
828 } catch (CredentialsNotAvailableException e) {
829 LOG.warn(e.getMessage());
830 }
831 if (creds != null) {
832 this.state.setCredentials(authscope, creds);
833 if (LOG.isDebugEnabled()) {
834 LOG.debug(authscope + " new credentials given");
835 }
836 }
837 }
838 return creds;
839 }
840
841 private Credentials promptForProxyCredentials(
842 final AuthScheme authScheme,
843 final HttpParams params,
844 final AuthScope authscope)
845 {
846 Credentials creds = null;
847 CredentialsProvider credProvider =
848 (CredentialsProvider)params.getParameter(CredentialsProvider.PROVIDER);
849 if (credProvider != null) {
850 try {
851 creds = credProvider.getCredentials(
852 authScheme, authscope.getHost(), authscope.getPort(), true);
853 } catch (CredentialsNotAvailableException e) {
854 LOG.warn(e.getMessage());
855 }
856 if (creds != null) {
857 this.state.setProxyCredentials(authscope, creds);
858 if (LOG.isDebugEnabled()) {
859 LOG.debug(authscope + " new credentials given");
860 }
861 }
862 }
863 return creds;
864 }
865
866 /***
867 * @return
868 */
869 public HostConfiguration getHostConfiguration() {
870 return hostConfiguration;
871 }
872
873 /***
874 * @return
875 */
876 public HttpState getState() {
877 return state;
878 }
879
880 /***
881 * @return
882 */
883 public HttpConnectionManager getConnectionManager() {
884 return connectionManager;
885 }
886
887 /***
888 * @return
889 */
890 public HttpParams getParams() {
891 return this.params;
892 }
893 }