blob: 03ee1954b419c4e338585e24498bbc60c4c2cf59 [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter&nbsp;1.&nbsp;Fundamentals</title><link rel="stylesheet" type="text/css" href="css/hc-tutorial.css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"><link rel="home" href="index.html" title="HttpCore Tutorial"><link rel="up" href="index.html" title="HttpCore Tutorial"><link rel="prev" href="preface.html" title="Preface"><link rel="next" href="nio.html" title="Chapter&nbsp;2.&nbsp;NIO extensions"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div xmlns:fo="http://www.w3.org/1999/XSL/Format" class="banner"><a class="bannerLeft" href="http://www.apache.org/" title="Apache Software Foundation"><img style="border:none;" src="images/asf_logo_wide.gif"></a><a class="bannerRight" href="http://hc.apache.org/httpcomponents-core-ga/" title="Apache HttpComponents Core"><img style="border:none;" src="images/hc_logo.png"></a><div class="clear"></div></div><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter&nbsp;1.&nbsp;Fundamentals</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="preface.html">Prev</a>&nbsp;</td><th width="60%" align="center">&nbsp;</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="nio.html">Next</a></td></tr></table><hr></div><div class="chapter" title="Chapter&nbsp;1.&nbsp;Fundamentals"><div class="titlepage"><div><div><h2 class="title"><a name="fundamentals"></a>Chapter&nbsp;1.&nbsp;Fundamentals</h2></div></div></div>
<div class="section" title="1.1.&nbsp;HTTP messages"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e48"></a>1.1.&nbsp;HTTP messages</h2></div></div></div>
<div class="section" title="1.1.1.&nbsp;Structure"><div class="titlepage"><div><div><h3 class="title"><a name="d5e50"></a>1.1.1.&nbsp;Structure</h3></div></div></div>
<p>
A HTTP message consists of a header and an optional body. The message header of an HTTP
request consists of a request line and a collection of header fields. The message header
of an HTTP response consists of a status line and a collection of header fields. All
HTTP messages must include the protocol version. Some HTTP messages can optionally
enclose a content body.
</p>
<p>
HttpCore defines the HTTP message object model to closely follow this definition and
provides extensive support for serialization (formatting) and deserialization
(parsing) of HTTP message elements.
</p>
</div>
<div class="section" title="1.1.2.&nbsp;Basic operations"><div class="titlepage"><div><div><h3 class="title"><a name="d5e54"></a>1.1.2.&nbsp;Basic operations</h3></div></div></div>
<div class="section" title="1.1.2.1.&nbsp;HTTP request message"><div class="titlepage"><div><div><h4 class="title"><a name="d5e56"></a>1.1.2.1.&nbsp;HTTP request message</h4></div></div></div>
<p>
HTTP request is a message sent from the client to the server. The first line of
that message includes the method to be applied to the resource, the identifier of
the resource, and the protocol version in use.
</p>
<pre class="programlisting">
HttpRequest request = new BasicHttpRequest("GET", "/",
HttpVersion.HTTP_1_1);
System.out.println(request.getRequestLine().getMethod());
System.out.println(request.getRequestLine().getUri());
System.out.println(request.getProtocolVersion());
System.out.println(request.getRequestLine().toString());
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
GET
/
HTTP/1.1
GET / HTTP/1.1
</pre>
</div>
<div class="section" title="1.1.2.2.&nbsp;HTTP response message"><div class="titlepage"><div><div><h4 class="title"><a name="d5e62"></a>1.1.2.2.&nbsp;HTTP response message</h4></div></div></div>
<p>
HTTP response is a message sent by the server back to the client after having
received and interpreted a request message. The first line of that message
consists of the protocol version followed by a numeric status code and its
associated textual phrase.
</p>
<pre class="programlisting">
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
System.out.println(response.getProtocolVersion());
System.out.println(response.getStatusLine().getStatusCode());
System.out.println(response.getStatusLine().getReasonPhrase());
System.out.println(response.getStatusLine().toString());
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
HTTP/1.1
200
OK
HTTP/1.1 200 OK
</pre>
</div>
<div class="section" title="1.1.2.3.&nbsp;HTTP message common properties and methods"><div class="titlepage"><div><div><h4 class="title"><a name="d5e68"></a>1.1.2.3.&nbsp;HTTP message common properties and methods</h4></div></div></div>
<p>
An HTTP message can contain a number of headers describing properties of the
message such as the content length, content type and so on. HttpCore provides
methods to retrieve, add, remove and enumerate such headers.
</p>
<pre class="programlisting">
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie",
"c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie",
"c2=b; path=\"/\", c3=c; domain=\"localhost\"");
Header h1 = response.getFirstHeader("Set-Cookie");
System.out.println(h1);
Header h2 = response.getLastHeader("Set-Cookie");
System.out.println(h2);
Header[] hs = response.getHeaders("Set-Cookie");
System.out.println(hs.length);
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
Set-Cookie: c1=a; path=/; domain=localhost
Set-Cookie: c2=b; path="/", c3=c; domain="localhost"
2
</pre>
<p>
There is an efficient way to obtain all headers of a given type using the
<code class="interfacename">HeaderIterator</code> interface.
</p>
<pre class="programlisting">
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie",
"c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie",
"c2=b; path=\"/\", c3=c; domain=\"localhost\"");
HeaderIterator it = response.headerIterator("Set-Cookie");
while (it.hasNext()) {
System.out.println(it.next());
}
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
Set-Cookie: c1=a; path=/; domain=localhost
Set-Cookie: c2=b; path="/", c3=c; domain="localhost"
</pre>
<p>
It also provides convenience methods to parse HTTP messages into individual
header elements.
</p>
<pre class="programlisting">
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie",
"c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie",
"c2=b; path=\"/\", c3=c; domain=\"localhost\"");
HeaderElementIterator it = new BasicHeaderElementIterator(
response.headerIterator("Set-Cookie"));
while (it.hasNext()) {
HeaderElement elem = it.nextElement();
System.out.println(elem.getName() + " = " + elem.getValue());
NameValuePair[] params = elem.getParameters();
for (int i = 0; i &lt; params.length; i++) {
System.out.println(" " + params[i]);
}
}
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
c1 = a
path=/
domain=localhost
c2 = b
path=/
c3 = c
domain=localhost
</pre>
<p>
HTTP headers get tokenized into individual header elements only on demand. HTTP
headers received over an HTTP connection are stored internally as an array of
characters and parsed lazily only when their properties are accessed.
</p>
</div>
</div>
<div class="section" title="1.1.3.&nbsp;HTTP entity"><div class="titlepage"><div><div><h3 class="title"><a name="d5e84"></a>1.1.3.&nbsp;HTTP entity</h3></div></div></div>
<p>
HTTP messages can carry a content entity associated with the request or response.
Entities can be found in some requests and in some responses, as they are optional.
Requests that use entities are referred to as entity enclosing requests. The HTTP
specification defines two entity enclosing methods: POST and PUT. Responses are
usually expected to enclose a content entity. There are exceptions to this rule such
as responses to HEAD method and 204 No Content, 304 Not Modified, 205 Reset Content
responses.
</p>
<p>
HttpCore distinguishes three kinds of entities, depending on where their content
originates:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p title="streamed:">
<b>streamed:&nbsp;</b>
The content is received from a stream, or generated on the fly. In particular,
this category includes entities being received from a connection. Streamed
entities are generally not repeatable.
</p>
</li><li class="listitem">
<p title="self-contained:">
<b>self-contained:&nbsp;</b>
The content is in memory or obtained by means that are independent from
a connection or other entity. Self-contained entities are generally repeatable.
</p>
</li><li class="listitem">
<p title="wrapping:">
<b>wrapping:&nbsp;</b>
The content is obtained from another entity.
</p>
</li></ul></div>
<p>
This distinction is important for connection management with incoming entities. For
entities that are created by an application and only sent using the HttpCore framework,
the difference between streamed and self-contained is of little importance. In that
case, it is suggested to consider non-repeatable entities as streamed, and those that
are repeatable as self-contained.
</p>
<div class="section" title="1.1.3.1.&nbsp;Repeatable entities"><div class="titlepage"><div><div><h4 class="title"><a name="d5e102"></a>1.1.3.1.&nbsp;Repeatable entities</h4></div></div></div>
<p>
An entity can be repeatable, meaning its content can be read more than once. This
is only possible with self contained entities (like
<code class="classname">ByteArrayEntity</code> or <code class="classname">StringEntity</code>).
</p>
</div>
<div class="section" title="1.1.3.2.&nbsp;Using HTTP entities"><div class="titlepage"><div><div><h4 class="title"><a name="d5e107"></a>1.1.3.2.&nbsp;Using HTTP entities</h4></div></div></div>
<p>
Since an entity can represent both binary and character content, it has support
for character encodings (to support the latter, ie. character content).
</p>
<p>
The entity is created when executing a request with enclosed content or when the
request was successful and the response body is used to send the result back to
the client.
</p>
<p>
To read the content from the entity, one can either retrieve the input stream via
the <code class="methodname">HttpEntity#getContent()</code> method, which returns an
<code class="classname">java.io.InputStream</code>, or one can supply an output stream to
the <code class="methodname">HttpEntity#writeTo(OutputStream)</code> method, which will
return once all content has been written to the given stream.
</p>
<p>
The <code class="classname">EntityUtils</code> class exposes several static methods to
more easily read the content or information from an entity. Instead of reading
the <code class="classname">java.io.InputStream</code> directly, one can retrieve the whole
content body in a string / byte array by using the methods from this class.
</p>
<p>
When the entity has been received with an incoming message, the methods
<code class="methodname">HttpEntity#getContentType()</code> and
<code class="methodname">HttpEntity#getContentLength()</code> methods can be used for
reading the common metadata such as <code class="literal">Content-Type</code> and
<code class="literal">Content-Length</code> headers (if they are available). Since the
<code class="literal">Content-Type</code> header can contain a character encoding for text
mime-types like <code class="literal">text/plain</code> or <code class="literal">text/html</code>,
the <code class="methodname">HttpEntity#getContentEncoding()</code> method is used to
read this information. If the headers aren't available, a length of -1 will be
returned, and <code class="literal">NULL</code> for the content type. If the
<code class="literal">Content-Type</code> header is available, a Header object will be
returned.
</p>
<p>
When creating an entity for a outgoing message, this meta data has to be supplied
by the creator of the entity.
</p>
<pre class="programlisting">
StringEntity myEntity = new StringEntity("important message",
"UTF-8");
System.out.println(myEntity.getContentType());
System.out.println(myEntity.getContentLength());
System.out.println(EntityUtils.getContentCharSet(myEntity));
System.out.println(EntityUtils.toString(myEntity));
System.out.println(EntityUtils.toByteArray(myEntity).length);
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
Content-Type: text/plain; charset=UTF-8
17
UTF-8
important message
17
</pre>
</div>
<div class="section" title="1.1.3.3.&nbsp;Ensuring release of system resources"><div class="titlepage"><div><div><h4 class="title"><a name="d5e133"></a>1.1.3.3.&nbsp;Ensuring release of system resources</h4></div></div></div>
<p>
In order to ensure proper release of system resources one must close the content
stream associated with the entity.
</p>
<pre class="programlisting">
HttpResponse response;
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
try {
// do something useful
} finally {
instream.close();
}
}
</pre>
<p>
Please note that <code class="methodname">HttpEntity#writeTo(OutputStream)</code>
method is also required to ensure proper release of system resources once the
entity has been fully written out. If this method obtains an instance of
<code class="classname">java.io.InputStream</code> by calling
<code class="methodname">HttpEntity#getContent()</code>, it is also expected to close
the stream in a finally clause.
</p>
<p>
When working with streaming entities, one can use the
<code class="methodname">EntityUtils#consume(HttpEntity)</code> method to ensure that
the entity content has been fully consumed and the underlying stream has been
closed.
</p>
</div>
</div>
<div class="section" title="1.1.4.&nbsp;Creating entities"><div class="titlepage"><div><div><h3 class="title"><a name="d5e143"></a>1.1.4.&nbsp;Creating entities</h3></div></div></div>
<p>
There are a few ways to create entities. The following implementations are provided
by HttpCore:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p>
<a class="link" href="fundamentals.html#basic-entity" title="1.1.4.1.&nbsp;BasicHttpEntity">
<code class="classname">BasicHttpEntity</code>
</a>
</p>
</li><li class="listitem">
<p>
<a class="link" href="fundamentals.html#byte-array-entity" title="1.1.4.2.&nbsp;ByteArrayEntity">
<code class="classname">ByteArrayEntity</code>
</a>
</p>
</li><li class="listitem">
<p>
<a class="link" href="fundamentals.html#string-entity" title="1.1.4.3.&nbsp;StringEntity">
<code class="classname">StringEntity</code>
</a>
</p>
</li><li class="listitem">
<p>
<a class="link" href="fundamentals.html#input-stream-entity" title="1.1.4.4.&nbsp;InputStreamEntity">
<code class="classname">InputStreamEntity</code>
</a>
</p>
</li><li class="listitem">
<p>
<a class="link" href="fundamentals.html#file-entity" title="1.1.4.5.&nbsp;FileEntity">
<code class="classname">FileEntity</code>
</a>
</p>
</li><li class="listitem">
<p>
<a class="link" href="">
<code class="classname">EntityTemplate</code>
</a>
</p>
</li><li class="listitem">
<p>
<a class="link" href="fundamentals.html#entity-wrapper" title="1.1.4.6.&nbsp;HttpEntityWrapper">
<code class="classname">HttpEntityWrapper</code>
</a>
</p>
</li><li class="listitem">
<p>
<a class="link" href="fundamentals.html#buffered-entity" title="1.1.4.7.&nbsp;BufferedHttpEntity">
<code class="classname">BufferedHttpEntity</code>
</a>
</p>
</li></ul></div>
<div class="section" title="1.1.4.1.&nbsp;BasicHttpEntity"><div class="titlepage"><div><div><h4 class="title"><a name="basic-entity"></a>1.1.4.1.&nbsp;<code class="classname">BasicHttpEntity</code></h4></div></div></div>
<p>
This is exactly as the name implies, a basic entity that represents an underlying
stream. This is generally used for the entities received from HTTP messages.
</p>
<p>
This entity has an empty constructor. After construction it represents no content,
and has a negative content length.
</p>
<p>
One needs to set the content stream, and optionally the length. This can be done
with the <code class="methodname">BasicHttpEntity#setContent(InputStream)</code> and
<code class="methodname">BasicHttpEntity#setContentLength(long)</code> methods
respectively.
</p>
<pre class="programlisting">
BasicHttpEntity myEntity = new BasicHttpEntity();
myEntity.setContent(someInputStream);
myEntity.setContentLength(340); // sets the length to 340
</pre>
</div>
<div class="section" title="1.1.4.2.&nbsp;ByteArrayEntity"><div class="titlepage"><div><div><h4 class="title"><a name="byte-array-entity"></a>1.1.4.2.&nbsp;<code class="classname">ByteArrayEntity</code></h4></div></div></div>
<p>
<code class="classname">ByteArrayEntity</code> is a self contained, repeatable entity
that obtains its content from a given byte array. This byte array is supplied
to the constructor.
</p>
<pre class="programlisting">
String myData = "Hello world on the other side!!";
ByteArrayEntity myEntity = new ByteArrayEntity(myData.getBytes());
</pre>
</div>
<div class="section" title="1.1.4.3.&nbsp;StringEntity"><div class="titlepage"><div><div><h4 class="title"><a name="string-entity"></a>1.1.4.3.&nbsp;<code class="classname">StringEntity</code></h4></div></div></div>
<p>
<code class="classname">StringEntity</code> is a self contained, repeatable entity that
obtains its content from a <code class="classname">java.lang.String</code> object. It has
three constructors, one simply constructs with a given <code class="classname">java.lang.String
</code> object; the second also takes a character encoding for the data in the
string; the third allows the mime type to be specified.
</p>
<pre class="programlisting">
StringBuilder sb = new StringBuilder();
Map&lt;String, String&gt; env = System.getenv();
for (Entry&lt;String, String&gt; envEntry : env.entrySet()) {
sb.append(envEntry.getKey()).append(": ")
.append(envEntry.getValue()).append("\n");
}
// construct without a character encoding (defaults to ISO-8859-1)
HttpEntity myEntity1 = new StringEntity(sb.toString());
// alternatively construct with an encoding (mime type defaults to "text/plain")
HttpEntity myEntity2 = new StringEntity(sb.toString(), "UTF-8");
// alternatively construct with an encoding and a mime type
HttpEntity myEntity3 = new StringEntity(sb.toString(), "text/html", "UTF-8");
</pre>
</div>
<div class="section" title="1.1.4.4.&nbsp;InputStreamEntity"><div class="titlepage"><div><div><h4 class="title"><a name="input-stream-entity"></a>1.1.4.4.&nbsp;<code class="classname">InputStreamEntity</code></h4></div></div></div>
<p>
<code class="classname">InputStreamEntity</code> is a streamed, non-repeatable entity that
obtains its content from an input stream. It is constructed by supplying the input
stream and the content length. The content length is used to limit the amount of
data read from the <code class="classname">java.io.InputStream</code>. If the length matches
the content length available on the input stream, then all data will be sent.
Alternatively a negative content length will read all data from the input stream,
which is the same as supplying the exact content length, so the length is most
often used to limit the length.
</p>
<pre class="programlisting">
InputStream instream = getSomeInputStream();
InputStreamEntity myEntity = new InputStreamEntity(instream, 16);
</pre>
</div>
<div class="section" title="1.1.4.5.&nbsp;FileEntity"><div class="titlepage"><div><div><h4 class="title"><a name="file-entity"></a>1.1.4.5.&nbsp;<code class="classname">FileEntity</code></h4></div></div></div>
<p>
<code class="classname">FileEntity</code> is a self contained, repeatable entity that
obtains its content from a file. Since this is mostly used to stream large files
of different types, one needs to supply the content type of the file, for
instance, sending a zip file would require the content type <code class="literal">
application/zip</code>, for XML <code class="literal">application/xml</code>.
</p>
<pre class="programlisting">
HttpEntity entity = new FileEntity(staticFile,
"application/java-archive");
</pre>
</div>
<div class="section" title="1.1.4.6.&nbsp;HttpEntityWrapper"><div class="titlepage"><div><div><h4 class="title"><a name="entity-wrapper"></a>1.1.4.6.&nbsp;<code class="classname">HttpEntityWrapper</code></h4></div></div></div>
<p>
This is the base class for creating wrapped entities. The wrapping entity holds
a reference to a wrapped entity and delegates all calls to it. Implementations
of wrapping entities can derive from this class and need to override only those
methods that should not be delegated to the wrapped entity.
</p>
</div>
<div class="section" title="1.1.4.7.&nbsp;BufferedHttpEntity"><div class="titlepage"><div><div><h4 class="title"><a name="buffered-entity"></a>1.1.4.7.&nbsp;<code class="classname">BufferedHttpEntity</code></h4></div></div></div>
<p>
<code class="classname">BufferedHttpEntity</code> is a subclass of <code class="classname">
HttpEntityWrapper</code>. It is constructed by supplying another entity. It
reads the content from the supplied entity, and buffers it in memory.
</p>
<p>
This makes it possible to make a repeatable entity, from a non-repeatable entity.
If the supplied entity is already repeatable, calls are simply passed through to the
underlying entity.
</p>
<pre class="programlisting">
myNonRepeatableEntity.setContent(someInputStream);
BufferedHttpEntity myBufferedEntity = new BufferedHttpEntity(
myNonRepeatableEntity);
</pre>
</div>
</div>
</div>
<div class="section" title="1.2.&nbsp;Blocking HTTP connections"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e229"></a>1.2.&nbsp;Blocking HTTP connections</h2></div></div></div>
<p>
HTTP connections are responsible for HTTP message serialization and deserialization. One
should rarely need to use HTTP connection objects directly. There are higher level protocol
components intended for execution and processing of HTTP requests. However, in some cases
direct interaction with HTTP connections may be necessary, for instance, to access
properties such as the connection status, the socket timeout or the local and remote
addresses.
</p>
<p>
It is important to bear in mind that HTTP connections are not thread-safe. It is strongly
recommended to limit all interactions with HTTP connection objects to one thread. The only
method of <code class="interfacename">HttpConnection</code> interface and its sub-interfaces
which is safe to invoke from another thread is <code class="methodname"> HttpConnection#shutdown()
</code>.
</p>
<div class="section" title="1.2.1.&nbsp;Working with blocking HTTP connections"><div class="titlepage"><div><div><h3 class="title"><a name="d5e235"></a>1.2.1.&nbsp;Working with blocking HTTP connections</h3></div></div></div>
<p>
HttpCore does not provide full support for opening connections because the process of
establishing a new connection - especially on the client side - can be very complex
when it involves one or more authenticating or/and tunneling proxies. Instead, blocking
HTTP connections can be bound to any arbitrary network socket.
</p>
<pre class="programlisting">
Socket socket = new Socket();
// Initialize socket
BasicHttpParams params = new BasicHttpParams();
DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
conn.bind(socket, params);
conn.isOpen();
HttpConnectionMetrics metrics = conn.getMetrics();
metrics.getRequestCount();
metrics.getResponseCount();
metrics.getReceivedBytesCount();
metrics.getSentBytesCount();
</pre>
<p>
HTTP connection interfaces, both client and server, send and receive messages in two
stages. The message head is transmitted first. Depending on properties of the message
head it may be followed by a message body. Please note it is very important to always
close the underlying content stream in order to signal that the processing of
the message is complete. HTTP entities that stream out their content directly from the
input stream of the underlying connection must ensure the content of the message body
is fully consumed for that connection to be potentially re-usable.
</p>
<p>
Over-simplified process of client side request execution may look like this:
</p>
<pre class="programlisting">
Socket socket = new Socket();
// Initialize socket
HttpParams params = new BasicHttpParams();
DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
conn.bind(socket, params);
HttpRequest request = new BasicHttpRequest("GET", "/");
conn.sendRequestHeader(request);
HttpResponse response = conn.receiveResponseHeader();
conn.receiveResponseEntity(response);
HttpEntity entity = response.getEntity();
if (entity != null) {
// Do something useful with the entity and, when done, ensure all
// content has been consumed, so that the underlying connection
// can be re-used
EntityUtils.consume(entity);
}
</pre>
<p>
Over-simplified process of server side request handling may look like this:
</p>
<pre class="programlisting">
Socket socket = new Socket();
// Initialize socket
HttpParams params = new BasicHttpParams();
DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
conn.bind(socket, params);
HttpRequest request = conn.receiveRequestHeader();
if (request instanceof HttpEntityEnclosingRequest) {
conn.receiveRequestEntity((HttpEntityEnclosingRequest) request);
HttpEntity entity = ((HttpEntityEnclosingRequest) request)
.getEntity();
if (entity != null) {
// Do something useful with the entity and, when done, ensure all
// content has been consumed, so that the underlying connection
// could be re-used
EntityUtils.consume(entity);
}
}
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
200, "OK");
response.setEntity(new StringEntity("Got it"));
conn.sendResponseHeader(response);
conn.sendResponseEntity(response);
</pre>
<p>
Please note that one should rarely need to transmit messages using these low level
methods and should normally use the appropriate higher level HTTP service implementations instead.
</p>
</div>
<div class="section" title="1.2.2.&nbsp;Content transfer with blocking I/O"><div class="titlepage"><div><div><h3 class="title"><a name="d5e245"></a>1.2.2.&nbsp;Content transfer with blocking I/O</h3></div></div></div>
<p>
HTTP connections manage the process of the content transfer using the <code class="interfacename">
HttpEntity</code> interface. HTTP connections generate an entity object that
encapsulates the content stream of the incoming message. Please note that <code class="methodname">
HttpServerConnection#receiveRequestEntity()</code> and <code class="methodname">
HttpClientConnection#receiveResponseEntity()</code> do not retrieve or buffer any
incoming data. They merely inject an appropriate content codec based on the properties
of the incoming message. The content can be retrieved by reading from the content input
stream of the enclosed entity using <code class="methodname">HttpEntity#getContent()</code>.
The incoming data will be decoded automatically, and completely transparently to the data
consumer. Likewise, HTTP connections rely on <code class="methodname">
HttpEntity#writeTo(OutputStream)</code> method to generate the content of an
outgoing message. If an outgoing messages encloses an entity, the content will be
encoded automatically based on the properties of the message.
</p>
</div>
<div class="section" title="1.2.3.&nbsp;Supported content transfer mechanisms"><div class="titlepage"><div><div><h3 class="title"><a name="d5e253"></a>1.2.3.&nbsp;Supported content transfer mechanisms</h3></div></div></div>
<p>
Default implementations of HTTP connections support three content transfer mechanisms
defined by the HTTP/1.1 specification:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p title="Content-Length delimited:">
<b><code class="literal">Content-Length</code> delimited:&nbsp;</b>
The end of the content entity is determined by the value of the <code class="literal">
Content-Length</code> header. Maximum entity length: <code class="methodname">
Long#MAX_VALUE</code>.
</p>
</li><li class="listitem">
<p title="Identity coding:">
<b>Identity coding:&nbsp;</b>
The end of the content entity is demarcated by closing the underlying
connection (end of stream condition). For obvious reasons the identity encoding
can only be used on the server side. Max entity length: unlimited.
</p>
</li><li class="listitem">
<p title="Chunk coding:">
<b>Chunk coding:&nbsp;</b>
The content is sent in small chunks. Max entity length: unlimited.
</p>
</li></ul></div>
<p>
The appropriate content stream class will be created automatically depending on
properties of the entity enclosed with the message.
</p>
</div>
<div class="section" title="1.2.4.&nbsp;Terminating HTTP connections"><div class="titlepage"><div><div><h3 class="title"><a name="d5e273"></a>1.2.4.&nbsp;Terminating HTTP connections</h3></div></div></div>
<p>
HTTP connections can be terminated either gracefully by calling <code class="methodname">
HttpConnection#close()</code> or forcibly by calling <code class="methodname">
HttpConnection#shutdown()</code>. The former tries to flush all buffered data
prior to terminating the connection and may block indefinitely. The <code class="methodname">
HttpConnection#close()</code> method is not thread-safe. The latter terminates
the connection without flushing internal buffers and returns control to the caller as
soon as possible without blocking for long. The <code class="methodname">HttpConnection#shutdown()
</code> method is thread-safe.
</p>
</div>
</div>
<div class="section" title="1.3.&nbsp;HTTP exception handling"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e280"></a>1.3.&nbsp;HTTP exception handling</h2></div></div></div>
<p>
All HttpCore components potentially throw two types of exceptions: <code class="classname">IOException
</code>in case of an I/O failure such as socket timeout or an socket reset and
<code class="classname">HttpException</code> that signals an HTTP failure such as a violation of
the HTTP protocol. Usually I/O errors are considered non-fatal and recoverable, whereas
HTTP protocol errors are considered fatal and cannot be automatically recovered from.
</p>
<div class="section" title="1.3.1.&nbsp;Protocol exception"><div class="titlepage"><div><div><h3 class="title"><a name="d5e285"></a>1.3.1.&nbsp;Protocol exception</h3></div></div></div>
<p>
<code class="classname">ProtocolException</code> signals a fatal HTTP protocol violation that
usually results in an immediate termination of the HTTP message processing.
</p>
</div>
</div>
<div class="section" title="1.4.&nbsp;HTTP protocol processors"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e289"></a>1.4.&nbsp;HTTP protocol processors</h2></div></div></div>
<p>
HTTP protocol interceptor is a routine that implements a specific aspect of the HTTP
protocol. Usually protocol interceptors are expected to act upon one specific header or a
group of related headers of the incoming message or populate the outgoing message with one
specific header or a group of related headers. Protocol interceptors can also manipulate
content entities enclosed with messages; transparent content compression / decompression
being a good example. Usually this is accomplished by using the 'Decorator' pattern where
a wrapper entity class is used to decorate the original entity. Several protocol
interceptors can be combined to form one logical unit.
</p>
<p>
HTTP protocol processor is a collection of protocol interceptors that implements the
'Chain of Responsibility' pattern, where each individual protocol interceptor is expected
to work on the particular aspect of the HTTP protocol it is responsible for.
</p>
<p>
Usually the order in which interceptors are executed should not matter as long as they do
not depend on a particular state of the execution context. If protocol interceptors have
interdependencies and therefore must be executed in a particular order, they should be
added to the protocol processor in the same sequence as their expected execution order.
</p>
<p>
Protocol interceptors must be implemented as thread-safe. Similarly to servlets, protocol
interceptors should not use instance variables unless access to those variables is
synchronized.
</p>
<div class="section" title="1.4.1.&nbsp;Standard protocol interceptors"><div class="titlepage"><div><div><h3 class="title"><a name="d5e295"></a>1.4.1.&nbsp;Standard protocol interceptors</h3></div></div></div>
<p>
HttpCore comes with a number of most essential protocol interceptors for client and
server HTTP processing.
</p>
<div class="section" title="1.4.1.1.&nbsp;RequestContent"><div class="titlepage"><div><div><h4 class="title"><a name="d5e298"></a>1.4.1.1.&nbsp;<code class="classname">RequestContent</code></h4></div></div></div>
<p>
<code class="classname">RequestContent</code> is the most important interceptor for
outgoing requests. It is responsible for delimiting content length by adding
the <code class="literal">Content-Length</code> or <code class="literal">Transfer-Content</code> headers
based on the properties of the enclosed entity and the protocol version. This
interceptor is required for correct functioning of client side protocol processors.
</p>
</div>
<div class="section" title="1.4.1.2.&nbsp;ResponseContent"><div class="titlepage"><div><div><h4 class="title"><a name="d5e305"></a>1.4.1.2.&nbsp;<code class="classname">ResponseContent</code></h4></div></div></div>
<p>
<code class="classname">ResponseContent</code> is the most important interceptor for
outgoing responses. It is responsible for delimiting content length by adding
<code class="literal">Content-Length</code> or <code class="literal">Transfer-Content</code> headers
based on the properties of the enclosed entity and the protocol version. This
interceptor is required for correct functioning of server side protocol processors.
</p>
</div>
<div class="section" title="1.4.1.3.&nbsp;RequestConnControl"><div class="titlepage"><div><div><h4 class="title"><a name="d5e312"></a>1.4.1.3.&nbsp;<code class="classname">RequestConnControl</code></h4></div></div></div>
<p>
<code class="classname">RequestConnControl</code> is responsible for adding the
<code class="literal">Connection</code> header to the outgoing requests, which is essential
for managing persistence of <code class="literal">HTTP/1.0</code> connections. This
interceptor is recommended for client side protocol processors.
</p>
</div>
<div class="section" title="1.4.1.4.&nbsp;ResponseConnControl"><div class="titlepage"><div><div><h4 class="title"><a name="d5e319"></a>1.4.1.4.&nbsp;<code class="classname">ResponseConnControl</code></h4></div></div></div>
<p>
<code class="classname">ResponseConnControl</code> is responsible for adding
the <code class="literal">Connection</code> header to the outgoing responses, which is essential
for managing persistence of <code class="literal">HTTP/1.0</code> connections. This
interceptor is recommended for server side protocol processors.
</p>
</div>
<div class="section" title="1.4.1.5.&nbsp;RequestDate"><div class="titlepage"><div><div><h4 class="title"><a name="d5e326"></a>1.4.1.5.&nbsp;<code class="classname">RequestDate</code></h4></div></div></div>
<p>
<code class="classname">RequestDate</code> is responsible for adding the
<code class="literal">Date</code> header to the outgoing requests. This interceptor is
optional for client side protocol processors.
</p>
</div>
<div class="section" title="1.4.1.6.&nbsp;ResponseDate"><div class="titlepage"><div><div><h4 class="title"><a name="d5e332"></a>1.4.1.6.&nbsp;<code class="classname">ResponseDate</code></h4></div></div></div>
<p>
<code class="classname">ResponseDate</code> is responsible for adding the
<code class="literal">Date</code> header to the outgoing responses. This interceptor is
recommended for server side protocol processors.
</p>
</div>
<div class="section" title="1.4.1.7.&nbsp;RequestExpectContinue"><div class="titlepage"><div><div><h4 class="title"><a name="d5e338"></a>1.4.1.7.&nbsp;<code class="classname">RequestExpectContinue</code></h4></div></div></div>
<p>
<code class="classname">RequestExpectContinue</code> is responsible for enabling the
'expect-continue' handshake by adding the <code class="literal">Expect</code> header. This
interceptor is recommended for client side protocol processors.
</p>
</div>
<div class="section" title="1.4.1.8.&nbsp;RequestTargetHost"><div class="titlepage"><div><div><h4 class="title"><a name="d5e344"></a>1.4.1.8.&nbsp;<code class="classname">RequestTargetHost</code></h4></div></div></div>
<p>
<code class="classname">RequestTargetHost</code> is responsible for adding the
<code class="literal">Host</code> header. This interceptor is required for client side
protocol processors.
</p>
</div>
<div class="section" title="1.4.1.9.&nbsp;RequestUserAgent"><div class="titlepage"><div><div><h4 class="title"><a name="d5e350"></a>1.4.1.9.&nbsp;<code class="classname">RequestUserAgent</code></h4></div></div></div>
<p>
<code class="classname">RequestUserAgent</code> is responsible for adding the
<code class="literal">User-Agent</code> header. This interceptor is recommended for client
side protocol processors.
</p>
</div>
<div class="section" title="1.4.1.10.&nbsp;ResponseServer"><div class="titlepage"><div><div><h4 class="title"><a name="d5e356"></a>1.4.1.10.&nbsp;<code class="classname">ResponseServer</code></h4></div></div></div>
<p>
<code class="classname">ResponseServer</code> is responsible for adding the
<code class="literal">Server</code> header. This interceptor is recommended for server side
protocol processors.
</p>
</div>
</div>
<div class="section" title="1.4.2.&nbsp;Working with protocol processors"><div class="titlepage"><div><div><h3 class="title"><a name="d5e362"></a>1.4.2.&nbsp;Working with protocol processors</h3></div></div></div>
<p>
Usually HTTP protocol processors are used to pre-process incoming messages prior to
executing application specific processing logic and to post-process outgoing messages.
</p>
<pre class="programlisting">
BasicHttpProcessor httpproc = new BasicHttpProcessor();
// Required protocol interceptors
httpproc.addInterceptor(new RequestContent());
httpproc.addInterceptor(new RequestTargetHost());
// Recommended protocol interceptors
httpproc.addInterceptor(new RequestConnControl());
httpproc.addInterceptor(new RequestUserAgent());
httpproc.addInterceptor(new RequestExpectContinue());
HttpContext context = new BasicHttpContext();
HttpRequest request = new BasicHttpRequest("GET", "/");
httpproc.process(request, context);
HttpResponse response = null;
</pre>
<p>
Send the request to the target host and get a response.
</p>
<pre class="programlisting">
httpproc.process(response, context);
</pre>
<p>
Please note the <code class="classname">BasicHttpProcessor</code> class does not synchronize
access to its internal structures and therefore may not be thread-safe.
</p>
</div>
<div class="section" title="1.4.3.&nbsp;HTTP context"><div class="titlepage"><div><div><h3 class="title"><a name="d5e370"></a>1.4.3.&nbsp;HTTP context</h3></div></div></div>
<p>
Protocol interceptors can collaborate by sharing information - such as a processing
state - through an HTTP execution context. HTTP context is a structure that can be
used to map an attribute name to an attribute value. Internally HTTP context
implementations are usually backed by a <code class="classname">HashMap</code>. The primary
purpose of the HTTP context is to facilitate information sharing among various
logically related components. HTTP context can be used to store a processing state for
one message or several consecutive messages. Multiple logically related messages can
participate in a logical session if the same context is reused between consecutive
messages.
</p>
<pre class="programlisting">
BasicHttpProcessor httpproc = new BasicHttpProcessor();
httpproc.addInterceptor(new HttpRequestInterceptor() {
public void process(
HttpRequest request,
HttpContext context) throws HttpException, IOException {
String id = (String) context.getAttribute("session-id");
if (id != null) {
request.addHeader("Session-ID", id);
}
}
});
HttpRequest request = new BasicHttpRequest("GET", "/");
httpproc.process(request, context);
</pre>
<p>
<code class="interfacename">HttpContext</code> instances can be linked together to form a
hierarchy. In the simplest form one context can use content of another context to
obtain default values of attributes not present in the local context.
</p>
<pre class="programlisting">
HttpContext parentContext = new BasicHttpContext();
parentContext.setAttribute("param1", Integer.valueOf(1));
parentContext.setAttribute("param2", Integer.valueOf(2));
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute("param2", Integer.valueOf(0));
localContext.setAttribute("param3", Integer.valueOf(3));
HttpContext stack = new DefaultedHttpContext(localContext,
parentContext);
System.out.println(stack.getAttribute("param1"));
System.out.println(stack.getAttribute("param2"));
System.out.println(stack.getAttribute("param3"));
System.out.println(stack.getAttribute("param4"));
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
1
0
3
null
</pre>
</div>
</div>
<div class="section" title="1.5.&nbsp;HTTP parameters"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e380"></a>1.5.&nbsp;HTTP parameters</h2></div></div></div>
<p>
<code class="interfacename">HttpParams</code> interface represents a collection of immutable
values that define a runtime behavior of a component. In many ways <code class="interfacename">HttpParams
</code> is similar to <code class="interfacename">HttpContext</code>. The main
distinction between the two lies in their use at runtime. Both interfaces represent a
collection of objects that are organized as a map of textual names to object values, but
serve distinct purposes:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p>
<code class="interfacename">HttpParams</code> is intended to contain simple objects:
integers, doubles, strings, collections and objects that remain immutable at
runtime. <code class="interfacename">HttpParams</code> is expected to be used in the
'write once - read many' mode. <code class="interfacename">HttpContext</code> is
intended to contain complex objects that are very likely to mutate in the course of
HTTP message processing.
</p>
</li><li class="listitem">
<p>
The purpose of <code class="interfacename">HttpParams</code> is to define a behavior of
other components. Usually each complex component has its own <code class="interfacename">
HttpParams</code> object. The purpose of <code class="interfacename">HttpContext
</code> is to represent an execution state of an HTTP process. Usually
the same execution context is shared among many collaborating objects.
</p>
</li></ul></div>
<p>
<code class="interfacename">HttpParams</code>, like <code class="interfacename">HttpContext</code>
can be linked together to form a hierarchy. In the simplest form one set of parameters can
use content of another one to obtain default values of parameters not present in the local
set.
</p>
<pre class="programlisting">
HttpParams parentParams = new BasicHttpParams();
parentParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
HttpVersion.HTTP_1_0);
parentParams.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET,
"UTF-8");
HttpParams localParams = new BasicHttpParams();
localParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
HttpVersion.HTTP_1_1);
localParams.setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE,
Boolean.FALSE);
HttpParams stack = new DefaultedHttpParams(localParams,
parentParams);
System.out.println(stack.getParameter(
CoreProtocolPNames.PROTOCOL_VERSION));
System.out.println(stack.getParameter(
CoreProtocolPNames.HTTP_CONTENT_CHARSET));
System.out.println(stack.getParameter(
CoreProtocolPNames.USE_EXPECT_CONTINUE));
System.out.println(stack.getParameter(
CoreProtocolPNames.USER_AGENT));
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
HTTP/1.1
UTF-8
false
null
</pre>
<p>
Please note the <code class="classname">BasicHttpParams</code> class does not synchronize access to
its internal structures and therefore may not be thread-safe.
</p>
<div class="section" title="1.5.1.&nbsp;HTTP parameter beans"><div class="titlepage"><div><div><h3 class="title"><a name="d5e405"></a>1.5.1.&nbsp;HTTP parameter beans</h3></div></div></div>
<p>
<code class="interfacename">HttpParams</code> interface allows for a great deal of
flexibility in handling configuration of components. Most importantly, new parameters
can be introduced without affecting binary compatibility with older versions. However,
<code class="interfacename">HttpParams</code> also has a certain disadvantage compared to
regular Java beans: <code class="interfacename">HttpParams</code> cannot be assembled using
a DI framework. To mitigate the limitation, HttpCore includes a number of bean classes
that can be used in order to initialize <code class="interfacename">HttpParams</code> objects
using standard Java bean conventions.
</p>
<pre class="programlisting">
HttpParams params = new BasicHttpParams();
HttpProtocolParamBean paramsBean = new HttpProtocolParamBean(params);
paramsBean.setVersion(HttpVersion.HTTP_1_1);
paramsBean.setContentCharset("UTF-8");
paramsBean.setUseExpectContinue(true);
System.out.println(params.getParameter(
CoreProtocolPNames.PROTOCOL_VERSION));
System.out.println(params.getParameter(
CoreProtocolPNames.HTTP_CONTENT_CHARSET));
System.out.println(params.getParameter(
CoreProtocolPNames.USE_EXPECT_CONTINUE));
System.out.println(params.getParameter(
CoreProtocolPNames.USER_AGENT));
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
HTTP/1.1
UTF-8
false
null
</pre>
</div>
</div>
<div class="section" title="1.6.&nbsp;Blocking HTTP protocol handlers"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e415"></a>1.6.&nbsp;Blocking HTTP protocol handlers</h2></div></div></div>
<div class="section" title="1.6.1.&nbsp;HTTP service"><div class="titlepage"><div><div><h3 class="title"><a name="d5e417"></a>1.6.1.&nbsp;HTTP service</h3></div></div></div>
<p>
<code class="classname">HttpService</code> is a server side HTTP protocol handler based on the
blocking I/O model that implements the essential requirements of the HTTP protocol for
the server side message processing as described by RFC 2616.
</p>
<p>
<code class="classname">HttpService</code> relies on <code class="interfacename">HttpProcessor
</code> instance to generate mandatory protocol headers for all outgoing
messages and apply common, cross-cutting message transformations to all incoming and
outgoing messages, whereas HTTP request handlers are expected to take care of
application specific content generation and processing.
</p>
<pre class="programlisting">
HttpParams params;
// Initialize HTTP parameters
HttpProcessor httpproc;
// Initialize HTTP processor
HttpService httpService = new HttpService(
httpproc,
new DefaultConnectionReuseStrategy(),
new DefaultHttpResponseFactory());
httpService.setParams(params);
</pre>
<div class="section" title="1.6.1.1.&nbsp;HTTP request handlers"><div class="titlepage"><div><div><h4 class="title"><a name="d5e425"></a>1.6.1.1.&nbsp;HTTP request handlers</h4></div></div></div>
<p>
The <code class="interfacename">HttpRequestHandler</code> interface represents a
routine for processing of a specific group of HTTP requests. <code class="classname">HttpService
</code> is designed to take care of protocol specific aspects, whereas
individual request handlers are expected to take care of application specific HTTP
processing. The main purpose of a request handler is to generate a response object
with a content entity to be sent back to the client in response to the given
request.
</p>
<pre class="programlisting">
HttpRequestHandler myRequestHandler = new HttpRequestHandler() {
public void handle(
HttpRequest request,
HttpResponse response,
HttpContext context) throws HttpException, IOException {
response.setStatusCode(HttpStatus.SC_OK);
response.addHeader("Content-Type", "text/plain");
response.setEntity(
new StringEntity("some important message"));
}
};
</pre>
</div>
<div class="section" title="1.6.1.2.&nbsp;Request handler resolver"><div class="titlepage"><div><div><h4 class="title"><a name="d5e431"></a>1.6.1.2.&nbsp;Request handler resolver</h4></div></div></div>
<p>
HTTP request handlers are usually managed by a <code class="interfacename">
HttpRequestHandlerResolver</code> that matches a request URI to a request
handler. HttpCore includes a very simple implementation of the request handler
resolver based on a trivial pattern matching algorithm: <code class="classname">
HttpRequestHandlerRegistry</code> supports only three formats:
<code class="literal">*</code>, <code class="literal">&lt;uri&gt;*</code> and
<code class="literal">*&lt;uri&gt;</code>.
</p>
<pre class="programlisting">
HttpService httpService;
// Initialize HTTP service
HttpRequestHandlerRegistry handlerResolver =
new HttpRequestHandlerRegistry();
handlerReqistry.register("/service/*", myRequestHandler1);
handlerReqistry.register("*.do", myRequestHandler2);
handlerReqistry.register("*", myRequestHandler3);
// Inject handler resolver
httpService.setHandlerResolver(handlerResolver);
</pre>
<p>
Users are encouraged to provide more sophisticated implementations of
<code class="interfacename">HttpRequestHandlerResolver</code> - for instance, based on
regular expressions.
</p>
</div>
<div class="section" title="1.6.1.3.&nbsp;Using HTTP service to handle requests"><div class="titlepage"><div><div><h4 class="title"><a name="d5e442"></a>1.6.1.3.&nbsp;Using HTTP service to handle requests</h4></div></div></div>
<p>
When fully initialized and configured, the <code class="classname">HttpService</code> can
be used to execute and handle requests for active HTTP connections. The
<code class="methodname">HttpService#handleRequest()</code> method reads an incoming
request, generates a response and sends it back to the client. This method can be
executed in a loop to handle multiple requests on a persistent connection. The
<code class="methodname">HttpService#handleRequest()</code> method is safe to execute from
multiple threads. This allows processing of requests on several connections
simultaneously, as long as all the protocol interceptors and requests handlers used
by the <code class="classname">HttpService</code> are thread-safe.
</p>
<pre class="programlisting">
HttpService httpService;
// Initialize HTTP service
HttpServerConnection conn;
// Initialize connection
HttpContext context;
// Initialize HTTP context
boolean active = true;
try {
while (active &amp;&amp; conn.isOpen()) {
httpService.handleRequest(conn, context);
}
} finally {
conn.shutdown();
}
</pre>
</div>
</div>
<div class="section" title="1.6.2.&nbsp;HTTP request executor"><div class="titlepage"><div><div><h3 class="title"><a name="d5e450"></a>1.6.2.&nbsp;HTTP request executor</h3></div></div></div>
<p>
<code class="classname">HttpRequestExecutor</code> is a client side HTTP protocol handler based
on the blocking I/O model that implements the essential requirements of the HTTP
protocol for the client side message processing, as described by RFC 2616.
The <code class="classname">HttpRequestExecutor</code> relies on the <code class="interfacename">HttpProcessor
</code> instance to generate mandatory protocol headers for all outgoing
messages and apply common, cross-cutting message transformations to all incoming and
outgoing messages. Application specific processing can be implemented outside
<code class="classname">HttpRequestExecutor</code> once the request has been executed and a
response has been received.
</p>
<pre class="programlisting">
HttpClientConnection conn;
// Create connection
HttpParams params;
// Initialize HTTP parameters
HttpProcessor httpproc;
// Initialize HTTP processor
HttpContext context;
// Initialize HTTP context
HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
BasicHttpRequest request = new BasicHttpRequest("GET", "/");
request.setParams(params);
httpexecutor.preProcess(request, httpproc, context);
HttpResponse response = httpexecutor.execute(
request, conn, context);
response.setParams(params);
httpexecutor.postProcess(response, httpproc, context);
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
</pre>
<p>
Methods of <code class="classname">HttpRequestExecutor</code> are safe to execute from multiple
threads. This allows execution of requests on several connections simultaneously, as
long as all the protocol interceptors used by the <code class="classname">HttpRequestExecutor
</code> are thread-safe.
</p>
</div>
<div class="section" title="1.6.3.&nbsp;Connection persistence / re-use"><div class="titlepage"><div><div><h3 class="title"><a name="d5e461"></a>1.6.3.&nbsp;Connection persistence / re-use</h3></div></div></div>
<p>
The <code class="interfacename">ConnectionReuseStrategy</code> interface is intended to
determine whether the underlying connection can be re-used for processing of further
messages after the transmission of the current message has been completed. The default
connection re-use strategy attempts to keep connections alive whenever possible.
Firstly, it examines the version of the HTTP protocol used to transmit the message.
<code class="literal">HTTP/1.1</code> connections are persistent by default, while <code class="literal">
HTTP/1.0</code> connections are not. Secondly, it examines the value of the
<code class="literal">Connection</code> header. The peer can indicate whether it intends to
re-use the connection on the opposite side by sending <code class="literal">Keep-Alive</code> or
<code class="literal">Close</code> values in the <code class="literal">Connection</code> header. Thirdly,
the strategy makes the decision whether the connection is safe to re-use based on the
properties of the enclosed entity, if available.
</p>
</div>
</div>
</div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="preface.html">Prev</a>&nbsp;</td><td width="20%" align="center">&nbsp;</td><td width="40%" align="right">&nbsp;<a accesskey="n" href="nio.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Preface&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;Chapter&nbsp;2.&nbsp;NIO extensions</td></tr></table></div></body></html>