Request and Response modules for newLISP

Together, these two modules form a coherent replacement for the newLISP CGI module. They can be found here.

The Request module parses GET, POST, and COOKIE data and provides a few simple functions to retrieve these values. Values may be looked up by key using:

(Request:get "foo")
(Request:post "foo")
(Request:cookie "foo")

POST data is restricted to 4096 bytes. This can be altered by editing the *max-post-length* constant. I have included a few useful predicates:

(Request:get?)
(Request:post?)
(Request:cookie? "foo")

The request method can be directly determined using (Request:method). The path and domain are stored in Request:path and Request:domain, respectively. I included one other feature of interest for those who use mod_rewrite to create pretty urls.
(Request:segment) allows access to the individual url path segments. If called with an integer argument, it will attempt to return the segment at that index. Calling a higher index than exists results in an out of bounds error. If (Request:segment) is called sequentially, it will return the next segment in the list until there are no more segments left, after which it will return nil. Sample usage:

(while (set 's (Request:segment))
    (do-something-with s))

Additionally, the entire set of segments can be accessed as a list using (Request:segments).

The Response module contains functions to control the output of HTTP headers. Generic headers may be set using (Response:header "foo" "bar") and the current set of headers may be queried with (Response:header? "foo"). Content-type is handled automatically, although it may be overridden, e.g. (Response:header "Content-type" "text/plain"). The default content type is text/html; charset=utf-8.

Adding display content to the response in simple.
(Response:write "foo") will modify the content in place. This may be overridden when outputting the content using the default functor, e.g. (Response "foo"). The result of this is a string; it must be printed to the browser. Other types of output may be achieved with various functions:

(print (Response:redirect "/some/other/path/"))
(print (Response:error "
 
Some error has occurred
 
"))
(print (Response:not-found "
 
Page not found
 
"))

There are usage examples at the top of the module. Custom handlers need only override the internal function, (Response:_response), which simply outputs the entire page, including headers.

Cookies are dealt with using generic syntax and are automatically added to response output.

(Response:set-cookie "foo" "bar")
(Response:delete-cookie "foo")

Finally, one thing that users of the CGI module may miss is the put-page routine. At the moment, there is no equivalent to this in the Response module. I am currently working on a Template module that will provide similar functionality. Until then, there is no reason that put-page could not be copied and pasted into Response (or elsewhere) as required.

One note of warning:
Request and the newLISP CGI module will not work together. Once the POST data has been read from stdin, it is consumed. Whichever module is called first will have the POST data, which will be unavailable to the other module.

Leave a comment | Trackback
Feb 22nd, 2008 | Posted in Programming, Software
Tags: ,
No comments yet.