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