hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Httpcomponents Wiki] Update of "HttpClientTutorial" by OlegKalnichevski
Date Sat, 23 May 2009 12:47:08 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Httpcomponents Wiki" for change notification.

The following page has been changed by OlegKalnichevski:
http://wiki.apache.org/HttpComponents/HttpClientTutorial

------------------------------------------------------------------------------
  
      Originally HTTP was designed as a stateless, request / response oriented protocol that
made no special provisions for stateful sessions spanning across several logically related
request / response exchanges. As HTTP protocol grew in popularity and adoption more and more
systems began to use it for applications it was never intended for, for instance as a transport
for e-commerce applications. Thus, the support for state management became a necessity. 
      
-     Netscape Communications, at that time a leadidng developer of web client and server
software, implemented support for HTTP state management in their products based on a proprietary
specification. Later, Netscape tried to standardize the mechanism by publishing a specification
draft. Those efforts contributed to the formal specification defined through the  RFC standard
track. However, state management in a significant number of applications is still largely
based on the Netscape draft and is incompatible with the official specification. All major
developers of web browsers felt compelled to retain compatibility with those applications
greatly contributing to the fragmentation of standards compliance and compatibility issues.
+     Netscape Communications, at that time a leading developer of web client and server software,
implemented support for HTTP state management in their products based on a proprietary specification.
Later, Netscape tried to standardise the mechanism by publishing a specification draft. Those
efforts contributed to the formal specification defined through the  RFC standard track. However,
state management in a significant number of applications is still largely based on the Netscape
draft and is incompatible with the official specification. All major developers of web browsers
felt compelled to retain compatibility with those applications greatly contributing to the
fragmentation of standards compliance and compatibility issues.
  
  == HTTP cookies ==
  
      Cookie is a token or short packet of state information that the HTTP agent and the target
server can exchange to maintain a session. Netscape engineers used to refer to it as as a
"magic cookie" and the name stuck. 
      
-     HttpClient uses Cookie interface to represent an abstract cookie token. In its simples
form an HTTP cookie is merely a name / value pair. Usualy an HTTP cookie also contains a number
of attributes such as version, a domain for which is valid, a path that specifies the subset
of URLs on the origin server to which this cookie applies, and maximum period of time the
cookie is valid for.
+     HttpClient uses Cookie interface to represent an abstract cookie token. In its simples
form an HTTP cookie is merely a name / value pair. Usually an HTTP cookie also contains a
number of attributes such as version, a domain for which is valid, a path that specifies the
subset of URLs on the origin server to which this cookie applies, and maximum period of time
the cookie is valid for.
      
      SetCookie interface represents a {{{Set-Cookie}}} response header sent by the origin
server to the HTTP agent in order to maintain a conversational state. SetCookie2 interface
extends SetCookie with {{{Set-Cookie2}}} specific methods.
      
@@ -1203, +1203 @@

  
      * '''RFC 2965''': The official HTTP state management specification.
  
-     * '''Browser compatiblity''': this implementations strives to closely mimic (mis)behavior
of common web browser applications such as Microsoft Internet Explorer and Mozilla FireFox.
+     * '''Browser compatibility''': this implementations strives to closely mimic (mis)behavior
of common web browser applications such as Microsoft Internet Explorer and Mozilla FireFox.
  
      * '''Best match''':  'Meta' cookie specification that picks up a cookie policy based
on the format of cookies sent with the HTTP response. It basically aggregates all above implementations
into one class.
      
@@ -1223, +1223 @@

  
      HttpClient maintains a registry of available cookie specifications using CookieSpecRegistry
class. The following specifications are registered per default:
      
-     * '''compatibility''': Browser compatiblity (lenient policy).
+     * '''compatibility''': Browser compatibility (lenient policy).
  
      * '''netscape''': Netscape draft.
  
@@ -1251, +1251 @@

  
  == Custom cookie policy ==
  
-     In order to implement a custom cookie policy one should create a custom implementation
of CookieSpec interface, create a CookieSpecFactory implementation to create and inialize
instances of the custom specification and register the factory with HttpClient. Once the custom
specification has been registered, it can be activated the same way as the standard cookie
specifications.
+     In order to implement a custom cookie policy one should create a custom implementation
of CookieSpec interface, create a CookieSpecFactory implementation to create and initialize
instances of the custom specification and register the factory with HttpClient. Once the custom
specification has been registered, it can be activated the same way as the standard cookie
specifications.
  
  {{{
  CookieSpecFactory csf = new CookieSpecFactory() {
@@ -1260, +1260 @@

              @Override
              public void validate(Cookie cookie, CookieOrigin origin)
  	        throws MalformedCookieException {
- 	    // Oh, I am easy
+                 // Oh, I am easy
              }		
          };
      }	
@@ -1302, +1302 @@

      
      * '''http.cookie-store''' - CookieStore instance represents the actual cookie store.
The value of this attribute set in the local context takes precedence over the default one.
  
+     The local HttpContext object can be used to customize the HTTP state management context
prior to request execution or examine its state after the request has been executed:
+     
+ {{{
+ HttpClient httpclient = new DefaultHttpClient();
+ HttpContext localContext = new BasicHttpContext();
+ HttpGet httpget = new HttpGet("http://localhost:8080/"); 
+ HttpResponse response = httpclient.execute(httpget, localContext);
+ 
+ CookieOrigin cookieOrigin = (CookieOrigin) localContext.getAttribute(
+ 		ClientContext.COOKIE_ORIGIN);
+ System.out.println("Cookie origin: " + cookieOrigin);
+ CookieSpec cookieSpec = (CookieSpec) localContext.getAttribute(
+ 		ClientContext.COOKIE_SPEC);
+ System.out.println("Cookie spec used: " + cookieSpec);
+ }}}    
+     
  === Per user / thread state management ===
      
      One can use an individual local execution context in order to implement per user / thread
state management. Cookie specification registry and cookie store defined in the local context
will take precedence over the default ones set at the HTTP client level.
@@ -1359, +1375 @@

  
      * Parse and process the challenge sent by the target server in response to request for
a protected resource.
   
-     * Provide properties of the processed challenge: the authentication scheme type and
its parameters, such the realm this authentication scheme is applicable to, if avaialble
+     * Provide properties of the processed challenge: the authentication scheme type and
its parameters, such the realm this authentication scheme is applicable to, if available
      
      * Generate authorization string for the given set of credentials and the HTTP request
in response to the actual authorization challenge.
  
@@ -1387, +1403 @@

  
      * '''Digest''': Digest authentication scheme.
          
-     NTLM scheme is not registered per default. 
+     NTLM scheme is not registered per default. For details on how to enable NTLM support
please refer to the NTLM_SUPPORT.txt document included with HttpClient distributions.
+ 
+ == Credentials provider ==
+     
+     Credentials providers are intended to maintain a set of user credentials and to be able
to produce user credentials for a particular authentication scope. Authentication scope consists
of a host name, a port number, a realm name and an authentication scheme name. When registering
credentials with the credentials provider one can provide a wild card (any host, any port,
any realm, any scheme) instead of a concrete attribute value. The credentials provider is
then expected to be able to find the closest match for a particular scope if the direct match
cannot be found. 
+     
+     HttpClient can work with any physical representation of a credentials provider that
implements the CredentialsProvider interface. The default CredentialsProvider implementation
called BasicCredentialsProvider is a simple, in-memory implementation backed by a java.util.HashMap.
+ 
+ {{{
+ CredentialsProvider credsProvider = new BasicCredentialsProvider();
+ credsProvider.setCredentials(
+ 		new AuthScope("somehost", AuthScope.ANY_PORT), 
+ 		new UsernamePasswordCredentials("u1", "p1"));
+ credsProvider.setCredentials(
+ 		new AuthScope("somehost", 8080), 
+ 		new UsernamePasswordCredentials("u2", "p2"));
+ credsProvider.setCredentials(
+ 		new AuthScope("otherhost", 8080, AuthScope.ANY_REALM, "ntlm"), 
+ 		new UsernamePasswordCredentials("u3", "p3"));
+ 
+ System.out.println(credsProvider.getCredentials(
+ 		new AuthScope("somehost", 80, "realm", "basic")));
+ System.out.println(credsProvider.getCredentials(
+ 		new AuthScope("somehost", 8080, "realm", "basic")));
+ System.out.println(credsProvider.getCredentials(
+ 		new AuthScope("otherhost", 8080, "realm", "basic")));
+ System.out.println(credsProvider.getCredentials(
+ 		new AuthScope("otherhost", 8080, null, "ntlm")));
+ }}}
+ 
+ stdout>
+ {{{
+ [principal: u1]
+ [principal: u2]
+ null
+ [principal: u3]
+ }}}
+ 
+ == HTTP authentication and execution context ==
+ 
+     HttpClient relies on the AuthState class to keep track of detailed information about
the state of the authentication process. HttpClient creates two instances of AuthState in
the course of HTTP request execution: one for target host authentication and another one for
proxy authentication. In case the target server or the proxy require user authentication the
respective AuthScope instance will be populated with the AuthScope, AuthScheme and Crednetials
used during the authentication process. The AuthState can be examined in order to find out
what kind of authentication was requested, whether a matching AuthScheme implementation was
found and whether the credentials provider managed to find user credentials for the given
authentication scope.
+ 
+     In the course of HTTP request execution HttpClient adds the following authentication
related objects to the execution context: 
+ 
+     * '''http.authscheme-registry''' - AuthSchemeRegistry instance representing the actual
authentication scheme registry. The value of this attribute set in the local context takes
precedence over the default one.
+ 
+     * '''http.auth.credentials-provider''' - CookieSpec instance representing the actual
credentials provider. The value of this attribute set in the local context takes precedence
over the default one.
+     
+     * '''http.auth.target-scope''' - AuthState instance representing the actual target authentication
state. The value of this attribute set in the local context takes precedence over the default
one.
+     
+     * '''http.auth.proxy-scope''' - AuthState instance representing the actual proxy authentication
state. The value of this attribute set in the local context takes precedence over the default
one.
+     
+     The local HttpContext object can be used to customize the HTTP authentication context
prior to request execution or examine its state after the request has been executed:
+     
+ {{{
+ HttpClient httpclient = new DefaultHttpClient();
+ HttpContext localContext = new BasicHttpContext();
+ HttpGet httpget = new HttpGet("http://localhost:8080/"); 
+ HttpResponse response = httpclient.execute(httpget, localContext);
+ 
+ AuthState proxyAuthState = (AuthState) localContext.getAttribute(
+ 		ClientContext.PROXY_AUTH_STATE);
+ System.out.println("Proxy auth scope: " + proxyAuthState.getAuthScope());
+ System.out.println("Proxy auth scheme: " + proxyAuthState.getAuthScheme());
+ System.out.println("Proxy auth credentials: " + proxyAuthState.getCredentials());
+ AuthState targetAuthState = (AuthState) localContext.getAttribute(
+ 		ClientContext.TARGET_AUTH_STATE);
+ System.out.println("Target auth scope: " + targetAuthState.getAuthScope());
+ System.out.println("Target auth scheme: " + targetAuthState.getAuthScheme());
+ System.out.println("Target auth credentials: " + targetAuthState.getCredentials());
+ }}}    
+     
+ === Preemptive authentication ===
+ 
+     HttpClient does not support preemptive authentication out of the box, because if misused
or used incorrectly the preemptive authentication can lead to significant security issues,
such as sending user credentials in clear text to an unauthorized third party. Therefore,
users are expected to evaluate potential benefits of preemptive authentication versus security
risks in the context of their specific application environment and are required to add support
for preemptive authentication using standard HttpClient extension mechanisms such as protocol
interceptors.
+     
+     This is an example of a simple protocol interceptor that preemptively introduces an
instance of BasicScheme to the execution context, if no authentication has been attempted
yet. Please note that this interceptor must be added to the protocol processing chain before
the standard authentication interceptors.
+     
+ {{{
+ HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() {
+ 	
+     public void process(
+             final HttpRequest request, 
+             final HttpContext context) throws HttpException, IOException {
          
- == Choosing authetication policy ==
+         AuthState authState = (AuthState) context.getAttribute(
+                 ClientContext.TARGET_AUTH_STATE);
+         CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(
+                 ClientContext.CREDS_PROVIDER);
+         HttpHost targetHost = (HttpHost) context.getAttribute(
+                 ExecutionContext.HTTP_TARGET_HOST);
+         
+         // If not auth scheme has been initialized yet
+         if (authState.getAuthScheme() == null) {
+             AuthScope authScope = new AuthScope(
+             		targetHost.getHostName(), 
+             		targetHost.getPort());
+             // Obtain credentials matching the target host
+             Credentials creds = credsProvider.getCredentials(authScope);
+             // If found, generate BasicScheme preemptively
+             if (creds != null) {
+                 authState.setAuthScheme(new BasicScheme());
+                 authState.setCredentials(creds);
+             }
+         }
+     }
+ 	
+ };
  
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ // Add as the very first interceptor in the protocol chain
+ httpclient.addRequestInterceptor(preemptiveAuth, 0);
+ }}}
+     
-   HTTP client level authetication policy can be overriden on the HTTP request level if required.
- 
- == Authentication handling ==
- 
-   Custom authentication handling.
- 
- == Preemptive authetication ==
- 
-   Must be used with care. Requires custom protocol interceptors. 
- 
  = Redirect handling =
  
    Redirects are handled automatically, except those explicitly prohibited by the HTTP spec.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Mime
View raw message