added handler combinators and adapted current basic handlers
This commit is contained in:
parent
f4bacf411a
commit
2c9b931100
|
@ -1,47 +1,42 @@
|
||||||
;;; http server in the Scheme Shell -*- Scheme -*-
|
;; Request-handlers for scheme web server
|
||||||
;;; Copyright (c) 1995 by Olin Shivers. <shivers@lcs.mit.edu>
|
|
||||||
|
|
||||||
;;; Imports and non-R4RS'isms
|
;; general request-handler-combinator:
|
||||||
;;; scsh syscalls
|
;; predicate: path x request --> boolean
|
||||||
;;; format Formatted output
|
;; if #t, handler is called
|
||||||
;;; ?, UNLESS, SWITCH Conditionals
|
;; if #f, default-handler is called
|
||||||
;;; httpd-core stuff
|
(define (make-request-handler predicate handler default-handler)
|
||||||
;;; httpd error stuff
|
(lambda (path req)
|
||||||
;;; CONDITION-STUFF Scheme 48 error conditions
|
(if (predicate path req)
|
||||||
;;; url stuff
|
(handler path req)
|
||||||
|
(default-handler path req))))
|
||||||
|
|
||||||
;;; Path handlers
|
;; same as make-request-handler except that the predicate is only
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;; called with the path:
|
||||||
;;; Path handlers are the guys that actually perform the requested operation
|
;; predicate: path --> boolean
|
||||||
;;; on the URL. The handler interface is
|
(define (make-path-handler predicate handler default-handler)
|
||||||
;;; (handler path-list request)
|
(make-request-handler
|
||||||
;;; The path-list is a URL path list that is a suffix of REQUEST's url's
|
(lambda (path req) (predicate path)) handler default-handler))
|
||||||
;;; path-list. Path handlers can decide how to handle an operation by
|
|
||||||
;;; recursively keying off of the elements in path-list.
|
|
||||||
;;;
|
|
||||||
;;; The object-oriented view:
|
|
||||||
;;; One way to look at this is to think of the request's METHOD as a
|
|
||||||
;;; generic operation on the URL. Recursive path handlers do method
|
|
||||||
;;; lookup to determine how to implement a given operation on a particular
|
|
||||||
;;; path.
|
|
||||||
;;;
|
|
||||||
;;; The REQUEST is a request record, as defined in httpd-core.scm, containing
|
|
||||||
;;; the details of the client request. However, path handlers should *not*
|
|
||||||
;;; read the request entity from, or write the reply to the request's socket.
|
|
||||||
;;; Path-handler I/O should be done on the current i/o ports: if the handler
|
|
||||||
;;; needs to read an entity, it should read it from (CURRENT-INPUT-PORT); when
|
|
||||||
;;; the handler wishes to write a reply, it should write it to
|
|
||||||
;;; (CURRENT-OUTPUT-PORT). This makes it easy for the procedure that called
|
|
||||||
;;; the handler to establish I/O indirections or filters if it so desires.
|
|
||||||
;;;
|
|
||||||
;;; This file implements a basic set of path handlers and some useful
|
|
||||||
;;; support procedures for them.
|
|
||||||
|
|
||||||
|
;; selects handler according to host-field of http-request
|
||||||
|
(define (make-hostname-handler hostname handler default-handler)
|
||||||
|
(make-request-handler
|
||||||
|
(lambda (path req)
|
||||||
|
;; we expect only one host-header-field
|
||||||
|
(string=? hostname (string-trim (get-header (request:headers req) 'host))))
|
||||||
|
handler default-handler))
|
||||||
|
|
||||||
|
;; selects handler according to path-prefix
|
||||||
|
;; if path-prefix matches, handler is called without the path-prefix
|
||||||
|
(define (make-path-prefix-handler path-prefix handler default-handler)
|
||||||
|
(lambda (path req)
|
||||||
|
(if (string=? path-prefix (car path))
|
||||||
|
(handler (cdr path) req)
|
||||||
|
(default-handler path req))))
|
||||||
|
|
||||||
(define server/buffer-size 8192) ; WTF
|
(define server/buffer-size 8192) ; WTF
|
||||||
|
|
||||||
|
|
||||||
;;; (alist-path-dispatcher hander-alist default-handler) -> handler
|
;;; (alist-path-dispatcher handler-alist default-handler) -> handler
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;; This function creates a table-driven path-handler that dispatches off
|
;;; This function creates a table-driven path-handler that dispatches off
|
||||||
;;; of the car of the request path. The handler uses the car to index into
|
;;; of the car of the request path. The handler uses the car to index into
|
||||||
|
@ -54,11 +49,14 @@
|
||||||
;;; path is 'foo', do X; if it's 'bar', do Y; otherwise, do Z."
|
;;; path is 'foo', do X; if it's 'bar', do Y; otherwise, do Z."
|
||||||
|
|
||||||
(define (alist-path-dispatcher handler-alist default-handler)
|
(define (alist-path-dispatcher handler-alist default-handler)
|
||||||
(lambda (path req)
|
(fold-right
|
||||||
(cond ((and (pair? path) (assoc (car path) handler-alist)) =>
|
(lambda (handler-pair default-handler)
|
||||||
(lambda (entry) ((cdr entry) (cdr path) req)))
|
(make-path-prefix-handler
|
||||||
(else (default-handler path req)))))
|
(car handler-pair)
|
||||||
|
(cdr handler-pair)
|
||||||
|
default-handler))
|
||||||
|
default-handler
|
||||||
|
handler-alist))
|
||||||
|
|
||||||
;;; (home-dir-handler user-public-dir) -> handler
|
;;; (home-dir-handler user-public-dir) -> handler
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -85,28 +83,29 @@
|
||||||
(http-error http-reply/bad-request req
|
(http-error http-reply/bad-request req
|
||||||
"Path contains no home directory."))))
|
"Path contains no home directory."))))
|
||||||
|
|
||||||
;;; (tilde-home-dir-handler user-public-dir default)
|
;;; (tilde-home-dir-handler-predicate path)
|
||||||
|
;;; (tilde-home-dir-handler user-public-dir)
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;; If the car of the path is a tilde-marked home directory (e.g., "~kgk"),
|
;;; If the car of the path is a tilde-marked home directory (e.g., "~kgk"),
|
||||||
;;; do home-directory service as in HOME-DIR-HANDLER, otherwise punt to the
|
;;; do home-directory service as in HOME-DIR-HANDLER, otherwise punt to the
|
||||||
;;; default handler.
|
;;; default handler.
|
||||||
|
|
||||||
(define (tilde-home-dir-handler user-public-dir default-ph)
|
(define (tilde-home-dir-handler-predicate path)
|
||||||
|
(lambda (path)
|
||||||
|
(and (pair? path) ; Is it a ~foo/...
|
||||||
|
(let ((head (car path))) ; home-directory path?
|
||||||
|
(and (> (string-length head) 0)
|
||||||
|
(char=? (string-ref head 0) #\~))))))
|
||||||
|
|
||||||
|
(define (tilde-home-dir-handler user-public-dir)
|
||||||
(lambda (path req)
|
(lambda (path req)
|
||||||
(if (and (pair? path) ; Is it a ~foo/...
|
(let* ((tilde-home (car path)) ; Yes.
|
||||||
(let ((head (car path))) ; home-directory path?
|
(slen (string-length tilde-home))
|
||||||
(and (> (string-length head) 0)
|
(subdir (string-append
|
||||||
(char=? (string-ref head 0) #\~))))
|
(http-homedir (substring tilde-home 1 slen) req)
|
||||||
|
"/"
|
||||||
(let* ((tilde-home (car path)) ; Yes.
|
user-public-dir)))
|
||||||
(slen (string-length tilde-home))
|
(serve-rooted-file-path subdir (cdr path) file-serve req))))
|
||||||
(subdir (string-append
|
|
||||||
(http-homedir (substring tilde-home 1 slen) req)
|
|
||||||
"/"
|
|
||||||
user-public-dir)))
|
|
||||||
(serve-rooted-file-path subdir (cdr path) file-serve req))
|
|
||||||
|
|
||||||
(default-ph path req)))) ; No.
|
|
||||||
|
|
||||||
|
|
||||||
;;; Make a handler that serves files relative to a particular root
|
;;; Make a handler that serves files relative to a particular root
|
||||||
|
@ -120,7 +119,7 @@
|
||||||
;;; Dito, but also serve directory indices for directories without
|
;;; Dito, but also serve directory indices for directories without
|
||||||
;;; index.html. ICON-NAME specifies how to generate the links to
|
;;; index.html. ICON-NAME specifies how to generate the links to
|
||||||
;;; various decorative icons for the listings. It can either be a
|
;;; various decorative icons for the listings. It can either be a
|
||||||
;;; prcoedure which gets passed one of the icon tags in TAG->ICON and
|
;;; procedure which gets passed one of the icon tags in TAG->ICON and
|
||||||
;;; is expected to return a link pointing to the icon. If it is a
|
;;; is expected to return a link pointing to the icon. If it is a
|
||||||
;;; string, that is taken as prefix to which the names from TAG->ICON
|
;;; string, that is taken as prefix to which the names from TAG->ICON
|
||||||
;;; are appended.
|
;;; are appended.
|
||||||
|
|
|
@ -350,9 +350,14 @@
|
||||||
title-html))
|
title-html))
|
||||||
|
|
||||||
(define-interface httpd-basic-handlers-interface
|
(define-interface httpd-basic-handlers-interface
|
||||||
(export alist-path-dispatcher
|
(export make-request-handler
|
||||||
|
make-path-handler
|
||||||
|
make-hostname-handler
|
||||||
|
make-path-prefix-handler
|
||||||
|
alist-path-dispatcher
|
||||||
home-dir-handler
|
home-dir-handler
|
||||||
tilde-home-dir-handler
|
tilde-home-dir-handler
|
||||||
|
tilde-home-dir-handler-predicate
|
||||||
rooted-file-handler
|
rooted-file-handler
|
||||||
rooted-file-or-directory-handler
|
rooted-file-or-directory-handler
|
||||||
null-path-handler
|
null-path-handler
|
||||||
|
@ -712,17 +717,19 @@
|
||||||
(files (httpd text-generation)))
|
(files (httpd text-generation)))
|
||||||
|
|
||||||
(define-structure httpd-basic-handlers httpd-basic-handlers-interface
|
(define-structure httpd-basic-handlers httpd-basic-handlers-interface
|
||||||
(open scsh ; syscalls
|
(open scsh ; syscalls
|
||||||
formats ; FORMAT
|
formats ; FORMAT
|
||||||
httpd-request ; REQUEST record type, v0.9-request
|
httpd-request ; REQUEST record type, v0.9-request
|
||||||
httpd-reply-codes ; reply codes
|
httpd-reply-codes ; reply codes
|
||||||
httpd-text-generation ; begin-http-header
|
httpd-text-generation ; begin-http-header
|
||||||
httpd-error ; HTTP-ERROR
|
httpd-error ; HTTP-ERROR
|
||||||
htmlout
|
htmlout
|
||||||
conditions ; CONDITION-STUFF
|
conditions ; CONDITION-STUFF
|
||||||
url ; HTTP-URL record type
|
url ; HTTP-URL record type
|
||||||
handle-fatal-error ; WITH-FATAL-ERROR-HANDLER
|
handle-fatal-error ; WITH-FATAL-ERROR-HANDLER
|
||||||
string-lib ; STRING-JOIN
|
string-lib ; STRING-JOIN
|
||||||
|
list-lib ; FOLD-RIGHT
|
||||||
|
rfc822 ; GET-HEADER
|
||||||
scheme)
|
scheme)
|
||||||
(files (httpd handlers)))
|
(files (httpd handlers)))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue