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 if (!this.conn.isOpen()) {
477 this.conn.open();
478 }
479 try {
480 authenticateProxy(this.connectMethod);
481 } catch (AuthenticationException e) {
482 LOG.error(e.getMessage(), e);
483 }
484 applyConnectionParams(this.connectMethod);
485 this.connectMethod.execute(state, this.conn);
486 code = this.connectMethod.getStatusCode();
487 boolean retry = false;
488 AuthState authstate = this.connectMethod.getProxyAuthState();
489 authstate.setAuthRequested(code == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
490 if (authstate.isAuthRequested()) {
491 if (processAuthenticationResponse(this.connectMethod)) {
492 retry = true;
493 }
494 }
495 if (!retry) {
496 break;
497 }
498 if (this.connectMethod.getResponseBodyAsStream() != null) {
499 this.connectMethod.getResponseBodyAsStream().close();
500 }
501 }
502 if ((code >= 200) && (code < 300)) {
503 this.conn.tunnelCreated();
504
505 this.connectMethod = null;
506 return true;
507 } else {
508 return false;
509 }
510 }
511
512 /***
513 * Fake response
514 * @param method
515 * @return
516 */
517
518 private void fakeResponse(final HttpMethod method)
519 throws IOException, HttpException {
520
521
522
523
524
525
526
527
528
529
530 LOG.debug("CONNECT failed, fake the response for the original method");
531
532
533
534
535
536
537
538 if (method instanceof HttpMethodBase) {
539 ((HttpMethodBase) method).fakeResponse(
540 this.connectMethod.getStatusLine(),
541 this.connectMethod.getResponseHeaderGroup(),
542 this.connectMethod.getResponseBodyAsStream()
543 );
544 method.getProxyAuthState().setAuthScheme(
545 this.connectMethod.getProxyAuthState().getAuthScheme());
546 this.connectMethod = null;
547 } else {
548 releaseConnection = true;
549 LOG.warn(
550 "Unable to fake response on method as it is not derived from HttpMethodBase.");
551 }
552 }
553
554 /***
555 * Process the redirect response.
556 *
557 * @return <code>true</code> if the redirect was successful
558 */
559 private boolean processRedirectResponse(final HttpMethod method)
560 throws RedirectException
561 {
562
563 Header locationHeader = method.getResponseHeader("location");
564 if (locationHeader == null) {
565
566 LOG.error("Received redirect response " + method.getStatusCode()
567 + " but no location header");
568 return false;
569 }
570 String location = locationHeader.getValue();
571 if (LOG.isDebugEnabled()) {
572 LOG.debug("Redirect requested to location '" + location + "'");
573 }
574
575
576
577 URI redirectUri = null;
578 URI currentUri = null;
579
580 try {
581 currentUri = new URI(
582 this.conn.getProtocol().getScheme(),
583 null,
584 this.conn.getHost(),
585 this.conn.getPort(),
586 method.getPath()
587 );
588 redirectUri = new URI(location, true);
589 if (redirectUri.isRelativeURI()) {
590 if (this.params.isParameterTrue(HttpClientParams.REJECT_RELATIVE_REDIRECT)) {
591 LOG.warn("Relative redirect location '" + location + "' not allowed");
592 return false;
593 } else {
594
595 LOG.debug("Redirect URI is not absolute - parsing as relative");
596 redirectUri = new URI(currentUri, redirectUri);
597 }
598 }
599 method.setURI(redirectUri);
600 hostConfiguration.setHost(redirectUri);
601 } catch (URIException e) {
602 LOG.warn("Redirected location '" + location + "' is malformed");
603 return false;
604 }
605
606 if (this.params.isParameterFalse(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS)) {
607 if (this.redirectLocations == null) {
608 this.redirectLocations = new HashSet();
609 }
610 this.redirectLocations.add(currentUri);
611 try {
612 if(redirectUri.hasQuery()) {
613 redirectUri.setQuery(null);
614 }
615 } catch (URIException e) {
616
617 return false;
618 }
619
620 if (this.redirectLocations.contains(redirectUri)) {
621 throw new CircularRedirectException("Circular redirect to '" +
622 redirectUri + "'");
623 }
624 }
625
626 if (LOG.isDebugEnabled()) {
627 LOG.debug("Redirecting from '" + currentUri.getEscapedURI()
628 + "' to '" + redirectUri.getEscapedURI());
629 }
630
631 method.getHostAuthState().invalidate();
632 return true;
633 }
634
635 /***
636 * Processes a response that requires authentication
637 *
638 * @param method the current {@link HttpMethod HTTP method}
639 *
640 * @return <tt>true</tt> if the authentication challenge can be responsed to,
641 * (that is, at least one of the requested authentication scheme is supported,
642 * and matching credentials have been found), <tt>false</tt> otherwise.
643 */
644 private boolean processAuthenticationResponse(final HttpMethod method) {
645 LOG.trace("enter HttpMethodBase.processAuthenticationResponse("
646 + "HttpState, HttpConnection)");
647
648 try {
649 switch (method.getStatusCode()) {
650 case HttpStatus.SC_UNAUTHORIZED:
651 return processWWWAuthChallenge(method);
652 case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
653 return processProxyAuthChallenge(method);
654 default:
655 return false;
656 }
657 } catch (Exception e) {
658 if (LOG.isErrorEnabled()) {
659 LOG.error(e.getMessage(), e);
660 }
661 return false;
662 }
663 }
664
665 private boolean processWWWAuthChallenge(final HttpMethod method)
666 throws MalformedChallengeException, AuthenticationException
667 {
668 AuthState authstate = method.getHostAuthState();
669 if (authstate.isPreemptive()) {
670 authstate.invalidate();
671 authstate.setAuthRequested(true);
672 }
673 Map challenges = AuthChallengeParser.parseChallenges(
674 method.getResponseHeaders(WWW_AUTH_CHALLENGE));
675 if (challenges.isEmpty()) {
676 LOG.debug("Authentication challenge(s) not found");
677 return false;
678 }
679 AuthScheme authscheme = null;
680 try {
681 authscheme = this.authProcessor.processChallenge(authstate, challenges);
682 } catch (AuthChallengeException e) {
683 if (LOG.isWarnEnabled()) {
684 LOG.warn(e.getMessage());
685 }
686 }
687 if (authscheme == null) {
688 return false;
689 }
690 String host = method.getParams().getVirtualHost();
691 if (host == null) {
692 host = conn.getHost();
693 }
694 int port = conn.getPort();
695 AuthScope authscope = new AuthScope(
696 host, port,
697 authscheme.getRealm(),
698 authscheme.getSchemeName());
699
700 if (LOG.isDebugEnabled()) {
701 LOG.debug("Authentication scope: " + authscope);
702 }
703 if (authstate.isAuthAttempted() && authscheme.isComplete()) {
704
705 Credentials credentials = promptForCredentials(
706 authscheme, method.getParams(), authscope);
707 if (credentials == null) {
708 if (LOG.isInfoEnabled()) {
709 LOG.info("Failure authenticating with " + authscope);
710 }
711 return false;
712 } else {
713 return true;
714 }
715 } else {
716 authstate.setAuthAttempted(true);
717 Credentials credentials = this.state.getCredentials(authscope);
718 if (credentials == null) {
719 credentials = promptForCredentials(
720 authscheme, method.getParams(), authscope);
721 }
722 if (credentials == null) {
723 if (LOG.isInfoEnabled()) {
724 LOG.info("No credentials available for " + authscope);
725 }
726 return false;
727 } else {
728 return true;
729 }
730 }
731 }
732
733 private boolean processProxyAuthChallenge(final HttpMethod method)
734 throws MalformedChallengeException, AuthenticationException
735 {
736 AuthState authstate = method.getProxyAuthState();
737 if (authstate.isPreemptive()) {
738 authstate.invalidate();
739 authstate.setAuthRequested(true);
740 }
741 Map proxyChallenges = AuthChallengeParser.parseChallenges(
742 method.getResponseHeaders(PROXY_AUTH_CHALLENGE));
743 if (proxyChallenges.isEmpty()) {
744 LOG.debug("Proxy authentication challenge(s) not found");
745 return false;
746 }
747 AuthScheme authscheme = null;
748 try {
749 authscheme = this.authProcessor.processChallenge(authstate, proxyChallenges);
750 } catch (AuthChallengeException e) {
751 if (LOG.isWarnEnabled()) {
752 LOG.warn(e.getMessage());
753 }
754 }
755 if (authscheme == null) {
756 return false;
757 }
758 AuthScope authscope = new AuthScope(
759 conn.getProxyHost(), conn.getProxyPort(),
760 authscheme.getRealm(),
761 authscheme.getSchemeName());
762
763 if (LOG.isDebugEnabled()) {
764 LOG.debug("Proxy authentication scope: " + authscope);
765 }
766 if (authstate.isAuthAttempted() && authscheme.isComplete()) {
767
768 Credentials credentials = promptForProxyCredentials(
769 authscheme, method.getParams(), authscope);
770 if (credentials == null) {
771 if (LOG.isInfoEnabled()) {
772 LOG.info("Failure authenticating with " + authscope);
773 }
774 return false;
775 } else {
776 return true;
777 }
778 } else {
779 authstate.setAuthAttempted(true);
780 Credentials credentials = this.state.getProxyCredentials(authscope);
781 if (credentials == null) {
782 credentials = promptForProxyCredentials(
783 authscheme, method.getParams(), authscope);
784 }
785 if (credentials == null) {
786 if (LOG.isInfoEnabled()) {
787 LOG.info("No credentials available for " + authscope);
788 }
789 return false;
790 } else {
791 return true;
792 }
793 }
794 }
795
796 /***
797 * Tests if the {@link HttpMethod method} requires a redirect to another location.
798 *
799 * @param method HTTP method
800 *
801 * @return boolean <tt>true</tt> if a retry is needed, <tt>false</tt> otherwise.
802 */
803 private boolean isRedirectNeeded(final HttpMethod method) {
804 switch (method.getStatusCode()) {
805 case HttpStatus.SC_MOVED_TEMPORARILY:
806 case HttpStatus.SC_MOVED_PERMANENTLY:
807 case HttpStatus.SC_SEE_OTHER:
808 case HttpStatus.SC_TEMPORARY_REDIRECT:
809 LOG.debug("Redirect required");
810 if (method.getFollowRedirects()) {
811 return true;
812 } else {
813 LOG.info("Redirect requested but followRedirects is "
814 + "disabled");
815 return false;
816 }
817 default:
818 return false;
819 }
820 }
821
822 /***
823 * Tests if the {@link HttpMethod method} requires authentication.
824 *
825 * @param method HTTP method
826 *
827 * @return boolean <tt>true</tt> if a retry is needed, <tt>false</tt> otherwise.
828 */
829 private boolean isAuthenticationNeeded(final HttpMethod method) {
830 method.getHostAuthState().setAuthRequested(
831 method.getStatusCode() == HttpStatus.SC_UNAUTHORIZED);
832 method.getProxyAuthState().setAuthRequested(
833 method.getStatusCode() == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
834 if (method.getHostAuthState().isAuthRequested() ||
835 method.getProxyAuthState().isAuthRequested()) {
836 LOG.debug("Authorization required");
837 if (method.getDoAuthentication()) {
838 return true;
839 } else {
840 LOG.info("Authentication requested but doAuthentication is "
841 + "disabled");
842 return false;
843 }
844 } else {
845 return false;
846 }
847 }
848
849 private Credentials promptForCredentials(
850 final AuthScheme authScheme,
851 final HttpParams params,
852 final AuthScope authscope)
853 {
854 LOG.debug("Credentials required");
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(), false);
862 } catch (CredentialsNotAvailableException e) {
863 LOG.warn(e.getMessage());
864 }
865 if (creds != null) {
866 this.state.setCredentials(authscope, creds);
867 if (LOG.isDebugEnabled()) {
868 LOG.debug(authscope + " new credentials given");
869 }
870 }
871 } else {
872 LOG.debug("Credentials provider not available");
873 }
874 return creds;
875 }
876
877 private Credentials promptForProxyCredentials(
878 final AuthScheme authScheme,
879 final HttpParams params,
880 final AuthScope authscope)
881 {
882 LOG.debug("Proxy credentials required");
883 Credentials creds = null;
884 CredentialsProvider credProvider =
885 (CredentialsProvider)params.getParameter(CredentialsProvider.PROVIDER);
886 if (credProvider != null) {
887 try {
888 creds = credProvider.getCredentials(
889 authScheme, authscope.getHost(), authscope.getPort(), true);
890 } catch (CredentialsNotAvailableException e) {
891 LOG.warn(e.getMessage());
892 }
893 if (creds != null) {
894 this.state.setProxyCredentials(authscope, creds);
895 if (LOG.isDebugEnabled()) {
896 LOG.debug(authscope + " new credentials given");
897 }
898 }
899 } else {
900 LOG.debug("Proxy credentials provider not available");
901 }
902 return creds;
903 }
904
905 /***
906 * @return
907 */
908 public HostConfiguration getHostConfiguration() {
909 return hostConfiguration;
910 }
911
912 /***
913 * @return
914 */
915 public HttpState getState() {
916 return state;
917 }
918
919 /***
920 * @return
921 */
922 public HttpConnectionManager getConnectionManager() {
923 return connectionManager;
924 }
925
926 /***
927 * @return
928 */
929 public HttpParams getParams() {
930 return this.params;
931 }
932 }