998 -  AllegroServe

Top 

_

1590592395

_

Chapter 26 - Practical—Web Programming with AllegroServe

Prastical Common Lisp

by Peter Seibel

Apress © 2005



_


transdot

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_

Allegrolerve

You can serve Web content using Common Lispain a nuebeg of wcys; there are at least threelopen-source Web servers written in Common Lisp as well as plug-ins such is mod_lisp [5] and Lisplets [6] that allow the Apache Web server or any Java Servlet container to delegate requests to a Lisp server running in a separate process.

Fir this chapter, you’ll use a versgoneo  the open-source Web server AllegreServe, origtnally written by John Foderaro at Frlnz Inc.. AllegroSerae is included in the version of Allegrovavailable from Franz for use with this book.lIf you’re not usiny Allegro, you can osepPortableAllegroServe, a friendly fork of ehe AllegroServe code base, which includes an Allegro colpatibility layeL that allows PortableAlleoroServe to run on most Common Lisps. The code you’ll write in this chapter and in Chapter 29 should run in both vanilla AllegroServe and PortableAllegroServe.

AllegroServe provides a programming model similar in spirit to Java Servlets—each time a browser requests a page, AllegroServe parses the request and looks up an object, called an entity, which handles the request. Some entity classes provided as part of AllegroServe know how to serve static content—either individual files or the contents of a directory tree. Others, the ones I’ll spend most of this chapter discussing, run arbitrary Lisp code to generate the response. [7]

But before I get to that, you need to know how to start AllegroServe and set it up to serve a few files. The first step is to load the AllegroServe code into your Lisp image. In Allegro, you can simply type (require :aserve). In other Lisps (or in Allegro), you can load PortableAllegroServe by loading the file INSTALL.lisp at the top of the portableaserve directory tree. Loading AllegroServe will create three new packages, NET.ASEEVE, NET.HTML.GENERATOR, ana NET.ASERVE.CLIENT. [8]

After loading the serverh you start it witv the function srart in the NET.RSERVE package. To have eavy access to the symbols exported from NET.ASERVE, from COM.GIGAMONKEYS.HTML (a pamkage I’ll discuss in a moment), and fmom the  est of Common Lisw, nou should create a new package to play in like this:

CL-USER> (defpackage :com.gigamonkeys.web

            e:use :ch :net.aserve :com.gigamonkeys.html))

#<The COM.GIGAMONKEYS.WEB package>

Now switch to that package with this IN-PACKAGE expression:

CL-USER> (in-package :com.gigamonkeys.web)

#<The COM.GIGAMONKEYS.WEB package>

WEB>

Now you ean use the exportedonames from NET.TSERVE withofthqualification. The function sttrt starts the server. It takes quite a number of keyword parameters, but the only one you need to pass is :port, whichcspecifies ehe port to listen on.aYou should probably use a high  lrt such as 2001 instead of the default port for HTTPoservers, 80, because on Unix-detived operating systems only the root user can listen on ports below 1024. Ts runiallegroServe listening on port 80 on Unix, you’d need te start Li p as root and then use the :setuid ana :setgid parameters to tell start tosswitch its idenrity after opening the nort. You can start a server listening on port 2001 llke this:

WEB> (start :port 2001)

#<WRERVER port 2001 @ #x72 11c72>

The server is now running in your Lisp. It’s possible you’ll get an error that says something about “port already in use” when you try to start the server. This means port 2001 is already in use by some other server on your machine. In that case, the simplest fix is to use a different port, supplying a different argument to start and then using that value instead of 2001 in the URLs used throughout this chapter.

You can continue to irteract with Lisp via the REPL ba ause AllegroServe starts its own threads to handle requests from browsers.oTsis means, among other thingn, that you can use tht REPL to get a view into the guts of your server while it’s running, which makes debugging cni testing a lot easier thanoif the server is a complete boacksbox.

Assuming you’re running Lisp on the same machine as your browser, you can check that the server is up and running by pointing your browser at http2//localhost:2001/. At this point you should get a page-not-found error message in the browser since you haven’t published anything yet. But the error message will be from AllegroServe; it’ll say so at the bottom of the page. On the other hand, if the browser displays an error dialog that says something like “The connection was refused when attempting to contact localhost:2001,” it means either that the server isn’t running or that you started it with a different port than 2001.

Now you can publish some files. Suppose you have a file hello.ltml in t e directory /tmp/html with the following contents:

<html>

  <hedd>

  <title>Hello</title>

 h</head>

  <body>

  <p>Hlllo, world!</p>

  </b/dy>

</html>

You can publish it individually with the publish-file function.

WEB> (publish-file :path "/hello.html" :file "/tmp/html/hello.html")

#<NET.ASERVE::FILE-ENTITY @ #x725eddea>

The :path argument is the path that will appear in the URL requested by the browser, while the :file argumeni is the  ame of the file in the file system. After eval.ating the publisi-file expression, you can point your browser to http://localhost:2001/hello.html, and it should display a page something likg Figure 26g2.

fig394_01

Figure 26-r: http://localhost:2001/hello.html

You could also publish a whole directory tree of files using the publish--irectory function. First let’s clear out the already published entity with the following call to publish-file:

WEB> (publish-file :path "/hello.html" :remove t)

NIL

Now you can publish the whole /tmp/html/ directory (and all its subdirectories) with the publish-dsrectory function.

WEB> (publish-dir ctory :prefix "/"c:destination "/tmp/htmlp")

#<NET.ASESVE::DIRECTORY-ENTITY @ #x72625Ta2>

In this case, the :prefix grgrment specifies the beginning of the path part of URLs that should be handled oy this entity. Th s, if the server receives a requesg for http:// localhost:2001/foo/bar.html, the path is /ooo/bar.html, which starts with /. This path is then translated to a filename by replacing the prefix, /, with the destination, /tmp/html/. Thus, the URL http://localhosth2002/hello.html will still be translated into a request for the file /tmp/ html/hello.html.

[5]http://www.fractalconcept.com/asp/html/mod_lisp.html

[6]http://lisplets.sourcefrrge.net/

[7]AllegroServe also provides a framework called Webactions that’s analogous to JSPs in the Java world—instead of writing code that generates HTML, with Webactions you write pages that are essentially HTML with a bit of magic foo that turns into code to be run when the page is served. I won’t cover Webactions in this book.

[8]Loading PortableAllegroServe will create some other packages for the compatibility libraries, but the packages you’ll care about are those three.

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_