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: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to