Introduction to AllegroServe Tutorial

Go to the tutorial main page.

Other AllegroServe tutorials include GET requests tutorial, POST requests tutorial, Multipart requests tutorial, and Redirects tutorial.

AllegroServe is an HTTP server and HTML generator for Lisp. As with other HTTP servers, such as Apache (Unix) or the Internet Information Services (Windows), AllegroServe can be used to deliver web pages and other data over a TCP/IP network (such as the Internet) to internet browsers such as Firefox, Mozilla, and the Internet Explorer.

Quick Start 1: Publish static single file

For this example, we create a file called c:\tutorials\myfile.html and demonstrate how to serve this file when requested from an HTTP client such as an internet browser. This process is called publishing.

The actual pathname for this example is unimportant. Except for pathname naming differences between Unix and Windows, all of these examples work identically on all Allegro CL platforms.

Steps:

  1. Create the file c:\tutorials\myfile.html with the following contents:
    <html>
    <head><title> My Page Title </title></head>
    <body>
    <p> My Page's first paragraph. </p>
    </body>
    </html>
  2. In Allegro CL, evaluate the following forms:
    > (require :aserve)
    > (net.aserve:start :port 8000)
    > (net.aserve:publish-file :path "/myfile" :file "c:/tutorials/myfile.html")
  3. Using an internet browser such as Firefox, Mozilla, or the Internet Explorer, visit the location http://localhost:8000/myfile. You should see a page with the text "My Page's first paragraph".
  4. [Optional] Let us assume the machine being used is accessible over a TCP/IP network with the name machine_a.mycompany.com. On a second machine in that network, open an internet browser and visit the location http://machine_a.mycompany.com:8000/myfile. You should see a page with the text "My Page's first paragraph".

Notes:

Step 2: The (require :aserve) statement ensures AllegroServe is present in the current Lisp environment.
The :file argument is being specified using forward slashes. You can use either forward or backward slashes to name the file. Backward slashes have to be escaped to be read by the Lisp reader. The argument could have been specified as :file "c:\\tutorials\\myfile.html".
The (net.aserve:start :port 8000) statement starts the AllegroServe server. You only need to start the server once in an AllegroServe session. (Specifically, you do not need to restart it for other examples below if you are running them in a single Lisp session.) Note that we use :port 8000 to specify that AllegroServe listen for incoming requests on TCP/IP port 8000. If this port is unavailable, which is possible if another process on the computer is already using the port, then you can pick another port number and use that number where we use 8000. The standard port for http service is 80, which is the default value of the :port argument. In other words, you can start the AllegroServe server using just (net.aserve:start). Note that on Unix, you have to be superuser to use ports numbered below 1024.
Step 4: If machine_a.mycompany.com is behind a firewall, you need to ensure that the second machine can access machine_a's port 8000. This may require a firewall adjustment.

Quick Start 2: Publish static directory tree.

We demonstrate how to publish a directory tree of html documents by publishing the html-formatted documentation directory included with Allegro CL. (Because the Student and Trial version are distributed without the doc/ subdirectory, if you are using those version, you must download the documentation in order for this example to work. See https://franz.com/documentation/ to download the documentation.)

Steps:

  1. In Allegro CL, evaluate the following forms:
    > (require :aserve)
    > (net.aserve:start :port 8000)
    > (net.aserve:publish-directory
        :prefix "/acl-doc" 
        :destination (namestring (translate-logical-pathname #p"sys:doc")))
  2. Using an internet browser such as Firefox, Mozilla, or the Internet Explorer, visit the location http://localhost:8000/acl-doc. You should see the index page for the Allegro CL documentation. As you navigate this page by following links, you should be able to see from the address bar in your browser that the pages are being served using location addresses prefixed by http://localhost:8000/acl-doc/[...]. This indicates the browser is interacting with an HTTP server, that being our AllegroServe session.
  3. [Optional] Let us assume the machine being used is accessible over a TCP/IP network with the name machine_a.mycompany.com. On a second machine in that network, open an internet browser and visit the location http://machine_a.mycompany.com:8000/acl-doc. You should see the index page for the Allegro CL documentation. As you navigate this page by following links, you should be able to see from the address bar in your browser that the pages are being served using location addresses prefixed by http://machine_a.mycompany.com:8000/acl-doc/[...]. This indicates the browser is interacting with an HTTP server, that being our AllegroServe session.

Notes:

Step 1: See Quick Start 1 Notes for notes about (require :aserve) and (net.aserve:start ...) statements.
The :destination argument to net.aserve:publish-directory must be a string.
In a normal Allegro CL installation, the documentation directory is accessible using the logical pathname #p"sys:doc".
Step 3: If machine_a.mycompany.com is behind a firewall, you need to ensure that the second machine can access machine_a's port 8000. This may require a firewall adjustment.

Quick Start 3: Publish static Lisp-generated html pages

We demonstrate how to publish and generate an HTML expression from Lisp.

Steps:

  1. In Allegro CL, evaluate the following forms:
    > (require :aserve)
    > (net.aserve:start :port 8000)
    > (net.aserve:publish :path "/hello" :content-type "text/html" 
                          :function 'hello-function)
    > (defun hello-function (req ent) 
        (net.aserve:with-http-response (req ent)
          (net.aserve:with-http-body (req ent)
    	(net.html.generator:html
              (:html (:p "Hello WWW!"))))))
    
  2. Using an internet browser such as Firefox, Mozilla, or the Internet Explorer, visit the location http://localhost:8000/hello. You should see a page with the text "Hello WWW!".
  3. [Optional] Let us assume the machine being used is accessible over a TCP/IP network with the name machine_a.mycompany.com. On a second machine in that network, open an internet browser and visit the location http://machine_a.mycompany.com:8000/hello. You should see a page with the text "Hello WWW!".

Notes:

Step 1: See Quick Start 1 Notes for notes about (require :aserve) and (net.aserve:start ...) statements.
The (net.aserve:publish ...) expression tells AllegroServe that an HTTP request for the location /hello should invoke the function specified by the :function argument (in this case, hello-function).
The with-http-response and with-http-body forms typically occur in functions associated with AllegroServe publishing. See the AllegroServe documentation for their full descriptions. For our purposes, the interesting part of hello-function is the html generating expression which emits the simple text paragraph. Note that html tag names, such as p (paragraph), are used in the Lisp expression.
You do not need to learn a new language to emit html. The relationship between Lisp html expressions and HTML can be mostly described as follows:
HTML Lisp
<html-tag> ... </html-tag> (:html-tag ...)
<html-tag attribute=value> ... </html-tag> ((:html-tag :attribute "value") ... )
Step 3: If machine_a.mycompany.com is behind a firewall, you need to ensure that the second machine can access machine_a's port 8000. This may require a firewall adjustment.

Quick Start 4: Publish Lisp-generated pages with international characters.

We demonstrate how to publish Lisp-generated pages which include international characters.

Note that this example does not work in Lisp images which only support 8-bit characters (e.g., mlisp8 or alisp8).

Steps:

  1. In Allegro CL, evaluate the following forms:
    > (require :aserve)
    > (net.aserve:start :port 8000 :external-format (crlf-base-ef :utf-8))
    > (net.aserve:publish
        :path "/word/french"
        :content-type "text/html; charset=utf-8"
        :function 'french-word)
    > (defun french-word (req ent)
        (net.aserve:with-http-response (req ent)
          (net.aserve:with-http-body (req ent)
    	(net.html.generator:html
    	 (:html
    	  (:body
    	   (:princ-safe
    	    ;; french word for "castle"
    	    (coerce
    	     '(#\c #\h #\latin_small_letter_a_with_circumflex
    	       #\t #\e #\a #\u)
    	     'string))))))))
    [Optional]
    > (net.aserve:publish
        :path "/word/japanese"
        :content-type "text/html; charset=utf-8"
        :function 'japanese-word)
    [Optional]
    > (defun japanese-word (req ent)
        (net.aserve:with-http-response (req ent)
          (net.aserve:with-http-body (req ent)
    	(net.html.generator:html
    	 (:html
    	  (:body
    	   (:princ-safe
    	    ;; Japanese word for "thank you" (arigatou)
    	    (coerce
    	     '(#\hiragana_letter_a
    	       #\hiragana_letter_ri
    	       #\hiragana_letter_ga
    	       #\hiragana_letter_to
    	       #\hiragana_letter_u)
    	     'string))))))))
    
  2. Using an internet browser such as Firefox, Mozilla, or the Internet Explorer, visit the location http://localhost:8000/word/french. You should see a page with the text "château". Notice the third letter as being a small letter â with a circumflex.
  3. If you evaluated the expressions in the Steps above marked as [Optional], you can test them as follows: Using an internet browser such as Firefox, Mozilla, or the Internet Explorer, visit the location http://localhost:8000/word/japanese. You should see a page with a five-character Japanese word. If you see boxes instead of characters, then your browser may not have the proper Japanese or Asian language fonts installed.
  4. [Optional] Let us assume the machine being used is accessible over a TCP/IP network with the name machine_a.mycompany.com. On a second machine in that network, open an internet browser and visit the location http://machine_a.mycompany.com:8000/word/french, and, if you evaluated the expressions marked as [Optional], http://machine_a.mycompany.com:8000/word/japanese. You should see pages as described in the previous steps.

Notes:

Step 1: See Quick Start 1 Notes for notes about (require :aserve) and (net.aserve:start ...) statements. Note that in this example, we are calling net.aserve:start with the :external-format (crlf-base-ef :utf-8) argument. This is necessary to ensure that the proper encoding is used when sending international characters to the http clients (e.g., browsers). If you are running more than one tutorial example in a single Lisp session, you should evaluate this net.aserve:start form as shown above for this example.
See Quick Start 3 Notes for notes about (net.aserve:publish ...), with-http-response, with-http-body, and the html generator macro. The :princ-safe form in this example demonstrates how to include Lisp return values in the html output.
Step 4: If machine_a.mycompany.com is behind a firewall, you need to ensure that the second machine can access machine_a's port 8000. This may require a firewall adjustment.

Quick Start 5: Publish dynamic Lisp-generated HTML pages html

We demonstrate using a simple form to dynamically generate server requests, which the Lisp server uses to dynamically generate html responses.

Steps:

  1. In Allegro CL, evaluate the following forms:
    > (require :aserve)
    > (net.aserve:start :port 8000)
    > (net.aserve:publish
        :path "/times"
        :content-type "text/html"
        :function 'times-function)
    > (defun times-function (req ent)
        (net.aserve:with-http-response (req ent)
          (net.aserve:with-http-body (req ent)
    	(let ((nrows (net.aserve:request-query-value "nrows" req)))
    	  (if* nrows
    	     then (net.html.generator:html
    		   (:html
    		    (:body
    		     ((:table :border "1")
    		      (dotimes (i (read-from-string nrows))
    			(net.html.generator:html
    			 (:tr
    			  (:td (:princ i))
    			  (:td (:princ (* i i))))))))))
    	     else (net.html.generator:html
    		   (:html
    		    (:body
    		     "Enter table size: "
    		     ((:form :action "/times")
    		      ((:input :type "text" :name "nrows"))
    		      :br
    		      ((:input :type "submit")))))))))))
    
  2. Using an internet browser such as Firefox, Mozilla, or the Internet Explorer, visit the location http://localhost:8000/times. You should see a page with the text "Enter table size:" followed by a text input box followed by a Submit Query button. Enter a number, say, 6, into the text input box and press the Submit Query button. You should then see a page with 6-by-2 table with each row being an integer and its square.
  3. [Optional] Let us assume the machine being used is accessible over a TCP/IP network with the name machine_a.mycompany.com. On a second machine in that network, open an internet browser and visit the location http://machine_a.mycompany.com:8000/times. You should see pages as described in the previous step.

Notes:

Step 1: See Quick Start 1 Notes for notes about (require :aserve) and (net.aserve:start ...) statements.
See Quick Start 3 Notes for notes about (net.aserve:publish ...), with-http-response, with-http-body, and the html generator macro. The :princ form in this example demonstrates how to include Lisp return values in the html output. In an earlier example, we used :princ-safe. See the AllegroServe documentation for complete descriptions of these html generator directives. In this tutorial, :princ and :princ-safe are interchangeable.
The times-function demonstrates not only how different pages can be displayed from within a single publish function, but also how one can insert Lisp functions (in the squares table) within an html expression to control the html forms being emitted.
The if* conditional operator is an Allegro CL extension not included in the ANSI Common Lisp Specification.
Step 3: If machine_a.mycompany.com is behind a firewall, you need to ensure that the second machine can access machine_a's port 8000. This may require a firewall adjustment.

More information

More examples, including demonstrations of authentication, serving images, using cookies, timeouts, client to server file transfer, and other internationalization features can be found in the examples/aserve/examples.cl file included in the Allegro CL installation.

The AllegroServe documentation is available in doc/aserve/aserve.html. The HTML generator is described in doc/aserve/htmlgen.html.

Allegro Webactions is a framework on top of AllegroServe for developing entire web sites using the Model-View-Controller paradigm. Among other things, this paradigm separates web page design tasks from dynamic content programming tasks. It is described in doc/using-webactions.html and doc/webactions.html.

Other AllegroServe tutorials include GET requests tutorial, POST requests tutorial, Multipart requests tutorial, and Redirects tutorial.

Go to the tutorial main page.