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