Common Lisp Package: S-HTTP-SERVER

S-HTTP-SERVER is a minial standalone Common Lisp HTTP Server

README:

S-HTTP-SERVER

A Minimal Standalone Common Lisp HTTP Server

S-HTTP-SERVER is a minimal standalone HTTP Server. This simple package is used as a building block in a number of other open source projects.

Contents

Features

S-HTTP-SERVER can:

  • handle HTTP requests and generate HTTP responses
  • be configured with plugins or handlers
  • has a builtin status handler
  • comes with a static resource handler, favicon handler and redirect handler
  • allows you to write and install your own handlers
  • support HTTPS on LispWorks

Status

S-HTTP-SERVER is considered stable code.

News

Platforms

S-HTTP-SERVER is written in ANSI standard Common Lisp and should be portable across any CL implementation.

Installation

The S-HTTP-SERVER package is loaded using ASDF. There is an excellent tutorial on ASDF to get you started.

CL-USER 1 > (asdf:oos 'asdf:load-op :`S-HTTP-SERVER`) 

Usage

Basically, you create an S-HTTP-SERVER object and start it. Out of the box only the status/debug page http://localhost:1701/s-http-server is served. By registering new context handlers you can configure the server further. The static-resource-handler hosts static documents from a root directory in the file system. It is possible to write your own handlers, look at the code of static-resource-handler and S-HTTP-SERVER-handler for guidance.

CL-USER 1 > (in-package :`S-HTTP-SERVER`)  
#<The `S-HTTP-SERVER` package, 90/128 internal, 31/64 external>  
 
`S-HTTP-SERVER` 2 > (defvar *server* (make-`S-HTTP-SERVER`))  
*SERVER*  
 
`S-HTTP-SERVER` 3 > (start-server *server*)  
;; `S-HTTP-SERVER`: Started a new server on port 1701  
#<`S-HTTP-SERVER` "`S-HTTP-SERVER`" port 1701 running 10C5F6EB>  
 
`S-HTTP-SERVER` 4 > (register-context-handler *server* "/my-site" 'static-resource-handler :arguments '("/var/www/"))  
((STATIC-RESOURCE-HANDLER "/my-site" "/var/www/") (`S-HTTP-SERVER`-HANDLER "/`S-HTTP-SERVER`" :BUILTIN))  
 
`S-HTTP-SERVER` 5 > (stop-server *server*)  
;; `S-HTTP-SERVER`: Stopped server  
#<`S-HTTP-SERVER` "`S-HTTP-SERVER`" port 1701 not running 10C5F6EB>

Jean-François Brouillet has written an excellent tutorial on using S-HTTP-SERVER, complete with screenshots and code examples.

API Reference

There is automatically generated API Reference documentation available for the S-HTTP-SERVER package.

Mailinglist

The KPAX mailing list is used for this project.

Changelog

Release Notes:

  • release 1: moved S-HTTP-SERVER into a seperate project under a new structure

TODO

There is currently no TODO list.

FAQ

Nothing appropriate.

Bugs

There are no known bugs.

Authors

S-HTTP-SERVER was written by Sven Van Caekenberghe.

Maintainers

S-HTTP-SERVER is being maintained by Sven Van Caekenberghe.

License

You are granted the rights to distribute and use this software as governed by the terms of the Lisp Lesser General Public License (http://opensource.franz.com/preamble.html), also known as the LLGPL.

History

This is a new project.

References

The reference for the HTTP protocol is RFC 2616. Also worth reading is the Wikipedia article about HTTP.

Copyright © 2005, 2006 Sven Van Caekenberghe, Beta Nine BVBA. All Right Reserved.

FUNCTION

Public

ACCEPTS-GZIP-ENCODING-P (HTTP-REQUEST)

Return T when http-request accepts gzip content encoding

COMPRESSIBLE-MIME-TYPE-P (MIME-TYPE)

Return T when mime-type is compressible using gzip

CONFIGURE-DEFAULT-HANDLERS (S-HTTP-SERVER)

Setup a set of default handlers to a server

FAVICON-HANDLER (S-HTTP-SERVER HANDLER HTTP-REQUEST STREAM)

Handle that annoying favicon.ico request in a more elegant way

GZIP-COMPRESS (IN COMPRESSOR BYTE-BUFFER)

Compress input stream or function in using gzip, returning (values data-chunks data-size)

MAKE-S-HTTP-SERVER (&KEY (PORT *HTTP-SERVER-PORT*) (NAME s-http-server) (LOG-STREAM *STANDARD-OUTPUT*) (ACCESS-LOG-STREAM *STANDARD-OUTPUT*))

Create a new object representing an S-HTTP-SERVER

PS (S-HTTP-SERVER)

Show the state of all http connections known to the server

REDIRECT-HANDLER (S-HTTP-SERVER HANDLER HTTP-REQUEST STREAM)

This handler immediately redirects to another URL

REQUEST-HEADER-VALUE (HTTP-REQUEST HEADER-NAME)

Get the value of a named header of http-request

S-HTTP-SERVER-HANDLER (S-HTTP-SERVER HANDLER HTTP-REQUEST STREAM)

The builtin S-HTTP-SERVER testing/debugging handler returning a simple status/echo/snoop page

STANDARD-HTTP-HTML-ERROR-RESPONSE (HTTP-REQUEST STREAM CODE REASON EXTRA)

Generate and write a standard HTML error as HTTP Response using code, reason and extra

STANDARD-HTTP-HTML-MESSAGE-RESPONSE (HTTP-REQUEST STREAM TITLE MESSAGE &OPTIONAL (STATUS 200) (STRING OK))

Generate and write a standard HTML message as HTTP Response using title, message, status and string

STANDARD-HTTP-RESPONSE-HEADERS (HTTP-REQUEST &KEY (CONTENT-TYPE text/plain) CONTENT-LENGTH)

Generate the standard headers alist given context-type and context-length, managing old-style Keep-Alive

STATIC-RESOURCE-HANDLER (S-HTTP-SERVER HANDLER HTTP-REQUEST STREAM)

Host static resources from a document root

TOGGLE-CONNECTION-POOLING (S-HTTP-SERVER ON-OFF)

Turn (global) connection pooling on or off

WRAP-WITH-BASIC-AUTHENTICATION (HANDLER-FUNCTION &KEY ARGUMENTS AUTHENTICATOR REALM)

Creates and returns a new handler that wraps handler-function and argument with basic authentication. Authenticator is either a dotted alist of usernames and passwords or a function accepting (username . password). Realm is for use in the WWW-Authenticate header response.

WRITE-HTTP-RESPONSE-HEADERS (HEADERS STREAM)

Write the headers alist as HTTP Response Headers to stream

WRITE-HTTP-RESPONSE-LINE (STRING &OPTIONAL (STREAM *STANDARD-OUTPUT*))

Write string to stream, ending with the HTTP end of line convention (CR+LF)

WRITE-HTTP-RESPONSE-STATUS-LINE (STREAM &OPTIONAL (STATUS-CODE 200) (STRING OK) (HTTP-VERSION HTTP/1.1))

Write an HTTP Response Status line to stream, using status-code string and http-version

Private

AUTHORIZED-P (BASIC-AUTHORIZATION AUTHENTICATOR)

Check whether a basic-authorization is authorized by authenticator

DECODE-BASIC-AUTHORIZATION (AUTHORIZATION)

Decode the Base64 encoding of username:password returning (username . password)

ECHO-DEBUG-HANDLER (S-HTTP-SERVER HANDLER HTTP-REQUEST STREAM)

An echoing testing/debugging handler returning a simple text/plain status/echo/snoop page

HOST-STATIC-BYTES (HTTP-REQUEST STREAM BYTES &KEY EXPIRES-MAX-AGE (MIME-TYPE application/octet-stream) LAST-MODIFIED (START 0) END)

Return (values t <response-code> <size>) handling condition GET as well

HOST-STATIC-RESOURCE (HTTP-REQUEST STREAM RESOURCE-PATHNAME &KEY EXPIRES-MAX-AGE)

Return (values t <response-code> <size>) handling conditional GET as well

PARSE-HTTP-DATE (STRING)

Return the CL universal-time represented in string using GMT HTTP Date format, or nil on error

PS-HANDLER (S-HTTP-SERVER HANDLER HTTP-REQUEST STREAM)

Show the state of all http connections known to the server

RANDOM-HANDLER (S-HTTP-SERVER HANDLER HTTP-REQUEST STREAM)

Return a random hex string of a specified size

READ-CRLF-LINE (LINE-BUFFER STREAM &OPTIONAL (EOF-ERROR-P T) EOF-VALUE)

Read a CRLF termintated line from a character input stream into line-buffer. Return length excluding CRLF.

RESPONSE-DATE (&OPTIONAL (UNIVERSAL-TIME (GET-UNIVERSAL-TIME)))

Generate a GMT HTTP Response Date

Undocumented

BASIC-AUTHENTICATION-REQUIRED-HTTP-RESPONSE (HTTP-REQUEST STREAM REALM)

COMPUTE-REAL-RESOURCE-PATHNAME (ROOT PATH CONTEXT PATHNAME-BUILDER)

DW-BENCH (S-HTTP-SERVER HANDLER HTTP-REQUEST STREAM)

ESCAPE (STRING)

FORMAT-HTTP-RESPONSE-LINE (STREAM FORMAT-STRING &REST ARGS)

HEADER-FIELD-NAME->KEYWORD (STRING &OPTIONAL (START 0) END)

HEADER-FIELD-VALUE->STRING (STRING &OPTIONAL (START 0) END)

HELLO-WORLD (S-HTTP-SERVER HANDLER HTTP-REQUEST STREAM)

MAKE-REAL-RESOURCE-PATHNAME (ROOT-DIR-COMPONENTS URI-DIR-COMPONENTS NAME TYPE)

MIME-TYPE-FOR-PATHNAME (PATHNAME)

MIME-TYPE-SUFFIX-MAP

PARSE-HTTP-REQUEST (STREAM LINE-BUFFER)

PARSE-HTTP-REQUEST-HEADERS (STREAM LINE-BUFFER)

PARSE-HTTP-REQUEST-LINE (STREAM LINE-BUFFER)

GENERIC-FUNCTION

Public

FIND-HANDLER (SERVER HTTP-REQUEST)

Given http-request select a handler from server

GET-FULL-PATH (HTTP-REQUEST)

Get the full path of this HTTP request (including the query)

GET-PATH (HTTP-REQUEST)

Get the path of this HTTP request

HANDLE-HTTP-SERVER-CONNECTION (SERVER HTTP-CONNECTION)

Handle connection requests

LOGM (SERVER KIND FORMAT-STRING &REST ARGS)

Log a formatted message

REGISTER-CONTEXT-HANDLER (SERVER CONTEXT-PREFIX HANDLER-FUNCTION &KEY ARGUMENTS AT-END-P DO-NOT-REPLACE-P)

Configure server so that every request starting with context-prefix is sent to handler-function

START-SERVER (SERVER)

Start the server

STOP-SERVER (SERVER)

Stop the server

UNREGISTER-CONTEXT-HANDLER (SERVER CONTEXT-PREFIX &KEY ONLY-FIRST-P ONLY-LAST-P)

Remove any configuration of server for context-prefix

Undocumented

GET-BYTE-BUFFER (HTTP-CONNECTION)

GET-GZIP-COMPRESSOR (HTTP-CONNECTION)

Private

Undocumented

CLEANUP-ALL-POOLED-CONNECTIONS (S-HTTP-SERVER)

CLEANUP-CONNECTIONS (S-HTTP-SERVER &KEY (FILTER 'IDENTITY) (SELECTOR 'IDENTITY) DO-NOT-POOL (THRESHOLD 0))

CLEANUP-DEAD-CONNECTIONS (S-HTTP-SERVER)

CLEANUP-EXCESS-ALIVE-CONNECTIONS (S-HTTP-SERVER)

CLEANUP-EXCESS-POOLED-CONNECTIONS (S-HTTP-SERVER)

CLEANUP-OLD-CONNECTIONS (S-HTTP-SERVER)

CLEANUP-OLD-POOLED-CONNECTIONS (S-HTTP-SERVER)

DO-PERIODIC-CHECK (S-HTTP-SERVER)

FLUSH-LOG-STREAMS (S-HTTP-SERVER)

GET-AGE (HTTP-CONNECTION)

HANDLE-NEW-HTTP-SERVER-CONNECTION (S-HTTP-SERVER SOCKET-STREAM CONNECTION-ID)

HANDLE-ONE-HTTP-REQUEST-RESPONSE (S-HTTP-SERVER HTTP-CONNECTION)

KILL-CONNECTION (HTTP-CONNECTION &OPTIONAL DO-NOT-POOL)

LOG-ACCESS (S-HTTP-SERVER HTTP-CONNECTION HTTP-REQUEST RESPONSE BYTES)

SLOT-ACCESSOR

Public

Undocumented

GET-ACCESS-LOG-STREAM (OBJECT)

SETFGET-ACCESS-LOG-STREAM (NEW-VALUE OBJECT)

GET-BOOT-TIME (OBJECT)

SETFGET-BOOT-TIME (NEW-VALUE OBJECT)

GET-CONTEXTS (OBJECT)

SETFGET-CONTEXTS (NEW-VALUE OBJECT)

GET-DEBUG-MODE (OBJECT)

SETFGET-DEBUG-MODE (NEW-VALUE OBJECT)

GET-HEADERS (OBJECT)

SETFGET-HEADERS (NEW-VALUE OBJECT)

GET-HTTP-CONNECTION (OBJECT)

SETFGET-HTTP-CONNECTION (NEW-VALUE OBJECT)

GET-HTTP-CONNECTIONS (OBJECT)

SETFGET-HTTP-CONNECTIONS (NEW-VALUE OBJECT)

GET-HTTP-SERVER (OBJECT)

SETFGET-HTTP-SERVER (NEW-VALUE OBJECT)

GET-HTTP-VERSION (OBJECT)

SETFGET-HTTP-VERSION (NEW-VALUE OBJECT)

GET-KEEP-ALIVE (OBJECT)

SETFGET-KEEP-ALIVE (NEW-VALUE OBJECT)

GET-LINE-BUFFER (OBJECT)

SETFGET-LINE-BUFFER (NEW-VALUE OBJECT)

GET-LOG-STREAM (OBJECT)

SETFGET-LOG-STREAM (NEW-VALUE OBJECT)

GET-METHOD (OBJECT)

SETFGET-METHOD (NEW-VALUE OBJECT)

GET-NAME (OBJECT)

SETFGET-NAME (NEW-VALUE OBJECT)

GET-PORT (OBJECT)

SETFGET-PORT (NEW-VALUE OBJECT)

GET-SERVER-PROCESS (OBJECT)

SETFGET-SERVER-PROCESS (NEW-VALUE OBJECT)

GET-URI (OBJECT)

SETFGET-URI (NEW-VALUE OBJECT)

GET-USER (OBJECT)

SETFGET-USER (NEW-VALUE OBJECT)

Private

Undocumented

GET-ID (OBJECT)

SETFGET-ID (NEW-VALUE OBJECT)

GET-LAST-PERIODIC-CHECK (OBJECT)

SETFGET-LAST-PERIODIC-CHECK (NEW-VALUE OBJECT)

GET-LOG-LOCK (OBJECT)

SETFGET-LOG-LOCK (NEW-VALUE OBJECT)

GET-PROCESS (OBJECT)

SETFGET-PROCESS (NEW-VALUE OBJECT)

GET-REQUEST-COUNT (OBJECT)

SETFGET-REQUEST-COUNT (NEW-VALUE OBJECT)

GET-STATE (OBJECT)

SETFGET-STATE (NEW-VALUE OBJECT)

GET-STREAM (OBJECT)

SETFGET-STREAM (NEW-VALUE OBJECT)

GET-TIMESTAMP (OBJECT)

SETFGET-TIMESTAMP (NEW-VALUE OBJECT)

VARIABLE

Public

*FAVICON*

If not nil, the pathname to a favicon.ico or a (unsigned-byte 8) array representing a favicon

*HTTP-SERVER-IDENTIFICATION*

Identification string sent as value of the 'Server' HTTP Response Header

*HTTP-SERVER-PORT*

Default port used when creating a new S-HTTP-SERVER

*LAST-HTTP-REQUEST*

The last HTTP-REQUEST object handled by S-HTTP-SERVER

+ENABLE-GZIP-COMPRESSION+

Use Salza2 to GZIP compress certain mime types

Private

*MIME-TYPE-SUFFIX-MAP*

Hashtable mapping suffixes to mime-types, computed at run-time

+ACCESS-LOG-FORMAT+

Either :common-log-format or :extended-common-log-format

+ALLOWED-CONNECTION-KEEPALIVE-AGE+

Number of seconds a kept alive connection is allowed to be inactive (Apache default)

+ALLOWED-CONNECTION-POOLED-AGE+

Number of seconds a pooled connection is allowed to exist

+ALLOWED-HTTP-METHODS+

The HTTP methods that we allow in the request line

+ALLOWED-KEEPALIVE-CONNECTIONS+

Maximum number of simulataneous kept alive connections (hard resoure limit)

+ALLOWED-POOLED-CONNECTIONS+

Maximum number of inactive connections allowed in the pool

+BASIC-MIME-TYPE-SUFFIX-MAP+

Fallback for when no mime-type info can be loaded from a known location

+COMPRESSIBLE-MIME-TYPES+

The list of mime-types that can/should be gzip compressed

+KNOWN-MIME.TYPE-LOCATIONS+

Places to search for a system level mime-type to suffix map

+PERIOD-CHECK-INTERVAL+

Do some periodic checks every 5 seconds

+POOL-CONNECTIONS+

If t, pool connections, reusing processes and resources

Undocumented

*DOCTYPE-HTML-401-STRICT*

*DOCTYPE-HTML-401-TRANSITIONAL*

+COMMON-LOG-TIMESTAMP-FORMAT+

+COMMON-REQUEST-HEADERS+

CLASS

Public

HTTP-REQUEST

The object representing an HTTP request as being handled by the S-HTTP-SERVER

S-HTTP-SERVER

The object representing a minimal standalone HTTP Server

Private

HTTP-CONNECTION

The object representing a kept-alive HTTP connection and handling process

CONDITION

Private

Undocumented

BOGUS-HTTP-REQUEST-METHOD

BOGUS-HTTP-REQUEST-URI

HTTP-REQUEST-ERROR

MISSING-HTTP-REQUEST-LINE