NAME
nwg - standard network working group module
STANDARD NETWORK WORKING GROUP OBJECT
This chapter covers the fundamental objects of the AFNIX standard
network working group service module. This modules contain object that
are generally defined by a RFC and used in networking application. All
AFNIX network working group objects are located in the afnix-nwg
module. This module must be loaded prior any operation. Multiple calls
to the module initialization routine are harmless. The interpreter
method module loads a specific module by name. When the module has been
loaded, the object are available in the afnix:nwg nameset.
interp:library "afnix-nwg"
The uri class
The Uri class is a base class that parse a Uniform Resource Identifier
or uri string and provides methods to access individual component of
that uri. The implementation conforms to RFC 3986. The URI components
are the scheme, the authority, the path, the query and the fragment.
The class also takes care of the character escaping.
const uri (afnix:www:Uri "http://www.afnix.org")
An uri can be broken into several components called the scheme, the
authority, the path, optionally the query and the fragment. The Uri
class provide a method to retrieve each component of the parsed uri.
const uri (afnix:www:Uri "http://www.afnix.org/")
println (uri:get-scheme) # http
println (uri:get-authority) # www.afnix.org
println (uri:get-path) # /
Character conversion
The Uri class performs automatically the character conversion in the
input uri. For example, the + character is replaced by a blank. The %
character followed by two hexadecimal values is replaced by the
corresponding ASCII character. Note that this conversion does now apply
to the query string.
Query string
The get-query method returns the query string of the uri. The query
string starts after the ? character. The query string is a series of
key-pair values separated by the & character.
const uri (afnix:www:Uri
"http://www.afnix.org?name=hello&value=world")
println (uri:get-query) # name=hello&value=world
The module also provides the UriQuery class that parses the query
string and store the result in the form of a property list. The query
string parse is particularly useful when writing automated scripts.
# create a query string object
const qs (afnix:nwg:UriQuery (uri:get-query))
# get the name value
qs:get-value "name"
Managing a cgi request
Managing a cgi request involves primarily the parsing of the requesting
uri. The uri generally contains the http referrer as well as parameter
which are stored in the form of a query string. However, depending on
the cgi method which can be of type GET or POST, the treatment is
somewhat different.
Checking the protocol version
In the presence of a cgi protocol, it is always a good idea to check
the protocol version, or at least to put an assertion. The protocol
version is normally CGI/1.1 and is stored in the GATEWAY_INTERFACE
environment variable.
# check the cgi protocol
assert "CGI/1.1" (afnix:sys:get-env "GATEWAY_INTERFACE")
Getting the query string
If the request method is GET, then the query string is available in the
environment variable QUERY_STRING. If the request method is POST, the
query string is available in the input stream. The length of the query
string is given by the CONTENT_LENGTH environment variable. The
following example illustrates the extraction of the query string.
# check the cgi protocol
assert "CGI/.1" (afnix:sys:get-env "GATEWAY_INTERFACE")
# initialize the query string
const query (afnix:sys:get-env "QUERY_STRING")
# get the request method
const rqm (afnix:sys:get-env "REQUEST_METHOD")
# check for a post request and update the query string
if (== rqm "POST") {
# create a buffer from the content length
const len (Integer (afnix:sys:get-env "CONTENT_LENGTH"))
# get the standard input stream and read content
const is (interp:get-input-stream)
const buf (is:read len)
# set the query string
query:= (buf:to-string)
}
Parsing the query string
The UriQuery class is designed to parse a cgi query string. Once the
string has been parsed, it is possible to perform a query by key since
the class operates with a property list.
const query (afnix:www:UriQuery "name=hello&value=world")
query:length # 2
query:get-value "name" # hello
query:get-value "value" # world
The UriQuery class is the foundation to build cgi script. When the
library is combined with the web application management (wam) service,
powerful applications can be built easily.
HTTP PROTOCOL OBJECT
This chapter covers the http objects of the AFNIX 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 as
well as the http reply, the client view is adopted which means that the
object is designed to operate with an output stream. On the hand, the
http response object is designed to operate as an input strem since its
represents the represents the server response that can be read by a
client. In other word, the object described here are designed for a
client perspective and not a server, where the respective object should
be reversed.
HTTP reply
The HttpReply class is a class designed to handle a HTTP reply
transaction. Most of the time, this object is not needed since it is
used by high level object. However, there is some situation where it
might become handy. For example, a CGI script needs to reply with a
text file that will be use for download. In this case, the HttpReply
object provides a simple mechanism to perform this operation.
const reply (afnix:nwg:HttpReply)
The HttpReply class operates with a buffer which is used to accumulate
characters. When the buffer is ready, this one is sent along with a
header. The HTTP 1.1 protocol requires at least to inform the client of
the content type of the data being transferred. The HttpReply has by
default a text/plain content-type property set by default. This
property can be changed at the object construction.
# create a reply object
const reply (afnix:nwg:HttpReply)
# add some data
reply:add-buffer "Hello world"
# write the reply to the output
reply:write
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 AFNIX 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 HttpReply
object can be used to install the cookie. Combined with the write
method, the cookie can be send to the http client.
STANDARD NWG SERVICES REFERENCE
This appendix is a reference of the AFNIX standard nwg services
module.
Symbol Description
afnix-nwg module
afnix:nwg nameset
Uri
The Uri class is a base object used to parse or build a uniform
resource identifier as defined by RFC 3986. The URI can be built by
specifying each component or by parsing a string. When a string is
given in the constructor, the class parses the string and extract all
components. The uri components are the scheme, the authority, the path,
the query and the fragment. The class also takes care of the character
escaping.
Predicate
uri-p
Inheritance
Object
Constructors
Uri (none)
The Uri constructor creates an empty uri object.
Uri (String)
The Uri constructor create a uri object by value. The string
argument is the uri to parse at the object construction.
Methods
parse -> none (String)
The parse method reset the uri object, parse the string argument
and fill the uri object with the result.
get-scheme -> String (none)
The get-scheme method returns the scheme of the parsed uri
object.
get-authority -> String (none)
The get-authority method returns the authority part of the
parsed uri.
get-path -> String (none)
The get-path method returns the path of the parsed uri.
get-path-target -> String (none)
The get-path-target method returns the path target of the parsed
uri. The path target is the last element of the uri path.
get-query -> String (none)
The get-query method returns the complete query string of the
parsed uri. Note that characters are not escaped when getting
the string.
get-fragment -> String (none)
The get-fragment method returns the complete query string of the
parsed uri.
get-base -> String (none)
The get-base method returns the combined uri scheme and
authority.
get-hname -> String (none)
The get-hname method returns the combined uri scheme, authority
and path.
add-path -> Uri (String)
The add-path method adds a path to the calling uri and returns a
new uri with the new path added to the old one.
get-href -> Uri (String)
The get-href method returns a new uri by eventually combining
the string argument. If the strign argument correspond to an
uri, the corresponding uri is built. Otherwise, the string
argument is considered as a pth to be added to the current uri
in order to build a new uri.
get-system-path -> String (none)
The get-system-path method returns the system path
representation of the uri path. This function works only if the
scheme if a file scheme.
get-path-encoded -> String (none)
The get-path-encoded method returns the uri in the encoded form.
Normally the get-path removes the percent-encoded characters
which might not be appropriate with some protocol such like the
http protocol. The get-path-encoded returns the original path.
Note that getting the path with getpath and doing a percent
coding might result in a different result since the internal
representation uses normalized string.
get-host -> String (none)
The get-host method returns the authority or path host name if
any can be found with respect to the scheme. With a ftp, http or
https scheme, the ost is extracted from the authority. With a
mailto scheme, the host is extracted fromthe path.
get-port -> Integer (none)
The get-port method returns the authority port if any can be
found with respect to the scheme.
UriQuery
The UriQuery class is a simple class that parses a uri query string and
build property list. during the parsing process, a special
transliteration process is done as specified by RFC 3986. This class is
primarily used with cgi scripts. Note that the string to parse is
exactly the one produced by the get-query method of the Uri class.
Predicate
uri-query-p
Inheritance
Plist
Constructors
UriQuery (none)
The UriQuery constructor creates an empty uri query object.
UriQuery (String)
The UriQuery constructor create a uri object by value. The
string argument is the uri query string to parse at the object
construction. The query string is the one obtained from the get-
query method of the Uri class.
Methods
parse -> none (String)
The parse method reset the uri query object, parses the string
argument and fill the property list object with the result.
get-query -> String (none)
The get-query method returns the original query string.
Functions
normalize-uri-name -> String (String)
The normalize-uri-name function normalizes the string argument
by adding a uri scheme if missing in the original string. If the
function detects that the name starts with a host name, the
"http" scheme is added. If the function detects that the string
starts with a path, the "file" scheme is added. otherwise, the
name argument is left untouched.
system-uri-name -> String (String)
The system-uri-name function normalizes the string argument by
prioritizing the system name. The function attempts to find a
file that match the sring argument and eventually build a uri
file scheme. If the file is not fond, the normalization process
occurs with the normalize-uri-name function.
STANDARD NWG SERVICES REFERENCE
This appendix is a reference of the http protocol service, a sub-group
of the AFNIX standard nwg services module.
HttpProto
The HttpProto class is a base class that ease the deployment of the
http protocol. The base class is built with a property list which is
used to define the message header. The class also defines the write
methods which are used to write a message either on an output stream or
into a buffer.
Inheritance
Object
Methods
set-header -> none (String Literal)
The set-header method adds a new property to the http header.
The first argument is the property name. The second argument is
a literal object which is internally converted to a string.
write -> none (none|Output|Buffer)
The write method formats and writes the http header to an output
stream or a buffer. Without argument, the default output stream
is used.
HttpRequest
The HttpRequest class class is a base class designed to format a http
request. The class operates with the protocol version 1.1 as defined by
RFC 2616. A request is formatted with a request command and a uri.
Predicate
http-request-p
Inheritance
HttpProto
Constructors
HttpRequest (String)
The HttpRequest constructor creates a http request object with a
specific command. The string argument is the request command to
use.
HttpRequest (Uri)
The HttpRequest constructor creates a http request object with a
uri. The default request command is "GET".
HttpRequest (String String)
The HttpRequest constructor creates a http request object with a
specific command and a uri name. The first string argument is
the request command to use. The second string argument is the
uri attached to the command. Note that the term uri should be
understood as a request uri those scope applies to the whole
server with certain commands such like the option command.
HttpRequest (String Uri)
The HttpRequest constructor creates a http request object with a
specific command and a uri. The first string argument is the
request command to use. The second argument is the uri attached
to the command.
Methods
write -> none (none|Output|Buffer)
The write method formats and writes the request to an output
stream or a buffer. Without argument, the default output stream
is used.
set-command -> none (String)
The set-command method sets the command request. This method
does not check that the command is a valid HTTP command; thus
leaving plenty of room for server development. As a matter of
fact, RFC 2616 does not prohibit the existence of such
extension.
get-command -> String (none)
The get-command method returns the request command string.
set-uri -> none (String)
The set-uri method sets the request uri. The argument string
does not have to be a valid uri string since some commands might
accept special string such like "*" to indicate all applicable
uri.
get-uri -> String (none)
The get-uri method returns the request uri string.
HttpResponse
The HttpResponse class class is a http protocol class that handle the
response following a http request. The response from a request
generally contains a status line followed by a header and the body. The
class is bound to an input stream which is used to read characters. The
object encoding mode is set automatically from the header if it is
available.
Predicate
http-response-p
Inheritance
Input
Constructors
HttpResponse (none)
The HttpResponse constructor creates a default http response
object. Without an input stream bound to it, the class operates
like an input stream which operate on a character buffer.
HttpResponse (Input)
The HttpResponse constructor creates a http response object with
a specific input stream. At construction, the local buffer is
reset and the input stream is bound to the object. The input
stream is subsequently read to determine the response nature.
Methods
reset -> none (none)
The reset method reset the http response stream by clearing the
local input buffer and the response header. The bound input
stream is not touched.
get-status-code -> Integer (none)
The get-status-code method returns the response status code. If
the response was not succesfully read, the status code is 0.
ok-p -> Boolean (none)
The ok-p predicate returns true is the response status code is
valid (aka status 200).
encoding-mode-p -> Boolean (none)
The encoding-mode-p predicate returns true is encoding mode is
defined in the header. If not, it might be desirabe to set the
stream encoding mode.
location-p -> Boolean (none)
The location-p predicate returns true is the response status
code indicates that a request should be made at another
location. The location can be found with the get-location
method.
get-location -> String (none)
The get-location method returns the loction uri found in the
response header. This method is equivalent to a header query.
get-media-type -> String (none)
The get-media-type method returns the media type found in the
response header. This method is equivalent to a header query.
set-input-stream -> none (Input)
The set-input-stream method binds an input stream to the http
response object. Once the stream is bound, the input stream is
read to determine the nature of the response. In particular, the
response header is parsed automatically and the stream is ready
to operate like any other input stream. If the header contains a
length attribute, the read method and the associated predicate
will behave like a stream which has reached its end when the
number of characters read reach the content length.
header-length -> Integer (none)
The header-length method returns the number of entries in the
response header.
header-get -> Property (Integer)
The header-get method returns a header entry by index. The
integer argument is the header index. The result is in the form
of a property object.
header-find -> Property (String)
The header-find method returns a header entry by name. The
string argument is the property name. The result is in the form
of a property object. If the entry is not found, the nil object
is returned.
header-lookup -> Property (String)
The header-lookup method returns a header entry by name. The
string argument is the property name. The result is in the form
of a property object. If the entry is not found, an exception is
raised.
header-get-value -> String (String)
The header-get-value method returns a header value by name. The
string argument is the header property name. If the entry is not
found, an exception is raised.
HttpReply
The HttpReply class is a simple designed to format a http reply. The
class holds a property list which is used to format the header and a
buffer which is the reply content. When the write method is called, the
header and the buffer is formatted to the output stream argument. The
class creates initially the content-type property which is initialized
to the text/plain mime value.
Predicate
http-reply-p
Inheritance
HttpProto
Constructors
HttpReply (none)
The HttpReply constructor creates an empty http reply object.
HttpReply (String)
The HttpReply constructor creates a http reply object with a
specific content type. The string argument is the mime content
type to set.
Methods
add-buffer -> none (Literal|Buffer)
The add-buffer method adds some content to the HTTP reply
buffer. The argument can be either a literal r a buffer object.
write -> none (none|Output|Buffer)
The write method formats and writes the reply to an output
stream or a buffer. Without argument, the default output stream
is used.
set-cookie -> none (Cookie)
The set-cookie method sets a cookie object to the http header.
The cookie version is properly handled by the method.
set-status -> none (Integer)
The set-status method sets a reply status code. The code must be
a valid http status code. The method takes care to format
properly the status message. Note that a reply body can be
attached to describe the message status. Note also that RFC 2616
prohibits the presence of a message body with the status code
1xx (informational), 204 (no content) and 304 (not modified).
This rule is enforced by the class.
redirect -> none (String)
The redirect method set the message status to indicate that the
page should be redirected to the specified uri. The string
argument is the target uri. The method operates by setting a
status code 303 (see other) in the header. If a temporary
redirection is preferable, the implementor is advised to set
manually the appropriate status code.
Cookie
The Cookie class is a special class designed to handle cookie setting
within a http transaction. A cookie is name/value pair that is set by
the server and stored by the http client. Further connection with the
client will result with the cookie value transmitted by the client to
the server. A cookie has various parameters that controls its existence
and behavior. The most important one is the cookie maximum age that is
defined in seconds. A null value tells the client to discard the
cookie. A cookie without maximum age is valid only during the http
client session. A cookie can be added to the HttpReply object with the
set-cookie method. A cookie can be constructed with a name/value pair.
An optional third argument is the maximum age. The default cookie
version is 1 as specified by RFC 2965. With a version 1, the maximum
age is interpreted as the number of seconds before the cookie expires.
With version 0, the maximum age is the absolute time.
Predicate
cookie-p
Inheritance
Object
Constructors
Cookie (String String)
The Cookie constructor creates a cookie with a name value pair.
The first argument is the cookie name. The second argument is
the cookie value.
Cookie (String String Integer)
The Cookie constructor creates a cookie with a name value pair
and a maximum age. The first argument is the cookie name. The
second argument is the cookie value. The third argument is the
cookie maximum age.
Methods
get-version -> Integer (none)
The get-version method returns the cookie version.
set-version -> none (Integer)
The set-version method sets the cookie version. The version
number can only be 0 or 1.
get-name -> String (none)
The get-name method returns the cookie name. This is the name
store on the http client.
set-name -> none (String)
The set-name method sets the cookie name. This is the name store
on the http client.
get-value -> String (none)
The get-value method returns the cookie value. This is the value
stored on the http client bounded by the cookie name.
set-value -> none (String)
The set-value method sets the cookie value. This is the value
store on the http client bounded by the cookie name.
get-maximum-age -> Integer (none)
The get-maximum-age method returns the cookie maximum age. The
default value is -1, that is, no maximum age is set and the
cookie is valid only for the http client session.
set-maximum-age -> none (Integer)
The set-maximum-age method sets the cookie maximum age. A
negative value is reset to -1. A 0 value tells the http client
to discard the cookie. A positive value tells the http client to
store the cookie for the remaining seconds.
get-path -> String (none)
The get-path method returns the cookie path value. The path
determines for which http request the cookie is valid.
set-path -> none (String)
The set-path method sets the cookie path value. The path
determines for which http request the cookie is valid.
get-domain -> String (none)
The get-domain method returns the cookie domain value.
set-domain -> none (String)
The set-domain method sets the cookie domain value. It is string
recommended to use the originator domain name since many http
client can reject cookie those domain name does not match the
originator name.
get-port -> Integer (none)
The get-port method returns the cookie port number.
set-port -> none (Integer)
The set-port method sets the cookie port number. This value is
not used with a cookie version 0.
get-comment -> String (none)
The get-comment method returns the cookie comment value.
set-comment -> none (String)
The set-comment method sets the cookie comment value.
get-comment-url -> String (none)
The get-comment-url method returns the cookie comment url value.
set-comment-url -> none (String)
The set-comment-url method sets the cookie comment url value.
This value is not used with cookie version 0.
get-discard -> Boolean (none)
The get-discard method returns the cookie discard flag.
set-discard -> none (Boolean)
The set-discard method sets the cookie discard flag. The discard
flag the tells the user agent to destroy the cookie when it
terminates. This value is not used with cookie version 0.
get-secure -> Boolean (none)
The get-secure method returns the cookie secure flag.
set-secure -> none (Boolean)
The set-secure method sets the cookie secure flag. When a cookie
is secured, it is only returned by the http client if a
connection has been secured (i.e use https).
to-string -> String (none)
The to-string method returns a string formatted for the http
reply header. Normally this method should not be called since
the set-cookie method of the httpReply takes care of such thing.