pod web

Standard weblet APIs for processing HTTP requests

Mixins

Weblet

Weblet services a web request.

Classes

Cookie

Cookie models an HTTP cookie used to pass data between the server and user agent as defined by RFC 6265.

FileWeblet

FileWeblet is used to service an HTTP request on a File.

WebAuthScheme

Models an HTTP challenge/response authentication scheme as defined in RFC7235.

WebClient

The WebClient class is used to manage client side HTTP requests and responses.

WebMod

WebMod defines a web modules which is plugged into a web server's URI namespace to service web requests.

WebOutStream

WebOutStream provides methods for generating XML and XHTML content.

WebReq

WebReq encapsulates a web request.

WebRes

WebRes encapsulates a response to a web request.

WebSession

WebSession provides a name/value map associated with a specific browser "connection" to the web server.

WebSocket

WebSocket is used for both client and server web socket messaging.

WebUtil

WebUtil encapsulates several useful utility web methods.

Overview

The web pod defines the standard APIs used to handle both client and server side HTTP requests.

Client side HTTP requests:

Server side web APIs are organized into the primary classes:

WebClient

The WebClient class is used to manage client side HTTP requests and responses. The basic lifecycle of WebClient:

  1. configure request fields such as reqUri, reqMethod, and reqHeaders
  2. send request headers via writeReq
  3. optionally write request body via reqOut
  4. read response status and headers via readRes
  5. process response fields such as resCode and resHeaders
  6. optionally read response body via resIn

Using the low level methods writeReq and readRes enables HTTP pipelining (multiple requests and responses on the same TCP socket connection). There are also a series of convenience methods which make common cases easier.

See examples for sample code.

Weblets

Pretty much anything that touches a HTTP request should be implement Weblet. The lifecycle of a Weblet is quite simple:

WebReq

The WebReq class models the request side of a HTTP request. Common methods you will use include:

WebRes

The WebRes class models the response side of a HTTP request. A WebRes has the following lifecycle:

Common methods you will use include:

WebRes is a fairly low level API which requires the commit state model to avoid buffering the content.

WebSessions

The WebSession class models the client session which allows you to persist state between HTTP requests. WebSessions in Fantom are cookie based using the cookie name "fanws". The default session implementation stores sessions in memory for up to 24 hours, then clears them from the cache - session state is not persisted between VM restarts.

WebSession provides a Str:Obj? map to store arbitrary name/value pairs. You can use the map, get, or set methods to manage session state. You can use delete to explicitly delete the session cookie and server side state. The values stored in a WebSession should always be serializable objects.

WebSessions are created and accessed via the WebReq.session method. The first time a session is accessed it sets the cookie header in the response - therefore sessions should always be accessed before the response is committed. Deleting a session also requires setting the cookie header and must done before the response is committed.

Example of storing a counter in a session:

override Void doGet()
{
  Int count := req.session.get("counter", 0)
  req.session["counter"] = count + 1

  res.headers["Content-Type"] = "text/plain"
  res.statusCode = 200
  res.out.printLine("session counter=$count")
}

WebMods

The WebMod class is the base class for plugging in web server modules. WebMods are immutable Weblets which may be composed together to build higher level modules or to configure the entire web server.

During processing of a given web request, there is always exactly one WebMod responsible for the request which is available via the WebReq.mod method. The URI used to route to the module is accessed by WebReq.modBase, and the remainder of the URI which is internal to the module via WebReq.modRel. Using these methods you can write modules which can be freely plugged anywhere into a server's URI namespace.

WebMods receive the onStart and onStop callbacks when the web server is started and stopped. These callbacks can be used to perform initialization and cleanup such as managing actors.

The webmod pod includes a library of modules which are designed to handle common tasks such publishing static files, routing, and pipelining.

Expect Continue

Using "Expect: 100-continue" allows the server to fail-fast and report an error to the client before the client sends the request body. This technique is often used before posting large files to verify preconditions.

The WebClient API does not provide automatic support for using the Expect header. You must manually handle flow control yourself. Here is a simple example showing how to post a file using the Expect header:

c := WebClient(`http://example.com/post-file`)
c.reqMethod = "POST"
c.reqHeaders["Content-Type"] = file.mimeType.toStr
c.reqHeaders["Content-Length"] = file.size.toStr
c.reqHeaders["Expect"] = "100-continue"
c.writeReq
c.readRes
if (c.resCode != 100) throw IOErr("Expecting 100, not $c.resCode")
file.in.pipe(c.reqOut, file.size)
c.reqOut.close
c.readRes
if (c.resCode != 200) throw IOErr("Expecting 200, not $c.resCode")

Server side processing of the Expect header is automatic. When a Weblet acquires the WebReq.in stream for the first time, the request is checked for the "Expect: 100-continue" header and if specified, then a 100 Continue is automatically sent.