Updated HttpClient tutorial for 4.4 release

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1652164 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2015-01-15 16:28:53 +00:00
parent 939c69d378
commit 1e50e40854
3 changed files with 115 additions and 125 deletions

View File

@ -281,11 +281,11 @@ static class GetThread extends Thread {
<para>HttpClient tries to mitigate the problem by testing whether the connection is 'stale',
that is no longer valid because it was closed on the server side, prior to using the
connection for executing an HTTP request. The stale connection check is not 100%
reliable and adds 10 to 30 ms overhead to each request execution. The only feasible
solution that does not involve a one thread per socket model for idle connections is a
dedicated monitor thread used to evict connections that are considered expired due to a
long period of inactivity. The monitor thread can periodically call
<methodname>ClientConnectionManager#closeExpiredConnections()</methodname> method to
reliable. The only feasible solution that does not involve a one thread per socket
model for idle connections is a dedicated monitor thread used to evict connections
that are considered expired due to a long period of inactivity. The monitor thread can
periodically call
<methodname>ClientConnectionManager#closeExpiredConnections()</methodname> method to
close all expired connections and evict closed connections from the pool. It can also
optionally call <methodname>ClientConnectionManager#closeIdleConnections()</methodname>
method to close all connections that have been idle over a given period of time.</para>
@ -457,58 +457,66 @@ SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
hostname matches the names stored inside the server's X.509 certificate, once the
connection has been established. This verification can provide additional guarantees
of authenticity of the server trust material.
The <interfacename>X509HostnameVerifier</interfacename> interface
represents a strategy for hostname verification. HttpClient ships with three
<interfacename>X509HostnameVerifier</interfacename> implementations.
The <interfacename>javax.net.ssl.HostnameVerifier</interfacename> interface
represents a strategy for hostname verification. HttpClient ships with two
<interfacename>javax.net.ssl.HostnameVerifier</interfacename> implementations.
Important: hostname verification should not be confused with
SSL trust verification.</para>
<itemizedlist>
<listitem>
<formalpara>
<title><classname>StrictHostnameVerifier</classname>:</title>
<para>The strict hostname verifier works the same way as Sun Java 1.4, Sun
Java 5, Sun Java 6. It's also pretty close to IE6. This implementation
appears to be compliant with RFC 2818 for dealing with wildcards. The
hostname must match either the first CN, or any of the subject-alts. A
<title><classname>DefaultHostnameVerifier</classname>:</title>
<para>The default implementation used by HttpClient is expected to be
compliant with RFC 2818. The hostname must match any of alternative
names specified by the certificate, or in case no alternative
names are given the most specific CN of the certificate subject. A
wildcard can occur in the CN, and in any of the subject-alts.</para>
</formalpara>
</listitem>
<listitem>
<formalpara>
<title><classname>BrowserCompatHostnameVerifier</classname>:</title>
<para>This hostname verifier that works the same way as Curl and Firefox. The
hostname must match either the first CN, or any of the subject-alts. A
wildcard can occur in the CN, and in any of the subject-alts. The only
difference between <classname>BrowserCompatHostnameVerifier</classname>
and <classname>StrictHostnameVerifier</classname> is that a wildcard
(such as "*.foo.com") with
<classname>BrowserCompatHostnameVerifier</classname> matches all
subdomains, including "a.b.foo.com".</para>
</formalpara>
</listitem>
<listitem>
<formalpara>
<title><classname>AllowAllHostnameVerifier</classname>:</title>
<title><classname>NoopHostnameVerifier</classname>:</title>
<para>This hostname verifier essentially turns hostname verification off.
This implementation is a no-op, and never throws
<exceptionname>javax.net.ssl.SSLException</exceptionname>.</para>
It accepts any SSL session as valid and matching the target host.
</para>
</formalpara>
</listitem>
</itemizedlist>
<para>Per default HttpClient uses the <classname>BrowserCompatHostnameVerifier</classname>
<para>Per default HttpClient uses the <classname>DefaultHostnameVerifier</classname>
implementation. One can specify a different hostname verifier implementation if
desired</para>
<programlisting><![CDATA[
SSLContext sslContext = SSLContexts.createSystemDefault();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext,
SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);
NoopHostnameVerifier.INSTANCE);
]]></programlisting>
<para>As of version 4.4 HttpClient makes use the public suffix list kindly maintained
by Mozilla Foundation to make sure that wildcards in SSL certificates cannot be
misused to apply to multiple domains with a common top-level domain. HttpClient
ships with a copy of the list retrieved at the time of the release. The latest
revision of the list can found at
<ulink url="https://publicsuffix.org/list/effective_tld_names.dat">
https://publicsuffix.org/list/</ulink>. It is highly adviseable to make a local
copy of the lsit and download the list no more than once per day from its original
location.
</para>
<programlisting><![CDATA[
PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.load(
PublicSuffixMatcher.class.getResource("my-copy-effective_tld_names.dat"));
DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher);
]]></programlisting>
<para>One can disable verification against the public suffic list by using
<code>null</code> matcher.
</para>
<programlisting><![CDATA[
DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(null);
]]></programlisting>
</section>
</section>
<section>
<title>HttpClient proxy configuration</title>
<para>Even though HttpClient is aware of complex routing scemes and proxy chaining, it
<para>Even though HttpClient is aware of complex routing schemes and proxy chaining, it
supports only simple direct or one hop proxy connections out of the box.</para>
<para>The simplest way to tell HttpClient to connect to the target host via a proxy is by
setting the default proxy parameter:</para>

View File

@ -71,7 +71,7 @@
HttpClient is NOT a browser. It is a client side HTTP transport library.
HttpClient's purpose is to transmit and receive HTTP messages. HttpClient will not
attempt to process content, execute javascript embedded in HTML pages, try to guess
content type, if not explicitly set, or reformat request / redirect location URIs,
content type, if not explicitly set, or reformat request / rewrite location URIs,
or other functionality unrelated to the HTTP transport.
</para>
</listitem>

View File

@ -45,63 +45,29 @@
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 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 the maximum period of time for which the cookie is valid.</para>
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.
The <interfacename>SetCookie2</interfacename> interface extends SetCookie with
<literal>Set-Cookie2</literal> specific methods.</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> or <literal>Set-Cookie2</literal>
header.</para>
<section>
<title>Cookie versions</title>
<para>Cookies compatible with Netscape draft specification but non-compliant with the
official specification are considered to be of version 0. Standard compliant cookies
are expected to have version 1. HttpClient may handle cookies differently depending
on the version.</para>
<para>Here is an example of re-creating a Netscape cookie:</para>
<programlisting><![CDATA[
BasicClientCookie netscapeCookie = new BasicClientCookie("name", "value");
netscapeCookie.setVersion(0);
netscapeCookie.setDomain(".mycompany.com");
netscapeCookie.setPath("/");
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>
<para>Here is an example of re-creating a standard cookie. Please note that standard
compliant cookie must retain all attributes as sent by the origin server:</para>
<programlisting><![CDATA[
BasicClientCookie stdCookie = new BasicClientCookie("name", "value");
stdCookie.setVersion(1);
stdCookie.setDomain(".mycompany.com");
stdCookie.setPath("/");
stdCookie.setSecure(true);
// Set attributes EXACTLY as sent by the server
stdCookie.setAttribute(ClientCookie.VERSION_ATTR, "1");
stdCookie.setAttribute(ClientCookie.DOMAIN_ATTR, ".mycompany.com");
]]></programlisting>
<para>Here is an example of re-creating a <literal>Set-Cookie2</literal> compliant
cookie. Please note that standard compliant cookie must retain all attributes as
sent by the origin server:</para>
<programlisting><![CDATA[
BasicClientCookie2 stdCookie = new BasicClientCookie2("name", "value");
stdCookie.setVersion(1);
stdCookie.setDomain(".mycompany.com");
stdCookie.setPorts(new int[] {80,8080});
stdCookie.setPath("/");
stdCookie.setSecure(true);
// Set attributes EXACTLY as sent by the server
stdCookie.setAttribute(ClientCookie.VERSION_ATTR, "1");
stdCookie.setAttribute(ClientCookie.DOMAIN_ATTR, ".mycompany.com");
stdCookie.setAttribute(ClientCookie.PORT_ATTR, "80,8080");
]]></programlisting>
</section>
</section>
<section>
<title>Cookie specifications</title>
@ -109,8 +75,7 @@ stdCookie.setAttribute(ClientCookie.PORT_ATTR, "80,8080");
specification. The cookie management specification is expected to enforce:</para>
<itemizedlist>
<listitem>
<para>rules of parsing <literal>Set-Cookie</literal> and optionally
<literal>Set-Cookie2</literal> headers.</para>
<para>rules of parsing <literal>Set-Cookie</literal> headers.</para>
</listitem>
<listitem>
<para>rules of validation of parsed cookies.</para>
@ -125,32 +90,60 @@ stdCookie.setAttribute(ClientCookie.PORT_ATTR, "80,8080");
<itemizedlist>
<listitem>
<formalpara>
<title>Netscape draft:</title>
<para>This specification conforms to the original draft specification published
<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>Standard:</title>
<para>RFC 2965 HTTP state management specification.</para>
<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>Browser compatibility:</title>
<para>This implementation strives to closely mimic the (mis)behavior of common web
browser applications such as Microsoft Internet Explorer and Mozilla
FireFox.</para>
<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>Best match:</title>
<para>'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.</para>
<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>
@ -160,9 +153,11 @@ stdCookie.setAttribute(ClientCookie.PORT_ATTR, "80,8080");
</formalpara>
</listitem>
</itemizedlist>
<para>It is strongly recommended to use the <literal>Best Match</literal> policy and let
HttpClient pick up an appropriate compliance level at runtime based on the execution
context.</para>
<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>
@ -170,13 +165,13 @@ stdCookie.setAttribute(ClientCookie.PORT_ATTR, "80,8080");
if required.</para>
<programlisting><![CDATA[
RequestConfig globalConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.BEST_MATCH)
.setCookieSpec(CookieSpecs.DEFAULT)
.build();
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultRequestConfig(globalConfig)
.build();
RequestConfig localConfig = RequestConfig.copy(globalConfig)
.setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY)
.setCookieSpec(CookieSpecs.STANDARD_STRICT)
.build();
HttpGet httpGet = new HttpGet("/");
httpGet.setConfig(localConfig);
@ -191,26 +186,14 @@ httpGet.setConfig(localConfig);
HttpClient. Once the custom specification has been registered, it can be activated the
same way as a standard cookie specification.</para>
<programlisting><![CDATA[
CookieSpecProvider easySpecProvider = new CookieSpecProvider() {
PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.getDefault();
public CookieSpec create(HttpContext context) {
return new BrowserCompatSpec() {
@Override
public void validate(Cookie cookie, CookieOrigin origin)
throws MalformedCookieException {
// Oh, I am easy
}
};
}
};
Registry<CookieSpecProvider> r = RegistryBuilder.<CookieSpecProvider>create()
.register(CookieSpecs.BEST_MATCH,
new BestMatchSpecFactory())
.register(CookieSpecs.BROWSER_COMPATIBILITY,
new BrowserCompatSpecFactory())
.register("easy", easySpecProvider)
.register(CookieSpecs.DEFAULT,
new DefaultCookieSpecProvider(publicSuffixMatcher))
.register(CookieSpecs.STANDARD,
new RFC6265CookieSpecProvider(publicSuffixMatcher))
.register("easy", new EasySpecProvider())
.build();
RequestConfig requestConfig = RequestConfig.custom()
@ -238,7 +221,6 @@ CloseableHttpClient httpclient = HttpClients.custom()
CookieStore cookieStore = new BasicCookieStore();
// Populate cookies if needed
BasicClientCookie cookie = new BasicClientCookie("name", "value");
cookie.setVersion(0);
cookie.setDomain(".mycompany.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);