# HTTP protocol objects

This chapter covers the http objects of the standard network working group service module.

## HTTP transaction objects

The concept of http transactions is defined in RFC 2616. In the client/server approach, a client issues a request which is answered with a response. A special case arise when the server is asked to perform some extra works, such like executing a script. In this case, the answer is called a reply which is formatted into a response when the server does its job correctly.

The nature of the http objects determines how the associated stream behaves. With a http request, the object is filled by reading an input stream when operating on the server side. On the other hand, the request is filled by data when operating on the client side. With a http response, the opposite situation occurs. The http response is filled by reading an input stream when operating on the client side and filled by data when operating on the server side.

### HTTP protocol

The `HttpProto` class is a base class designed to handle a http header that is found in both http request and response. The class is built around a property list that is filled either by parsing an input stream or by processing specific methods.

## HTTP response

The `HttpResponse` class is a class designed to handle a HTTP response. When operating on the client side, the response object is built by reading an input stream. When operating on the server side, the response object is built by calling specific methods.

### Creating a server response

A server response is created by specifing the response status code. By default, a http response is created with the default media type text/html. If the media type needs to be changed, it can be passed as the second argument to the response constructor. By default, the empty constructor creates an empty constructor with a valid status code.

#create a valid response const hr (afnix:nwg:HttpResponse 200)

Once the server response is created, it can be augmented with some headed values. Typicaly, a server will add some information about the response, such like the content length, the modification time or a tag. The `HttpResponse` provides several methods that ease the generation of these header values.

### Creating a client response

A client response is created by binding an input stream to the response object. The binding can be done either at construction or by using the `set-input-stream` method. In both cases, the object is cleared and a new header is filled after the `parse` method has been called.

# create a client response by stream const hr (afnix:nwg:HttpResponse is) # parse the response hr:parse

### Reading a client response

When the response has been created, it is important to check its status code. Most of the time, the response is valid and its content can be read directly. The `status-ok-p` predicate returns true if the status code is valid. In such case, an input response stream can be built in order to read the response. The `get-response-stream` method returns an input stream that contains the response data.

# check that a response is valid if (hr:status-ok-p) { # get the response stream const rs (ht:get-response-stream) # read the response stream while (rs:eos-p) (rs:read) }

Before reading a response, it is important to detect and verify the nature of the response content. The `media-type-p` predicate returns true if the media type is defined and the `get-media-type` method returns the response type in the form of a mime code such like text/html. Eventually, the character set associated with the media type can also be detected. The `encoding-mode-p` predicate and the `get-encoding-mode` method can be used to detect the content encoding mode. However, it is worth to note that the `get-response-stream` method automatically sets the encoding mode for the response stream from the header information.

### Special client response

Certain response can sometime contains special status codes that require a specific treatment. This is the case when the response corresponds to a http redirection. In this case, the new uri must be fetched to get the desired response. The `location-p` predicate returns true if the response corresponds to a http redirect and the `get-location` method can be used to get the new location uri. If this situation arises, it is up to the implementation to decide what to do with the new uri. In most cases, a new request will be sent to the server.

## Cookie object

The `Cookie` object is a special object that can be used during a http session, to post data to the http client. The idea behind cookies is to be able to maintain some state, during the user session for some time. A cookie is a name/value pair and eventually an expiration time. By default, the cookie object are defined for one http client session, but this behavior can be changed.

### Managing cookies

A cookie is created with a name/value pair and eventually an expiration time. Such expiration time is called the maximum-age and is automatically formatted by the object. With two arguments a session cookie is created. With a third argument as an integer, the constructor set the maximum age in seconds.

# create a cookie with name/value const cookie (afnix:nwg:Cookie "cartid" "123456789")

The cookie implementation follows the recommendation of the RFC-2965 for http state management. The most important point to remember is the interpretation of the maximum age that differs from one cookie version to another. With version 1, which is the default, the maximum age is defined relatively in seconds, while it is absolute with version 0.The maximum age is set either at construction or with the `set-max-age` method. The `set-max-age` method sets the cookie life time in seconds, in reference to the current time. A negative value is always reset to -1 and defined a session cookie. A 0 value tells the http client to remove the cookie. The `set-path` method defines the path for which this cookie apply.

### Adding a cookie

Once the cookie is defined, the `set-cookie` method of the `HttpResponse` object can be used to install the cookie. Combined with the `write` method, the cookie can be send to the http client.