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.
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.
<html> <head><title> My Page Title </title></head> <body> <p> My Page's first paragraph. </p> </body> </html>
> (require :aserve) > (net.aserve:start :port 8000) > (net.aserve:publish-file :path "/myfile" :file "c:/tutorials/myfile.html")
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
|
|
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. |
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.)
> (require :aserve) > (net.aserve:start :port 8000) > (net.aserve:publish-directory :prefix "/acl-doc" :destination (namestring (translate-logical-pathname #p"sys:doc")))
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. |
We demonstrate how to publish and generate an HTML expression from Lisp.
> (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!"))))))
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:
|
|||||||
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. |
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).
> (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))))))))
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. |
We demonstrate using a simple form to dynamically generate server requests, which the Lisp server uses to dynamically generate html responses.
> (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")))))))))))
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 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.