Components of the Framework

There are many components that provide the HTTP protocol handling within Grizzly. This section will cover the major components.

HttpCodecFilter (Server/Client)

The HttpCodecFilter is the base Filter that provides the ability to marshall/unmarshall HTTP primitives to and from the network. Note that this class does a majority of the heavy lifting when dealing with the HTTP protocol. However, Grizzly does have two subclasses of HttpCodecFilter to deal with different semantics depending on which side of the connection being dealt with.

HTTP Messages

In order to make working with HTTP easier for the developer, Grizzly abstracts the network representation of an http protocol request/response into various different message objects.

Figure 3.1. HTTP Message Constructions UML Diagram

HTTP Message Constructions UML Diagram

As seen from the diagram all messages produced/consumed by the HttpCodecFilter are simply HttpPackets. From there, there are several specialized packet representations:

Table 3.1. HttpPacket Implementations

HttpHeaderHttpHeaders represents the http message headers.
HttpContentRepresents the entity body of a http message.
HttpTrailerThis is a specialized form of HttpContent. It's only used when the chunked transfer encoding is used and represents the length of the current chunk.
HttpRequestPacketA form of HttpHeader representing a HTTP request.
HttpResponsePacketA form of HttpHeader representing a HTTP response to a HTTP request.

HttpRequestPacket, HttpResponsePacket, HttpContent, and HttpTrailer (if using the chunked transfer encoding) all have Builder objects in order to create new instances. For example, in order to create a response for a particular request:

final HttpResponsePacket.Builder builder = response.builder(request);
final HttpResponsePacket response = builder.chunked(true).status(200).reasonPhrase("OK").build();

Building off the example above, a message body can be added to the response that was just created:

final HttpContent.Builder contentBuilder = response.httpContentBuilder();
final HttpContent = contentBuilder.setContent(
                         Buffers.wrap(null, "<html><head></head><body>Hello!</body></html>")).setLast(true).build();

Finally, since the response body is chunked, a HttpTrailer needs to be included:

final HttpTrailer.Builder trailerBuilder = response.httpTrailerBuilder();
final HttpTrailer trailer = trailderBuilder.build();

Each of the created HttpPacket entites from above can then be written to client:

// assume we have access to the FilterChainContext via a variable called 'ctx'...
ctx.write(response); 
ctx.write(content);  
ctx.write(trailer);  

The examples above are there purely to demonstrate the different builder objects. However, the example above could have the step with the HttpContent.Builder eliminated completely since HttpTrailer is a specialized form of HttpContent:

final HttpResponsePacket.Builder builder = response.builder(request);
final HttpResponsePacket response = builder.chunked(true).status(200).reasonPhrase("OK").build();
final HttpTrailder.Builder trailerBuilder = response.httpTrailderBuilder();
trailerBuilder.setContent(null, "<html><head></head><body>Hello!</body></html>").setLast(true).build();
ctx.write(response);
ctx.write(trailer);

Transfer Encodings

Transfer encodings allow special transformation formats for communciating http messages between client and server. Grizzly includes two transfer encoding implementations:

Table 3.2. Supported Transfer-Encodings

Fixed-LengthImplemented by org.glassfish.grizzly.http.FixedLengthTransferEncoding. This transfer-encoing will be used when content-length has been specified, or if chunking has been disabled. In the case where chunking is disabled and no content length has been specified, the implementation will try to determine the content length on its own.
ChunkedImplemented by org.glassfish.grizzly.ChunkedTransferEncoding. This transfer-encoding will be used when specified on a request or response. For more details on the chunked transfer-encoding, see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1.

Custom transfer-encoding implementations may be provided by implementing the TransferEncoding interface:

/**
 * Abstraction, which represents HTTP transfer-encoding.
 * The implementation should take care about possible HTTP content fragmentation.
 *
 * @see FixedLengthTransferEncoding
 * @see ChunkedTransferEncoding
 * 
 * @author Alexey Stashok
 */
public interface TransferEncoding {
    /**
     * Return <tt>true</tt> if this encoding should be used to parse the
     * content of the passed {@link HttpHeader}, or <tt>false</tt> otherwise.
     * 
     * @param httpPacket {@link HttpHeader}.
     * @return <tt>true</tt> if this encoding should be used to parse the
     * content of the passed {@link HttpHeader}, or <tt>false</tt> otherwise.
     */
    public boolean wantDecode(HttpHeader httpPacket);

    /**
     * Return <tt>true</tt> if this encoding should be used to serialize the
     * content of the passed {@link HttpHeader}, or <tt>false</tt> otherwise.
     *
     * @param httpPacket {@link HttpHeader}.
     * @return <tt>true</tt> if this encoding should be used to serialize the
     * content of the passed {@link HttpHeader}, or <tt>false</tt> otherwise.
     */
    public boolean wantEncode(HttpHeader httpPacket);

    /**
     * This method will be called by {@link HttpCodecFilter} to let
     * <tt>TransferEncoding</tt> prepare itself for the content serialization.
     * At this time <tt>TransferEncoding</tt> is able to change, update HTTP
     * packet headers.
     *
     * @param c connection associated with this packet.
     * @param httpHeader HTTP packet headers.
     * @param content ready HTTP content (might be null).
     */
    public void prepareSerialize(Connection c,
                                 HttpHeader httpHeader,
                                 HttpContent content);

    /**
     * Parse HTTP packet payload, represented by {@link Buffer} using specific
     * transfer encoding.
     *
     * @param connection {@link Connection}
     * @param httpPacket {@link HttpHeader} with parsed headers.
     * @param buffer {@link Buffer} HTTP message payload.
     * @return {@link ParsingResult}
     */
    public ParsingResult parsePacket(Connection connection,
            HttpHeader httpPacket, Buffer buffer);

    /**
     * Serialize HTTP packet payload, represented by {@link HttpContent}
     * using specific transfer encoding.
     *
     * @param connection {@link Connection}
     * @param httpContent {@link HttpContent} with parsed {@link HttpContent#getHttpHeader()}.
     *
     * @return serialized {@link Buffer}
     */
    public Buffer serializePacket(Connection connection,
            HttpContent httpContent);
}

Custom TransferEncoding implementations may be registered by calling HttpCodecFilter.addTransferEncoding().

Content Encodings

Content encodings describe when encodings have been applied to the message body prior to their being transferred to the recipient. At the time that this was written, Grizzly 2.2.10 only supports gzip content encoding (implemented by org.glassfish.grizzly.http.GzipContentEnconding).

Custom content-encodings can be provided by implementing the ContentEncoding interface:

/**
 * Abstraction, which represents HTTP content-encoding.
 * Implementation should take care of HTTP content encoding and decoding.
 *
 * @see GZipContentEncoding
 * 
 * @author Alexey Stashok
 */
public interface ContentEncoding {

    /**
     * Get the <tt>ContentEncoding</tt> name.
     *
     * @return the <tt>ContentEncoding</tt> name.
     */
    String getName();

    /**
     * Get the <tt>ContentEncoding</tt> aliases.
     * 
     * @return the <tt>ContentEncoding</tt> aliases.
     */
    String[] getAliases();

    /**
     * Method should implement the logic, which decides if HTTP packet with
     * the specific {@link HttpHeader} should be encoded using this <tt>ContentEncoding</tt>.
     *
     * @param header HTTP packet header.
     * @return <tt>true</tt>, if this <tt>ContentEncoding</tt> should be used to
     * encode the HTTP packet, or <tt>false</tt> otherwise.
     */
    boolean wantEncode(HttpHeader header);

    /**
     * Decode HTTP packet content represented by {@link HttpContent}.
     * 
     * @param connection {@link Connection}.
     * @param httpContent {@link HttpContent} to decode.
     *
     * @return {@link ParsingResult}, which represents the result of decoding.
     */
    ParsingResult decode(Connection connection, HttpContent httpContent);
    
    /**
     * Encode HTTP packet content represented by {@link HttpContent}.
     * 
     * @param connection {@link Connection}.
     * @param httpContent {@link HttpContent} to encode.
     *
     * @return encoded {@link HttpContent}.
     */
    HttpContent encode(Connection connection, HttpContent httpContent);
}

Custom ContentEncoding implementations may be registered by calling HttpCodecFilter.addContentEncoding().

HTTP Potpourri

Table 3.3. Other HTTP Classes of Interest

CookieRepresents a HTTP cookie. Supports version 0 and version 1 cookies.
CookiesA collection of Cookies.
CookiesBuilderA Builder implementation for created a List of Cookies from the message headers of a HttpHeader packet. This can be used on either the server or client side.
LazyCookieA wrapper for Cookie that delays parsing the header value into the values exposed by Cookie until needed.
BufferChunkRepresents a portion of a buffer and exposes various operations to operate on said portion.
CharChunkA utility class for dealing with character arrays in an efficent manner.
DataChunkRepresents a chunk of data that may be a BufferChunk, CharChunk, or String.