hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Httpcomponents Wiki] Update of "HttpCoreTutorial" by OlegKalnichevski
Date Sun, 05 Oct 2008 17:13:20 GMT
Dear Wiki user,

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

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

------------------------------------------------------------------------------
  
   * Identity coding
  
- The end of the content entity is demarcated by closing the underying connection (EOF condition).
For obvious reasons the identity encoing can only be used on the server side. Max entity length:
unlimited.
+ The end of the content entity is demarcated by closing the underlying connection (EOF condition).
For obvious reasons the identity encoding can only be used on the server side. Max entity
length: unlimited.
      
   * Chunk coding
  
@@ -449, +449 @@

  === Terminating HTTP connections ===
  
  HTTP connections can be terminated either gracefully by calling !HttpConnection#close()
or forcibly by calling !HttpConnection#shutdown(). The former tries to flush all buffered
data prior to terminating the connection and may block indefinitely. The !HttpConnection#close()
method is not threading 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
!HttpConnection#shutdown() method is expected to be threading safe.
+ 
+ == HTTP exception handling ==
+ 
+ All !HttpCore components throw two types of exceptions: !IOException in case of an I/O failure
such as socket timeout or an socket reset and !HttpException 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. 
+ 
+ === Protocol exception ===
+ 
+ !ProtocolException signals a fatal HTTP protocol violation that usually results in an immediate
termination of the HTTP message processing.
          
  == HTTP protocol processors ==
  
+ 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. 
+ 
+ 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 a particular aspect of the HTTP protocol the interceptor is responsible for. 
+ 
+ Protocol interceptors must be implemented threading safe. Similarly to servlets, protocol
interceptors should not use instance variables unless access to those variables is synchronized.
+ 
- === Protocol interceptor ===
+ === Standard protocol interceptors ===
  
+ !HttpCore comes with a number of most essential protocol interceptors for client and server
HTTP processing.
-     The chain of responsibility pattern. Each individual protocol interceptor is responsible
-     for implementing a particular aspect of the HTTP protocol
  
-     Description of the most important protocol interceptors
+ ==== RequestContent ====
+ 
+ !RequestContent is the most important interceptor for outgoing requests. It is responsible
for delimiting content length by adding !Content-Length or !Transfer-Content 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.
      
+ ==== ResponseContent ====
+ 
+ !ResponseContent is the most important interceptor for outgoing responses. It is responsible
for delimiting content length by adding !Content-Length or !Transfer-Content 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.
+ 
+ ==== RequestConnControl ====
+ 
+ !RequestConnControl is responsible for adding !Connection header to the outgoing requests,
which is essential for managing persistence of HTTP/1.0 connections. This interceptor is recommended
for client side protocol processors.
+     
+ ==== ResponseConnControl ====
+ 
+ !ResponseConnControl is responsible for adding !Connection header to the outgoing responses,
which is essential for managing persistence of HTTP/1.0 connections. This interceptor is recommended
for server side protocol processors.
+ 
+ ==== RequestDate ====
+ 
+ !RequestDate is responsible for adding !Date header to the outgoing requests This interceptor
is optional for client side protocol processors.
+ 
+ ==== ResponseDate ====
+ 
+ !ResponseDate is responsible for adding !Date header to the outgoing responses. This interceptor
is recommended for server side protocol processors.
+ 
+ ==== RequestExpectContinue ====
+ 
+ !RequestExpectContinue is responsible for enabling the 'expect-continue' handshake by adding
!Expect header. This interceptor is recommended for client side protocol processors. 
+ 
+ ==== RequestTargetHost ====
+ 
+ !RequestTargetHost is responsible for adding !Host header. This interceptor is required
for client side protocol processors. 
+ 
+ ==== RequestUserAgent ====
+ 
+ !RequestUserAgent is responsible for adding !User-Agent header. This interceptor is recommended
for client side protocol processors. 
+ 
+ ==== ResponseServer ====
+ 
+ !ResponseServer is responsible for adding !Server header. This interceptor is recommended
for server side protocol processors. 
+ 
+ === Working with protocol processors ===
+ 
+ Usually HTTP protocol processors are used to pre-process incoming messages prior to executing
application specific processing logic and to post-process outgoing messages.
+ 
+ {{{
+ 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;
+ }}}
+ Send the request to the target host and get a response.
+ {{{
+ httpproc.process(response, context);
+ }}}
+ 
  === HTTP context ===
  
+ 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 HashMap. 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.
-     Protocol interceptors can collaborate by sharing information such as processing state
-     through the HTTP context
  
- == HTTP protocol handlers ==
+ {{{
+ BasicHttpProcessor httpproc = new BasicHttpProcessor();
+ httpproc.addInterceptor(new HttpRequestInterceptor() {
  
- === Server side protocol handling ===
- 
-     HttpService / HttpRequestHandler and friends
- 
- === Client side protocol handling ===
- 
-     HttpRequestExecutor and friends
+     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);
+ }}}
+ 
+ !HttpContexts 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.
+ 
+ {{{
+ 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"));
+ }}}
+ 
+ stdout >
+ {{{
+ 1
+ 0
+ 3
+ null
+ }}} 
+ 
+ == HTTP parameters ==
+ 
+ !HttpParams represents a collection of immutable values that define a runtime behavior of
a component. In many ways !HttpParams is similar to !HttpContext. 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:
+ 
+  * !HttpParams is intended to contain simple objects: integers, doubles, strings, collections
and objects that remain immutable at runtime. !HttpParams is expected to be used in the 'write
once - ready many' mode. !HttpContext is intended to contain complex objects that are very
likely to mutate in the course of HTTP message processing.
+ 
+  * The purpose of !HttpParams is to define a behavior of other components. Usually each
complex component has its own !HttpParams object. The purpose of !HttpContext is to represent
an execution state of an HTTP process. Usually the same execution context is shared among
many collaborating objects.     
+ 
+ !HttpParams, like !HttpContext, 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.
+ 
+ {{{
+ 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));
+ }}}
+ 
+ stdout >
+ {{{
+ HTTP/1.1
+ UTF-8
+ false
+ null
+ }}} 
+ 
+ === HTTP parameter beans ===
+ 
+ !HttpParams 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, !HttpParams also has a certain disadvantage compared to regular
java beans: !HttpParams cannot be assembled using a DI framework. To mitigate the limitation,
!HttpCore includes a number of bean classes that cab used in order to initialize !HttpParams
objects using standard java bean conventions. 
+ 
+ {{{
+ 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));
+ }}}
+ 
+ stdout >
+ {{{
+ HTTP/1.1
+ UTF-8
+ false
+ null
+ }}} 
+ 
+ == Blocking HTTP protocol handlers ==
+ 
+ === HTTP service ===
+ 
+ !HttpService is a server side HTTP protocol handler based in 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. !HttpService relies on !HttpProcessor to take care of the cross-cutting
protocol aspects that apply to all incoming and outgoing messages.
+ 
+ {{{
+ HttpParams params;
+ // Initialize HTTP parameters
+ HttpProcessor httpproc;
+ // Initialize HTTP processor
+ 
+ HttpService httpService = new HttpService(
+         httpproc, 
+         new DefaultConnectionReuseStrategy(), 
+         new DefaultHttpResponseFactory());
+ httpService.setParams(params);
+ }}}
+ 
+ ==== HTTP request handlers ====
+ 
+ !HttpRequestHandler interface represents a routine intended to handle processing of a specific
group of HTTP requests. !HttpService is designed to take care of protocol specific aspects,
whereas request handlers take care of application specific HTTP processing. Their main purpose
is to generate a content entity to be send back to the client in response to the given request.
+ 
+ {{{
+ 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"));
+     }
+     
+ });
+ }}}
+ 
+ Request handlers must be implemented threading safe. Similarly to servlets, request handlers
should not use instance variables unless access to those variables is synchronized.
+ 
+ ==== Request handler resolver ====
+ 
+ HTTP request handlers are usually managed by a !HttpRequestHandlerResolver that matches
a request URI to a request handler. !HttpCore includes an over-simplified implementation of
request handler resolver based on a trivial pattern matching algorithm: !HttpRequestHandlerRegistry
supports only three formats: *, <uri>* and *<uri>.
+ 
+ {{{
+ 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);
+ }}}
+ 
+ Users are encouraged to provide more sophisticated implementations of !HttpRequestHandlerResolver,
for instance, based on regular expressions.
+ 
+ ==== Using HTTP service to handle requests ====
+ 
+ When fully initialized and configured !HttpService can be used to execute handle requests
for active HTTP connections. !HttpService#!handleRequest() method reads an incoming requests,
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 !HttpService#!handleRequest()
is safe to execute from multiple threads to process requests on several connections simultaneously
as long as protocol interceptors and requests handlers used by the !HttpService are threading
safe.
+ 
+ {{{
+ HttpService httpService;
+ // Initialize HTTP service
+ HttpServerConnection conn;
+ // Initialize connection
+ HttpContext context;
+ // Initialize HTTP context
+ 
+ boolean active = true;
+ try {
+     while (active && conn.isOpen()) {
+         httpService.handleRequest(conn, context);
+     }
+ } finally {
+     conn.shutdown();
+ }
+ }}}
+ 
+ === HTTP request executor ===
+ 
+ !HttpRequestExecutor 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. !HttpRequestExecutor, similarly to its server side counterpart,
makes use of !HttpProcessor to take care of the cross-cutting protocol aspects that apply
to all incoming and outgoing messages. Application specific processing can be implemented
outside !HttpRequestExecutor once the request has been executed and a response has been received.
+ 
+ {{{
+ 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();
+ if (entity != null) {
+     entity.consumeContent();
+ }
+ }}}
+ 
+ Methods of !HttpRequestExecutor are safe to execute from multiple threads to execute requests
on several connections simultaneously as long as protocol interceptors used by the !HttpRequestExecutor
are threading safe.
+ 
  === Connection persistence / re-use ===
  
+ !ConnectionReuseStrategy interface is intended to determine whether the underlying connection
can be reused for processing of consecutive messages after the transmission of the current
one has been completed. The default connection re-use strategy attempts to keep connection
alive whenever possible. Firstly, it examines the version of the HTTP protocol used to transmit
the message. HTTP/1.1 connections are persistent per default, HTTP/1.0 are not. Secondly,
it examines the value of the !Connection header. The peer can indicate whether it intends
to re-use the connection on the opposite side by sending !Keep-Alive or !Close values in the
!Connection 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.  
-     ConnectionReuseStrategy interface and its implementations
- 
- == HTTP parameters ==
- 
-     HttpParams interface; Parameter hierachies
      
- === HTTP parameter beans ===
- 
-     Using plains beans for assembling HTTP parameters
- 
- == Customization of the HTTP message parsing / formatting ==
- 
-     LineParser / LineFormatter interfaces
-     
-     HeaderValueParser / HeaderValueFormatter interfaces
- 
- == Example of building a simple HTTP server (using blocking I/O model) ==
- 
-     Code sample with a code walk-through
- 
- == Example of building a simple HTTP client (using blocking I/O model) ==
- 
-     Code sample with a code walk-through
- 
  = NIO extensions =
   
  == Benefits and shortcomings of the non-blocking I/O model ==
  
-     NIO does not necessarily fit all use cases. Use only where appropriate: 
+ Contrary to the popular belief, the performance of NIO in terms of raw data throughput is
significantly lower than than of the blocking I/O. NIO does not necessarily fit all use cases
and should be used only where appropriate: 
      
+  * handling of thousands of connections, significant number of which can be idle 
+ 
-     * lots high latency connections
+  * handling high latency connections
      
-     * request / response handling needs to be decoupled. 
+  * request / response handling needs to be decoupled. 
  
  == Differences from other NIO frameworks ==
  
-     Solves similar problems as other frameworks, but has certain distinct 
+ Solves similar problems as other frameworks, but has certain distinct features
-     features
      
-     * minimalistic, optimized for data volume intensive protocols such as HTTP
+  * minimalistic, optimized for data volume intensive protocols such as HTTP
  
-     * efficient memory management
+  * efficient memory management: data consumer can read only as much input data as it can
process without having to allocate more memory
      
-     * direct access to the NIO channels where possible
+  * direct access to the NIO channels where possible
+     
+ == I/O reactor ==
+ 
+ !HttpCore NIO is based on the Reactor pattern as described by Doug Lea. The purpose of I/O
reactors is to react to I/O events and to dispatch event notifications to individual I/O sessions.
The main idea of I/O reactor pattern is to break away from one thread per connection model
imposed by the classic blocking I/O model. !IOReactor interface represents an abstract object
implementing the Reactor pattern. Internally, !IOReactor implementations encapsulate functionality
of the NIO !Selector.
+ 
+ I/O reactors usually employ a small number of worker threads (often as few as one) to dispatch
I/O event notifications to a much greater number (often as many as several thousands) of I/O
sessions or connections. It is generally recommended to have one dispatch thread per CPU core.
+ 
+ {{{
+ HttpParams params = new BasicHttpParams();
+ int workerCount = 2;
+ IOReactor ioreactor = new DefaultConnectingIOReactor(workerCount, params);
+ }}}
+ 
+ === I/O dispatchers ===
+ 
+ !IOReactor implementations make use of the !IOEventDispatch interface to notify of events
pending for a particular session. All methods of the !IOEventDispatch are executed on a dispatch
thread of the I/O reactor. Therefore, it is important that processing that takes place in
the event methods will not block the dispatch thread for too long, as the I/O reactor will
be unable to react to other events. 
+ 
+ {{{
+ HttpParams params = new BasicHttpParams();
+ IOReactor ioreactor = new DefaultConnectingIOReactor(2, params);
-     
+      
+ IOEventDispatch eventDispatch = new MyIOEventDispatch();
+ ioreactor.execute(eventDispatch);
+ }}}
+ 
+ There are several events methods of the !IOEventDispatch
+ 
+  * connected: new session has been created
+ 
+  * inputReady: session has pending input
+ 
+  * outputReady: session is ready for output
+ 
+  * timeout: session timed out
+ 
+  * disconnected: session has been terminated
+ 
- == I/O reactor pattern ==
+ === I/O reactor shutdown ===
  
-     HttpCore NIO is based on the Reactor pattern as described by Doug Lea
+ The shutdown of I/O reactors is a complex process and may usually take a while to complete.
I/O reactors will attempt to gracefully terminate all active I/O sessions and dispatch threads
approximately within the specified grace period. If any of the I/O sessions fails to terminate
correctly, the I/O reactor will forcibly shut down remaining sessions.    
  
+ {{{
+ int gracePeriod = 3000; // milliseconds
+ ioreactor.shutdown(gracePeriod);
+ }}}
+ 
+ The !IOReactor#shutdown(long) method is safe to call from any thread.
+ 
- === I/O session ===
+ === I/O sessions ===
  
+ I/O session represents a sequence of logically related data exchanges between two end points.
I/O session encapsulates functionality of NIO !SelectionKey and !SocketChannel. One can use
the channel associated with the I/O session to read from and data from it. 
-     IOSession interface and friends
-     
- === I/O event dispatch ===
  
-     IOEventDispatch interface
-     
+ {{{
+ IOSession iosession;
+ ReadableByteChannel channel = (ReadableByteChannel) iosession.channel();
+ ByteBuffer dst = ByteBuffer.allocate(2048); 
+ channel.read(dst);
+ }}}
+ 
+ === I/O session state management ===
+ 
+ I/O sessions are not bound to an execution thread, therefore one cannot use the context
of the thread to store a session's state. All details about a particular session must be stored
within the session itself. 
+ 
+ {{{
+ IOSession iosession;
+ Object someState;
+ iosession.setAttribute("state", someState);
+ Object currentState = iosession.getAttribute("state");
+ }}}
+ 
+ Please note if several sessions make use of shared objects, access to those objects must
be synchronized or threading safe. 
+ 
+ === I/O session event mask ===
+ 
+ One can declare an interest in a particular type of I/O events for a particular I/O session
by setting its event mask. 
+ 
+ {{{
+ IOSession iosession;
+ iosession.setEventMask(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
+ }}}
+ 
+ One can also toggle !OP_READ and !OP_WRITE flags individually.
+ 
+ {{{
+ iosession.setEvent(SelectionKey.OP_READ);
+ iosession.clearEvent(SelectionKey.OP_READ);
+ }}}
+ 
+ Event notifications will not take place if the corresponding interest flag is not set.
+ 
+ === I/O session buffers ===
+ 
+ Quite often I/O sessions need to maintain internal I/O buffers in order to transform input
/ output data prior to returning it to the consumer or writing it to the underlying channel.
Memory management in !HttpCore NIO is based on the fundamental principle that the data consumer
can read only as much input data as it can process without having to allocate more memory.
That means that quite often some input data may remain unread in one of the internal or external
session buffers. The I/O reactor can query the status of the session buffers and make sure
the consumer gets correctly notified of more data stored in one of the session buffers, thus
allowing the consumer to read the remaining data once it is able to process it. I/O sessions
can be made aware of the status of external session buffers using the !SessionBufferStatus
interface. 
+ 
+ {{{
+ IOSession iosession;
+ iosession.hasBufferedInput();
+ iosession.hasBufferedOutput();
+ SessionBufferStatus myBufferStatus = new MySessionBufferStatus(); 
+ iosession.setBufferStatus(myBufferStatus);
+ }}}
+ 
+ === I/O session shutdown ===
+ 
+ One can close an I/O session gracefully by calling !IOSession#close() allowing the session
to be closed in an orderly manner or by calling !IOSession#shutdown() to forcibly close the
underlying channel. The distinction between two methods is of primary importance for those
types of I/O sessions that involve some sort of a session termination handshake such as SSL/TLS
connections.
+ 
  === Listening I/O reactors ===
  
      ListeningIOReactor and ListenerEndpoint interfaces
@@ -541, +894 @@

  
      ConnectingIOReactor, SessionRequest and SessionRequestCallback interfaces    
      
- == NHTTP connections ==
+ == Non-blocking HTTP connections ==
  
+ Effectively NHTTP connections are wrappers around !IOSession with HTTP specific functionality.
NHTTP connections are stateful and not threading safe. Input / output operations on NHTTP
connections should be restricted to the dispatch events triggered by the I/O event dispatch
thread. 
-     NHttpClientConnection, NHttpServerConnection interfaces and friends. Basically 
-     wrappers around IOSession; 
-     
-     NHTTP connections are stateful. They should be read from / written to
-     from the I/O event dispatch thread.
-     
- == NHTTP message serialization and deserialization ==
  
-     NHttpMessageWriter / NHttpMessageParser interfaces
+ === Execution context of non-blocking HTTP connections ===
  
- === I/O control ===
+ NHTTP connections are not bound to a particular thread of execution and therefore they need
to maintain their own execution context. Each NHTTP connection has an !HttpContext instance
associated with it, which can be used to maintain a processing state. The !HttpContext instance
is threading safe and can be manipulated from multiple threads.
  
-     IOControl interface; suspending / requesting I/O event notifications
+ {{{
+ // Get NHTTP connection
+ DefaultNHttpClientConnection conn;
+ // State
+ Object myStateObject;
+ 
+ HttpContext context = conn.getContext();
+ context.setAttribute("state", myStateObject);
+ }}}
+ 
+ === Interacting with non-blocking HTTP connections ===
+ 
+ All NHTTP connections classes implement !IOControl interface, which represents a subset
of connection functionality for controlling interest in I/O even notifications. !IOControl
instances are expected to be fully threading safe. Therefore !IOControl can be used to request
/ suspend I/O event notifications from any thread. 
+ 
+ One must take special precautions when interacting with NHTTP connections. Input / output
operations on a NHTTP connection may lead to unpredictable results if executed from any thread
other than the I/O event dispatch thread.   
+ 
+ The following pattern is recommended:
+ 
+  * Use !IOControl interface to pass control over connection's I/O events to another thread
/ session.
+ 
+  * If input / output operations need be executed on that particular connection, store all
the required information (state) in the connection context and request the appropriate I/O
operation by calling !IOControl#requestInput() or !IOControl#requestOutput() method
+ 
+  * Execute the required operations from the event method on the dispatch thread using information
stored in connection context.
+ 
+ Please note all operations that take place in the event methods should not block for too
long, because while the dispatch thread remains blocked in one session, it is unable to process
events for all other sessions. I/O operations with the underlying channel of the session are
not a problem as they are guaranteed to be non-blocking.  
+ 
+ === Content codecs ===
+ 
+     ContentDecoder and ContentEncoder interfaces    
      
+ === Direct transfer to and from file channels ===
+ 
+     FileContentDecoder and FileContentEncoder interfaces
+ 
  == NHTTP entities ==
  
      Producing entities; consuming entities;
      
- === Content codecs ===
- 
-     ContentDecoder and ContentEncoder interfaces    
-     
- === Direct transfer to and from file channels ===
- 
-     FileContentDecoder and FileContentEncoder interfaces
- 
  == NHTTP protocol handlers ==
  
  === Asynchronous protocol handlers ===
@@ -591, +962 @@

  
      SSLIOSession, SSLServerIOEventDispatch, SSLClientIOEventDispatch classes
  
+ 
+ == Customization of the HTTP message parsing / formatting ==
+ 
+     LineParser / LineFormatter interfaces
+     
+     HeaderValueParser / HeaderValueFormatter interfaces
+ 
+ == Example of building a simple HTTP server (using blocking I/O model) ==
+ 
+     Code sample with a code walk-through
+ 
+ == Example of building a simple HTTP client (using blocking I/O model) ==
+ 
+     Code sample with a code walk-through
+ 
  == Example of building a simple HTTP server (using non-blocking I/O model) ==
  
      Code sample with a code walk-through

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


Mime
View raw message