Skip to content

Fermion – The Scheme Web Server

August 19, 2009

Fermion is a fast and secure web server written in Scheme. It is optimized to serve dynamic content generated by Scheme scripts. It is part of the larger Spark-Scheme project. It uses light-weight green threads to handle client requests and can efficiently serve thousands of simultaneous connections.

The following code starts an instance of Fermion:


;; file: my-http.ss

(import (net)
        (http))    
(web-server-start (web-server))

Create a HTML file called index.html and place it along with my-http.ss. This will be the default page served by our http server.

Start the web server with the command `spark my-http.ss’. Now you can access index.html with the URL: http://localhost.

The forte of Fermion is not in serving static files, but in generating content dynamically based on user input or some other volatile parameter. Let us write a simple web application that will greet the user based on the time of the day.


;; file: greet.ss

(import (aura))

(define (greet new-uri state)
 (((sgml 

 `(html
   (body
    (b ,(greeting-by-hour)))))

 'text)))

(define (greeting-by-hour)
 (let ((hour (date-hour (seconds->date (current-seconds)))))
    (cond ((<= hour 12) "Good morning!")
          ((<= hour 17) "Good afternoon!")
          (else "Good evening"))))

(list greet)

&#91;/sourcecode&#93;

The procedure <em>greet</em> will be executed by the web server, by passing it two arguments. <em>new-uri</em> will be a dynamically generated URI to which any further requests, like a form POST, should be send. <em>state</em> is a hash table that contains the current state of the session. For instance, it will contain values posted by previous requests. The web application exports a list of procedures that will be executed by Fermion, in the given order. Thus the programmer can design a web application as a sequence of operations, much like a normal console program. The <em>greet</em> sample also makes use of a library called <em>aura</em> which can be used to write SGML documents in Scheme syntax.

Fermion is a <em>secure </em>web server. It is possible to impose some control over HTTP requests by using configuration options. An example is given below:



(define httpd (web-server
                (list 'port 8080 ;; Web server will listen on port 8080.
                      'session-timeout (* 2 60) ;; 2 minutes
                      'max-header-length (* 112 1024) ;; Size of request header
                                                      ;; limited to 112kb.
                      'max-body-length (* 512 1024) ;; Size of request body limited to
                                                    ;; 512kb.
                      'max-response-size (* 512 1024)))) ;; Size of response limited to
                                                         ;; 512kb.

Fermion provide hooks where new procedures can be plugged-in to implement advanced security and compliance features. For instance, the following sample shows how to hook a procedure to check the length of the request URI. If the URI contain more than 512 characters, the request will be blocked.


(import (net)
        (http-request-parser)
        (http))

(define httpd (web-server))

;; The security hook procedure.
(define (check-uri-length httpd
                          client-connection
                          http-request)
 (cond ((> (string-length (http-request-uri http-request)) 512)
        (printf "Request URI too long. Closing connection.~n")
        (flush-output)
        (socket-close (connection-socket client-connection))
        #f)
       (else ;; Let the web server's request handler do its job.    
        #t)))

(web-server-hook! httpd 'before-handle-request check-uri-length)
(web-server-start httpd)

User defined policies can be applied on the response by using the ‘before-send-response hook.

I hope that Scheme hackers will find Fermion useful in their real-world web development tasks.

Links:
Fermion documentation.

No comments yet

Leave a comment