# Standard network working group

This chapter covers the fundamental objects of the standard network working group module. This modules contain object that are generally defined by a RFC and used in networking application.

## The uri class

The `Uri` class is a base class that parses 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.

## Special functions

Several dedicated functions are available in the library as a way to ease the object manipulations. Theses functions operate mostly on uri and files as described below.

### Uri functions

Several functions are designed to ease the uri manipulation. Most of them operate on the uri name or their associated system name. The `normalize-uri-name` function normalizes a 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. 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.

# normalize a uri name trans unm "http://www.afnix.org" assert unm (afnix:nwg:normalize-uri-name unm) assert unm (afnix:nwg:normalize-uri-name "www.afnix.org") assert unm (afnix:nwg:normalize-uri-name "//www.afnix.org")

### Mime functions

Mime functions are dedicated to easee the mainpulation of media types or mime. A media type is defined by a string in the form of a type and content value such as text/plain. The `mime-value-p` predicate returns true if a string mime value is a valid media type. From a file perspective, the `mime-extension-p` predicate returns true if the string extension has a valid media type associated to it. Finally, the `extension-to-mime` function can be used to get the string mime value associated with a file extension.

# check a media type assert true (afnix:nwg:mime-value-p "text/plain") # check the mime extension predicate assert true (afnix:nwg:mime-extension-p "txt") # check the extension to mime assert "text/plain" (afnix:nwg:extension-to-mime "txt")