[What do you want? dan**20000103183726 What do you want? Information ... ] { addfile ./doc/faq.html hunk ./doc/faq.html 1 +
Because it seemed like fun. Because CL-HTTP is not free. Because +the startup time of the average Lisp envronment is longer than +is probably acceptable for writing CGI in the language (and CGI is +awful anyway, let's face it). + +
Mostly because it seemed like fun. + +
A dictionary. + +
Other answers will be forthcoming if anybody asks the questions addfile ./doc/handlers.html hunk ./doc/handlers.html 1 +
Syntax: + +
export-handler url handler &key (match :prefix) (method +t) (stage :RESPONSE) + +
export-handler-list url handlers &key (match :prefix) (method +t) (stage :RESPONSE) + +
Arguments and Values: + +
url - a URL object. See url-class.lisp + +
handler - a function of two arguments, returning T (handled) or NIL + (try something else) + +
handlers - a list of handler functions, called in sequence until one + of them returns T + +
match - One of :exact - try this handler when url + exactly matches that requested, or :prefix - try when + url is a prefix of that requested + +
method - A list of keywords corresponding to HTTP/1.0 methods + (:get :post :put :delete etc), or T meaning match all methods + +
stage - response stage to call this at - see below + +
Description: + +handler may be a function designator or a list whose first +element is a symbol naming a function. The function is called with +arguments (request rest-of-url-string) - the request that +caused it to be invoked, and the portion of the request string left +over after matching against the exported url. In the case that +handler is a list, the elements of its cdr are also passed +(unevaluated) to the function. + +
Example: + +
+(export-handler (parse-urlstring "http://my.server.com/pages/" + `(file-request-handler "/var/www/htdocs/") + :method t) ++ +
+Those response stages in full: + +
+1) :authentication - who does the user say he is? Is he correct? +
+2) :authorization - is the user allowed to see this resource? +
+3) :response - send the resource back or do whever else is appropriate + at this stage for the request method +
+4) :log - do anything else that can be done after the stream to the + browser window is closed + +
+n) :error - if a Lisp ERROR is thrown during any of the preceding, run + this. Don't otherwise + +
+Producing output: + +
+Usually the :response stage is the one that gets to send back a +response. However, any earlier stage can send one if it wants +(usually in an atypical situation) and close the stream. If the +stream is closed, we skip directly to the :log stage when the current +stage is done. + +
+Authentication and authorization: + +
+Identities (usernames, basically) are unique per realm + +
+:authentication handler is responsible for checking that the supplied +credentials are correct for the given identity in the given URL space. +It will only produce a page if the credentials were not supplied or +don't match the claimed identity (and might not necessarily even then) + +
+:authorization handler has to check if the requested action is allowed +to the given identity when connecting from the given host name (though +note that IP-based authorization is not implemented currently - no +point as the proxy loses all the relevant information for us) + +
+For example + +
+0) To use the HTTP authentication methods, make sure that your URL +space corresponds to an HTTP realm. You need an :authentication +handler that digs for the request header's Authorization: line and +shoves a suitable user identifier into (request-user ) or hands out +the appopriate 40x error. A null :authorization handler will produce +a behaviour like the apache "require valid-user" directive, or you +could actually write a handler that checked this to confine it +further. + +
+How your application reports "incorrect password" (not authenticated) +as distinct from "we believe it's you, but you can't do that" (not +authorized) is up to you. Most browsers' user interface to this stuff +makes it hard to distinguish the two cases anyway; you might find it's +simplest just to put everything in the :authentication handler if the +users aren't going to notice the difference. + +
The make-basic-authentication-handler function exists to +make basic authentication more basic. It takes two arguments for +realm and password-checking function; the latter should take two +arguments username and password and return - on success +- a `user' which make-basic-authentication-handler will stick +in the request-user slot, or on failure NIL. +make-basic-authentication-handler returns a handler suitable +for exporting. + +
+1) cookie-based authentication, where the user's browser supplies a +cookie that we previously sent him. Our :authentication handler +checks the supplied cookie against our internal records, filling in +the (request-user ) slot if it matches. Our :authorization handler +checks if (request-user ) is one of the users allowed here, and +prints a helpful error page if not. + +
+2) ident-based authentication - you don't want to use this for +anything serious but in a secure intranet environment it might be +appropriate. Suggested implementation route would involve getting +apache to do the actual lookup as (a) it won't block, and (b) you'll +only end up identing the apache daemon if you do it yourself anyway. + +
+Note + +
+1) that we don't care what you put in the request-user slot provided +that your :authentication and :authorization handlers both agree on +it. It could be a username, user id, CLOS object defining a user, or +whatever. + +
+2) When IP-based access control becomes possible, it could conceivably +be used at authentication _or_ authorization stage. We might decide +for example that all requests from pc10.foo.com are from John Smith +(authenticate the request as from "John Smith") or we might decide that +all administrator requests must come from localhost - authentication +is identifying the remote user whereas authorization is checking that +he's "administrator" and connected from localhost. Clear? + + addfile ./doc/installation.html hunk ./doc/installation.html 1 +
+ +Nobody has really got nice clean installation sorted out for CL +programs, AFAICS. I tend to take the view that exposing people to the +gritty Lisp details is probably more constructive than wrapping it all +up in shell scripts that don't work on anyone else's system. So, +installation takes a bit of fiddling and it helps to have used +mk-defsystem before. + +
+* (ext:host-entry-name (ext:lookup-host-entry (unix:unix-gethostname))) ++ +It will probably help if this is correct, for at least some value of +``correct''. + +
Configuring Apache is Outside The Scope of these instructions, but +as a start, here are the relevant lines from my Debian laptop: +
+LoadModule proxy_module /usr/lib/apache/1.3/libproxy.so +NameVirtualHost localhost +Include /tmp/apache.cf.inc ++(localhost should usually be the machine's actual hostname, +but this thing has to run both standalone and on two different +networks, and it's too much of a headache to make it behave entirely +reasonably) + +
Araneida understands the HTTP/1.1 Host header, to support multiple +`virtual servers' in the same instance. Before you can export any +handlers, you need to decide the hostnames that you plan to serve +content from, and register them with Araneida + +
+# Note: You cannot just invent host names and hope they work. The name you +# define here must be a valid DNS name for your host. If you don't understand +# this, ask your network administrator. + -- Rob McCool, Apache httpd.conf ++ +
Syntax: + +
export-server server + +
Arguments and Values: + +
server - a SERVER object. See server-class.lisp for details + +
Description: + +
Registers server with Araneida, so that we know how to +answer requests for it. The same registration list is also used for +output-apache-conf + +
Note that the name and port in the server's BASE-URL slot don't +have to be (and in fact, usually aren't) the same as in PORT and NAME. +BASE-URL is the server's published address - in a normal +configuration, Apache will be listening to these and will forward +requests onto Araneida on HOST:PORT. You can see this in ../examples/main.lisp which works +with Apache on port 80 and Araneida on port 8000 + + + addfile ./doc/troubleshooting.html hunk ./doc/troubleshooting.html 1 +
+ +Well, actually, so far there has been no trouble. I'll write this +section when there is some. addfile ./doc/urls.html hunk ./doc/urls.html 1 +
+ ++(make-instance 'http-url :host "foo.com" :port "8000" :scheme "HTTP" + :path "/bar") +=> url + +(parse-urlstring "http://foo.com:8000/") +=> url + +(merge-urls an-exsting-url "/relative?url") +=> url ++ +
url-scheme url-endpoint url-path url-query url-fragment + +
also url-host url-port ( url-endpoint = url-host ":" url-port ) + +
These also have SETF methods. The behaviour of (setf url-scheme) +is undefined, however, and it will probably go away unless somebody +suggests a sensible one. + + + +
+(merge-url url string) ++ +will create and return a new URL from STRING according to the rules +for creating relative URLs. Note that this is a complex operation +which takes a whole RFC to describe, and it's unlikey that we do it +correctly in weird cases. + + + + + }