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