mirror of
https://github.com/apache/httpcomponents-client.git
synced 2025-02-13 13:35:54 +00:00
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1652164 13f79535-47bb-0310-9956-ffa450edef68
290 lines
15 KiB
XML
290 lines
15 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
|
<!--
|
|
====================================================================
|
|
Licensed to the Apache Software Foundation (ASF) under one
|
|
or more contributor license agreements. See the NOTICE file
|
|
distributed with this work for additional information
|
|
regarding copyright ownership. The ASF licenses this file
|
|
to you under the Apache License, Version 2.0 (the
|
|
"License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing,
|
|
software distributed under the License is distributed on an
|
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
KIND, either express or implied. See the License for the
|
|
specific language governing permissions and limitations
|
|
under the License.
|
|
====================================================================
|
|
-->
|
|
<chapter id="statemgmt">
|
|
<title>HTTP state management</title>
|
|
<para>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.</para>
|
|
<para>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.</para>
|
|
<section>
|
|
<title>HTTP cookies</title>
|
|
<para>An HTTP 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 a "magic cookie" and the name stuck.</para>
|
|
<para>HttpClient uses the <interfacename>Cookie</interfacename> interface to represent an
|
|
abstract cookie token. In its simplest form an HTTP cookie is merely a name / value pair.
|
|
Usually an HTTP cookie also contains a number of attributes such a domain for which is
|
|
valid, a path that specifies the subset of URLs on the origin server to which this
|
|
cookie applies, and the maximum period of time for which the cookie is valid.</para>
|
|
<para>The <interfacename>SetCookie</interfacename> interface represents a
|
|
<literal>Set-Cookie</literal> response header sent by the origin server to the HTTP
|
|
agent in order to maintain a conversational state.</para>
|
|
<para>The <interfacename>ClientCookie</interfacename> interface extends <interfacename>
|
|
Cookie</interfacename> interface with additional client specific functionality such
|
|
as the ability to retrieve original cookie attributes exactly as they were specified
|
|
by the origin server. This is important for generating the <literal>Cookie</literal>
|
|
header because some cookie specifications require that the <literal>Cookie</literal>
|
|
header should include certain attributes only if they were specified in the
|
|
<literal>Set-Cookie</literal> header.</para>
|
|
<para>Here is an example of creating a client-side cookie object:</para>
|
|
<programlisting><![CDATA[
|
|
BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
|
// Set effective domain and path attributes
|
|
cookie.setDomain(".mycompany.com");
|
|
cookie.setPath("/");
|
|
// Set attributes exactly as sent by the server
|
|
cookie.setAttribute(ClientCookie.PATH_ATTR, "/");
|
|
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, ".mycompany.com");
|
|
]]></programlisting>
|
|
</section>
|
|
<section>
|
|
<title>Cookie specifications</title>
|
|
<para>The <interfacename>CookieSpec</interfacename> interface represents a cookie management
|
|
specification. The cookie management specification is expected to enforce:</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>rules of parsing <literal>Set-Cookie</literal> headers.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>rules of validation of parsed cookies.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>formatting of <literal>Cookie</literal> header for a given host, port and path
|
|
of origin.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<para>HttpClient ships with several <interfacename>CookieSpec</interfacename>
|
|
implementations:</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<formalpara>
|
|
<title>Standard strict:</title>
|
|
<para>State management policy compliant with the syntax and semantics of
|
|
the well-behaved profile defined by RFC 6265, section 4.</para>
|
|
</formalpara>
|
|
</listitem>
|
|
<listitem>
|
|
<formalpara>
|
|
<title>Standard:</title>
|
|
<para>State management policy compliant with a more relaxed profile defined
|
|
by RFC 6265, section 4 intended for interoperability with existing servers
|
|
that do not conform to the well behaved profile.</para>
|
|
</formalpara>
|
|
</listitem>
|
|
<listitem>
|
|
<formalpara>
|
|
<title>Netscape draft (obsolete):</title>
|
|
<para>This policy conforms to the original draft specification published
|
|
by Netscape Communications. It should be avoided unless absolutely necessary
|
|
for compatibility with legacy code.</para>
|
|
</formalpara>
|
|
</listitem>
|
|
<listitem>
|
|
<formalpara>
|
|
<title>RFC 2965 (obsolete):</title>
|
|
<para>State management policy compliant with the obsolete state management
|
|
specification defined by RFC 2965. Please do not use in new applications.
|
|
</para>
|
|
</formalpara>
|
|
</listitem>
|
|
<listitem>
|
|
<formalpara>
|
|
<title>RFC 2109 (obsolete):</title>
|
|
<para>State management policy compliant with the obsolete state management
|
|
specification defined by RFC 2109. Please do not use in new applications.
|
|
</para>
|
|
</formalpara>
|
|
</listitem>
|
|
<listitem>
|
|
<formalpara>
|
|
<title>Browser compatibility (obsolete):</title>
|
|
<para>This policy strives to closely mimic the (mis)behavior of older versions
|
|
of browser applications such as Microsoft Internet Explorer and Mozilla
|
|
FireFox. Please do not use in new applications.</para>
|
|
</formalpara>
|
|
</listitem>
|
|
<listitem>
|
|
<formalpara>
|
|
<title>Default:</title>
|
|
<para>Default cookie policy is a synthetic policy that picks up either RFC 2965,
|
|
RFC 2109 or Netscape draft compliant implementation based on properties of
|
|
cookies sent with the HTTP response (such as version attribute,
|
|
now obsolete). This policy will be deprecated in favor of the
|
|
standard (RFC 6265 compliant) implementation in the next minor release
|
|
of HttpClient.</para>
|
|
</formalpara>
|
|
</listitem>
|
|
<listitem>
|
|
<formalpara>
|
|
<title>Ignore cookies:</title>
|
|
<para>All cookies are ignored.</para>
|
|
</formalpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<para>It is strongly recommended to use either <literal>Standard</literal> or
|
|
<literal>Standard strict</literal> policy in new applications. Obsolete specifications
|
|
should be used for compatibility with legacy systems only. Support for obsolete
|
|
specifications will be removed in the next major release of HttpClient.
|
|
</para>
|
|
</section>
|
|
<section>
|
|
<title>Choosing cookie policy</title>
|
|
<para>Cookie policy can be set at the HTTP client and overridden on the HTTP request level
|
|
if required.</para>
|
|
<programlisting><![CDATA[
|
|
RequestConfig globalConfig = RequestConfig.custom()
|
|
.setCookieSpec(CookieSpecs.DEFAULT)
|
|
.build();
|
|
CloseableHttpClient httpclient = HttpClients.custom()
|
|
.setDefaultRequestConfig(globalConfig)
|
|
.build();
|
|
RequestConfig localConfig = RequestConfig.copy(globalConfig)
|
|
.setCookieSpec(CookieSpecs.STANDARD_STRICT)
|
|
.build();
|
|
HttpGet httpGet = new HttpGet("/");
|
|
httpGet.setConfig(localConfig);
|
|
]]></programlisting>
|
|
</section>
|
|
<section>
|
|
<title>Custom cookie policy</title>
|
|
<para>In order to implement a custom cookie policy one should create a custom implementation
|
|
of the <interfacename>CookieSpec</interfacename> interface, create a
|
|
<interfacename>CookieSpecProvider</interfacename> 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 a standard cookie specification.</para>
|
|
<programlisting><![CDATA[
|
|
PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.getDefault();
|
|
|
|
Registry<CookieSpecProvider> r = RegistryBuilder.<CookieSpecProvider>create()
|
|
.register(CookieSpecs.DEFAULT,
|
|
new DefaultCookieSpecProvider(publicSuffixMatcher))
|
|
.register(CookieSpecs.STANDARD,
|
|
new RFC6265CookieSpecProvider(publicSuffixMatcher))
|
|
.register("easy", new EasySpecProvider())
|
|
.build();
|
|
|
|
RequestConfig requestConfig = RequestConfig.custom()
|
|
.setCookieSpec("easy")
|
|
.build();
|
|
|
|
CloseableHttpClient httpclient = HttpClients.custom()
|
|
.setDefaultCookieSpecRegistry(r)
|
|
.setDefaultRequestConfig(requestConfig)
|
|
.build();
|
|
]]></programlisting>
|
|
</section>
|
|
<section>
|
|
<title>Cookie persistence</title>
|
|
<para>HttpClient can work with any physical representation of a persistent cookie store that
|
|
implements the <interfacename>CookieStore</interfacename> interface. The default
|
|
<interfacename>CookieStore</interfacename> implementation called
|
|
<classname>BasicCookieStore</classname> is a simple implementation backed by a
|
|
<classname>java.util.ArrayList</classname>. Cookies stored in an
|
|
<classname>BasicClientCookie</classname> object are lost when the container object
|
|
get garbage collected. Users can provide more complex implementations if
|
|
necessary.</para>
|
|
<programlisting><![CDATA[
|
|
// Create a local instance of cookie store
|
|
CookieStore cookieStore = new BasicCookieStore();
|
|
// Populate cookies if needed
|
|
BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
|
cookie.setDomain(".mycompany.com");
|
|
cookie.setPath("/");
|
|
cookieStore.addCookie(cookie);
|
|
// Set the store
|
|
CloseableHttpClient httpclient = HttpClients.custom()
|
|
.setDefaultCookieStore(cookieStore)
|
|
.build();
|
|
]]></programlisting>
|
|
</section>
|
|
<section>
|
|
<title>HTTP state management and execution context</title>
|
|
<para>In the course of HTTP request execution HttpClient adds the following state management
|
|
related objects to the execution context:</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<formalpara>
|
|
<para><interfacename>Lookup</interfacename> instance representing the actual
|
|
cookie specification registry. The value of this attribute set in the local
|
|
context takes precedence over the default one.</para>
|
|
</formalpara>
|
|
</listitem>
|
|
<listitem>
|
|
<formalpara>
|
|
<para><interfacename>CookieSpec</interfacename> instance representing the actual
|
|
cookie specification.</para>
|
|
</formalpara>
|
|
</listitem>
|
|
<listitem>
|
|
<formalpara>
|
|
<para><classname>CookieOrigin</classname> instance representing the actual
|
|
details of the origin server.</para>
|
|
</formalpara>
|
|
</listitem>
|
|
<listitem>
|
|
<formalpara>
|
|
<para><interfacename>CookieStore</interfacename> instance representing the actual
|
|
cookie store. The value of this attribute set in the local context takes
|
|
precedence over the default one.</para>
|
|
</formalpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<para>The local <interfacename>HttpContext</interfacename> object can be used to customize
|
|
the HTTP state management context prior to request execution, or to examine its state after
|
|
the request has been executed. One can also use separate execution contexts in order
|
|
to implement per user (or per thread) state management. A cookie specification registry
|
|
and cookie store defined in the local context will take precedence over the default
|
|
ones set at the HTTP client level</para>
|
|
<programlisting><![CDATA[
|
|
CloseableHttpClient httpclient = <...>
|
|
|
|
Lookup<CookieSpecProvider> cookieSpecReg = <...>
|
|
CookieStore cookieStore = <...>
|
|
|
|
HttpClientContext context = HttpClientContext.create();
|
|
context.setCookieSpecRegistry(cookieSpecReg);
|
|
context.setCookieStore(cookieStore);
|
|
HttpGet httpget = new HttpGet("http://somehost/");
|
|
CloseableHttpResponse response1 = httpclient.execute(httpget, context);
|
|
<...>
|
|
// Cookie origin details
|
|
CookieOrigin cookieOrigin = context.getCookieOrigin();
|
|
// Cookie spec used
|
|
CookieSpec cookieSpec = context.getCookieSpec();
|
|
]]></programlisting>
|
|
</section>
|
|
</chapter>
|