pr 8028 and 8029

svn: r3347
This commit is contained in:
Jay McCarthy 2006-06-13 14:48:34 +00:00
parent 7015529bf5
commit fa67303a75
14 changed files with 328 additions and 275 deletions

View File

@ -0,0 +1,27 @@
(module bindings mzscheme
(require (lib "list.ss"))
(provide extract-binding/single
extract-bindings
exists-binding?)
; extract-binding/single : sym (listof (cons str str)) -> str
(define (extract-binding/single name bindings)
(define lst (extract-bindings name bindings))
(cond
[(empty? lst)
(error 'extract-binding/single "~e not found in ~e" name bindings)]
[(empty? (rest lst))
(first lst)]
[else
(error 'extract-binding/single "~e occurs multiple times in ~e" name bindings)]))
; extract-bindings : sym (listof (cons str str)) -> (listof str)
(define (extract-bindings name bindings)
(map cdr (filter (lambda (x) (equal? name (car x))) bindings)))
; exists-binding? : sym (listof (cons sym str)) -> bool
; for checkboxes
(define (exists-binding? name bindings)
(if (assq name bindings)
#t
#f)))

View File

@ -21,6 +21,17 @@
[load-configuration (path? . -> . unit/sig?)] [load-configuration (path? . -> . unit/sig?)]
[load-developer-configuration (path? . -> . unit/sig?)]) [load-developer-configuration (path? . -> . unit/sig?)])
(provide error-response
servlet-loading-responder
gen-servlet-not-found
gen-servlet-responder
gen-servlets-refreshed
gen-passwords-refreshed
gen-authentication-responder
gen-protocol-responder
gen-file-not-found-responder
gen-collect-garbage-responder)
(define default-configuration-table-path (define default-configuration-table-path
(build-path (collection-path "web-server") "configuration-table")) (build-path (collection-path "web-server") "configuration-table"))

View File

@ -1,27 +1,35 @@
(module dispatch-files mzscheme (module dispatch-files mzscheme
(require (lib "url.ss" "net") (require (lib "url.ss" "net")
(lib "xml.ss" "xml") (lib "xml.ss" "xml")
(lib "kw.ss")
(lib "list.ss")) (lib "list.ss"))
(require "dispatch.ss" (require "dispatch.ss"
"../configuration.ss"
"../util.ss" "../util.ss"
"../mime-types.ss" "../mime-types.ss"
"../response.ss") "../response.ss")
(provide interface-version (provide interface-version
gen-dispatcher) make)
(define interface-version 'v1) (define interface-version 'v1)
(define (gen-dispatcher htdocs-path mime-types-path indices file-not-found-responder) (define/kw (make #:key
(let ([get-mime-type (make-get-mime-type mime-types-path)]) [htdocs-path "htdocs"]
[mime-types-path "mime.types"]
[indices (list "index.html" "index.htm")]
[file-not-found-responder
(gen-file-not-found-responder "not-found.html")])
(define get-mime-type (make-get-mime-type mime-types-path))
(lambda (conn req) (lambda (conn req)
(let-values ([(uri method path) (decompose-request req)]) (define-values (uri method _path) (decompose-request req))
;; ************************************************************ ;; ************************************************************
;; ************************************************************ ;; ************************************************************
;; SERVING FILES ;; SERVING FILES
;; serve-file : connection symbol uri host -> void ;; serve-file : connection symbol uri host -> void
;; to find the file, including searching for implicit index files, and serve it out ;; to find the file, including searching for implicit index files, and serve it out
(let ([path (url-path->path htdocs-path (define path
(translate-escapes (url-path->string (url-path uri))))]) (url-path->path htdocs-path
(translate-escapes (url-path->string (url-path uri)))))
(cond (cond
[(file-exists? path) [(file-exists? path)
(output-file conn path method (get-mime-type path))] (output-file conn path method (get-mime-type path))]
@ -40,7 +48,7 @@
[else [else
(output-response/method conn (file-not-found-responder uri) method)]))] (output-response/method conn (file-not-found-responder uri) method)]))]
[else [else
(output-response/method conn (file-not-found-responder uri) method)])))))) (output-response/method conn (file-not-found-responder uri) method)])))
;; looks-like-directory : str -> bool ;; looks-like-directory : str -> bool
;; to determine if is url style path looks like it refers to a directory ;; to determine if is url style path looks like it refers to a directory

View File

@ -2,10 +2,10 @@
(require "dispatch.ss" (require "dispatch.ss"
"../servlet-helpers.ss") "../servlet-helpers.ss")
(provide interface-version (provide interface-version
gen-dispatcher) make)
(define interface-version 'v1) (define interface-version 'v1)
(define (gen-dispatcher lookup-dispatcher) (define (make lookup-dispatcher)
(lambda (conn req) (lambda (conn req)
(let* ([host (get-host (request-uri req) (request-headers/raw req))]) (let* ([host (get-host (request-uri req) (request-headers/raw req))])
((lookup-dispatcher host) conn req))))) ((lookup-dispatcher host) conn req)))))

View File

@ -1,15 +1,18 @@
(module dispatch-log mzscheme (module dispatch-log mzscheme
(require (lib "url.ss" "net") (require (lib "url.ss" "net")
(lib "date.ss") (lib "date.ss")
(lib "kw.ss")
(lib "async-channel.ss") (lib "async-channel.ss")
(lib "plt-match.ss")) (lib "plt-match.ss"))
(require "dispatch.ss" (require "dispatch.ss"
"../servlet-helpers.ss") "../servlet-helpers.ss")
(provide interface-version (provide interface-version
gen-dispatcher) make)
(define interface-version 'v1) (define interface-version 'v1)
(define (gen-dispatcher log-format log-path) (define/kw (make #:key
[log-format 'parenthesized-default]
[log-path #f])
(if log-path (if log-path
(case log-format (case log-format
[(parenthesized-default) [(parenthesized-default)
@ -34,8 +37,8 @@
; to produce a string that is displayed into the log file ; to produce a string that is displayed into the log file
; This is a kill-safe wait-less abstraction ; This is a kill-safe wait-less abstraction
(define (gen-log-message log-format log-path) (define (gen-log-message log-format log-path)
(let* ([log-ch (make-async-channel)] (define log-ch (make-async-channel))
[log-thread (define log-thread
(thread/suspend-to-kill (thread/suspend-to-kill
(lambda () (lambda ()
(let loop ([log-p #f]) (let loop ([log-p #f])
@ -57,8 +60,8 @@
(list 'from client-ip 'to host-ip 'for (url->string uri) 'at (list 'from client-ip 'to host-ip 'for (url->string uri) 'at
(date->string (seconds->date (current-seconds)) #t))) (date->string (seconds->date (current-seconds)) #t)))
log-p) log-p)
(loop log-p)]))))))))]) (loop log-p)])))))))))
(lambda args (lambda args
(thread-resume log-thread) (thread-resume log-thread (current-custodian))
(async-channel-put log-ch args) (async-channel-put log-ch args)
(void))))) (void))))

View File

@ -1,26 +1,31 @@
(module dispatch-passwords mzscheme (module dispatch-passwords mzscheme
(require (lib "kw.ss"))
(require "dispatch.ss" (require "dispatch.ss"
(all-except "../util.ss" translate-escapes) (all-except "../util.ss" translate-escapes)
"../configuration.ss"
"../servlet-helpers.ss" "../servlet-helpers.ss"
"../connection-manager.ss" "../connection-manager.ss"
"../response.ss") "../response.ss")
(provide interface-version (provide interface-version
gen-dispatcher) make)
(define interface-version 'v1) (define interface-version 'v1)
(define (gen-dispatcher password-file password-connection-timeout authentication-responder passwords-refresh-responder) (define/kw (make #:key
(let* ([password-cache (box #f)] [password-file "passwords"]
[reset-password-cache! [password-connection-timeout 300]
(lambda () [authentication-responder
(gen-authentication-responder "forbidden.html")]
[passwords-refresh-responder
(gen-passwords-refreshed "passwords-refresh.html")])
(define password-cache (box #f))
(define (reset-password-cache!)
; more here - a malformed password file will kill the connection ; more here - a malformed password file will kill the connection
(set-box! password-cache (read-passwords password-file)))] (set-box! password-cache (read-passwords password-file)))
[read-password-cache (define (read-password-cache)
(lambda () (unbox password-cache))
(unbox password-cache))])
(reset-password-cache!) (reset-password-cache!)
(lambda (conn req) (lambda (conn req)
(let-values ([(uri method path) (decompose-request req)]) (define-values (uri method path) (decompose-request req))
(cond (cond
[(access-denied? method path (request-headers/raw req) (read-password-cache)) [(access-denied? method path (request-headers/raw req) (read-password-cache))
=> (lambda (realm) => (lambda (realm)
@ -36,7 +41,7 @@
(passwords-refresh-responder) (passwords-refresh-responder)
method)] method)]
[else [else
(next-dispatcher)]))))) (next-dispatcher)])))
;; **************************************** ;; ****************************************
;; **************************************** ;; ****************************************
@ -49,10 +54,10 @@
;; denied?: str sym str -> (or/c str #f) ;; denied?: str sym str -> (or/c str #f)
;; the return string is the prompt for authentication ;; the return string is the prompt for authentication
(define (access-denied? method uri-str headers denied?) (define (access-denied? method uri-str headers denied?)
(let ([user-pass (extract-user-pass headers)]) (define user-pass (extract-user-pass headers))
(if user-pass (if user-pass
(denied? uri-str (lowercase-symbol! (car user-pass)) (cdr user-pass)) (denied? uri-str (lowercase-symbol! (car user-pass)) (cdr user-pass))
(denied? uri-str fake-user "")))) (denied? uri-str fake-user "")))
(define-struct (exn:password-file exn) ()) (define-struct (exn:password-file exn) ())

View File

@ -3,10 +3,10 @@
"../util.ss" "../util.ss"
"../response.ss") "../response.ss")
(provide interface-version (provide interface-version
gen-dispatcher) make)
(define interface-version 'v1) (define interface-version 'v1)
(define ((gen-dispatcher the-path procedure) conn req) (define ((make the-path procedure) conn req)
(let-values ([(uri method path) (decompose-request req)]) (let-values ([(uri method path) (decompose-request req)])
(if (string=? the-path path) (if (string=? the-path path)
(output-response/method (output-response/method

View File

@ -2,10 +2,10 @@
(require (lib "list.ss")) (require (lib "list.ss"))
(require "dispatch.ss") (require "dispatch.ss")
(provide interface-version (provide interface-version
gen-dispatcher) make)
(define interface-version 'v1) (define interface-version 'v1)
(define ((gen-dispatcher . dispatchers) conn req) (define ((make . dispatchers) conn req)
(let loop ([dispatchers dispatchers]) (let loop ([dispatchers dispatchers])
(let ([c (first dispatchers)]) (let ([c (first dispatchers)])
(with-handlers ([exn:dispatcher? (with-handlers ([exn:dispatcher?

View File

@ -1,5 +1,6 @@
(module dispatch-servlets mzscheme (module dispatch-servlets mzscheme
(require (lib "url.ss" "net") (require (lib "url.ss" "net")
(lib "kw.ss")
(lib "plt-match.ss") (lib "plt-match.ss")
(lib "unitsig.ss")) (lib "unitsig.ss"))
(require "dispatch.ss" (require "dispatch.ss"
@ -8,6 +9,7 @@
"../response.ss" "../response.ss"
"../servlet.ss" "../servlet.ss"
"../sig.ss" "../sig.ss"
"../configuration.ss"
(all-except "../util.ss" translate-escapes) (all-except "../util.ss" translate-escapes)
"../managers/manager.ss" "../managers/manager.ss"
"../managers/timeouts.ss" "../managers/timeouts.ss"
@ -15,14 +17,22 @@
"../private/servlet.ss" "../private/servlet.ss"
"../private/cache-table.ss") "../private/cache-table.ss")
(provide interface-version (provide interface-version
gen-dispatcher) make)
(define interface-version 'v1) (define interface-version 'v1)
(define (gen-dispatcher config:instances config:scripts config:make-servlet-namespace (define/kw (make config:instances config:scripts config:make-servlet-namespace
servlet-root #:key
responders-servlets-refreshed responders-servlet-loading responders-servlet [servlet-root "servlets"]
responders-file-not-found [responders-servlets-refreshed
timeouts-servlet-connection timeouts-default-servlet) (gen-servlets-refreshed "servlet-refresh.html")]
[responders-servlet-loading
servlet-loading-responder]
[responders-servlet
(gen-servlet-responder "servlet-error.html")]
[responders-file-not-found
(gen-file-not-found-responder "not-found.html")]
[timeouts-servlet-connection (* 60 60 24)]
[timeouts-default-servlet 30])
;; ************************************************************ ;; ************************************************************
;; ************************************************************ ;; ************************************************************
;; SERVING SERVLETS ;; SERVING SERVLETS

View File

@ -1,17 +1,23 @@
(module parse-table mzscheme (module parse-table mzscheme
(require (lib "match.ss") (require (lib "list.ss"))
"configuration-table-structs.ss") (require "configuration-table-structs.ss"
"bindings.ss")
(provide parse-configuration-table) (provide parse-configuration-table)
(define (get-binding key bindings default)
(first (get-binding* key bindings (list default))))
(define (get-binding* key bindings default)
(with-handlers ([exn? (lambda _ default)])
(extract-binding/single key bindings)))
; parse-configuration-table : tst -> configuration-table ; parse-configuration-table : tst -> configuration-table
(define parse-configuration-table (define (parse-configuration-table t)
(match-lambda (define port (get-binding 'port t 80))
[`((port ,port) (define max-waiting (get-binding 'max-waiting t 40))
(max-waiting ,max-waiting) (define initial-connection-timeout (get-binding 'initial-connection-timeout t 30))
(initial-connection-timeout ,initial-connection-timeout) (define default-host-table (get-binding* 'default-host-table t `()))
(default-host-table (define virtual-host-table (get-binding* 'virtual-host-table t `()))
,default-host-table)
(virtual-host-table . ,virtual-host-table))
(if (and (nat? port) (nat? max-waiting) (number? initial-connection-timeout) (if (and (nat? port) (nat? max-waiting) (number? initial-connection-timeout)
; more here - list? isn't really picky enough ; more here - list? isn't really picky enough
(list? virtual-host-table)) (list? virtual-host-table))
@ -24,37 +30,35 @@
(error 'parse-configuration-table "invalid virtual-host entry ~s" h))) (error 'parse-configuration-table "invalid virtual-host entry ~s" h)))
virtual-host-table)) virtual-host-table))
(error 'parse-configuration-table "invalid configuration values ~s" (error 'parse-configuration-table "invalid configuration values ~s"
(list port max-waiting initial-connection-timeout default-host-table virtual-host-table)))] (list port max-waiting initial-connection-timeout default-host-table virtual-host-table))))
[x (error 'parse-configuration-table "malformed configuration ~s" x)]))
; parse-host : tst -> host-table ; parse-host : tst -> host-table
(define parse-host (define (parse-host t)
(match-lambda (define host-table (get-binding* 'host-table t `()))
[`(host-table (define default-indices (get-binding* 'default-indices host-table `("index.html" "index.htm")))
(default-indices . ,default-indices) (define log-format (get-binding 'log-format host-table 'parenthesized-default))
(log-format ,log-format) (define messages (get-binding* 'messages host-table `()))
(messages (define servlet-message (get-binding 'servlet-message messages "servlet-error.html"))
(servlet-message ,servlet-message) (define authentication-message (get-binding 'authentication-message messages "forbidden.html"))
(authentication-message ,authentication-message) (define servlets-refreshed (get-binding 'servlets-refreshed messages "servlet-refresh.html"))
(servlets-refreshed ,servlets-refreshed) (define passwords-refreshed (get-binding 'passwords-refreshed messages "passwords-refresh.html"))
(passwords-refreshed ,passwords-refreshed) (define file-not-found-message (get-binding 'file-not-found-message messages "not-found.html"))
(file-not-found-message ,file-not-found-message) (define protocol-message (get-binding 'protocol-message messages "protocol-error.html"))
(protocol-message ,protocol-message) (define collect-garbage (get-binding 'collect-garbage messages "collect-garbage.html"))
(collect-garbage ,collect-garbage)) (define timeouts (get-binding* 'timeouts host-table `()))
(timeouts (define default-servlet-timeout (get-binding 'default-servlet-timeout timeouts 30))
(default-servlet-timeout ,default-servlet-timeout) (define password-connection-timeout (get-binding 'password-connection-timeout timeouts 300))
(password-connection-timeout ,password-connection-timeout) (define servlet-connection-timeout (get-binding 'servlet-connection-timeout timeouts (* 60 60 24)))
(servlet-connection-timeout ,servlet-connection-timeout) (define file-per-byte-connection-timeout (get-binding 'file-per-byte-connection-timeout timeouts 1/20))
(file-per-byte-connection-timeout ,file-per-byte-connection-timeout) (define file-base-connection-timeout (get-binding 'file-base-connection-timeout timeouts 30))
(file-base-connection-timeout ,file-base-connection-timeout)) (define paths (get-binding* 'paths host-table `()))
(paths (define configuration-root (get-binding 'configuration-root paths "conf"))
(configuration-root ,configuration-root) (define host-root (get-binding 'host-root paths "default-web-root"))
(host-root ,host-root) (define log-file-path (get-binding 'log-file-path paths "log"))
(log-file-path ,log-file-path) (define file-root (get-binding 'file-root paths "htdocs"))
(file-root ,file-root) (define servlet-root (get-binding 'servlet-root paths "."))
(servlet-root ,servlet-root) (define mime-types (get-binding 'mime-types paths "mime.types"))
(mime-types ,mime-types) (define password-authentication (get-binding 'password-authentication paths "passwords"))
(password-authentication ,password-authentication)))
(make-host-table (make-host-table
default-indices log-format default-indices log-format
(make-messages servlet-message (make-messages servlet-message
@ -75,8 +79,7 @@
file-root file-root
servlet-root servlet-root
mime-types mime-types
password-authentication))] password-authentication)))
[x (error 'parse-host "malformed host ~s" x)]))
; nat? : tst -> bool ; nat? : tst -> bool
(define (nat? x) (define (nat? x)

View File

@ -7,11 +7,10 @@
(lib "url.ss" "net")) (lib "url.ss" "net"))
(require "util.ss" (require "util.ss"
"response.ss" "response.ss"
"request-structs.ss") "request-structs.ss"
"bindings.ss")
(provide get-host (provide get-host
extract-binding/single (all-from "bindings.ss")
extract-bindings
exists-binding?
extract-user-pass extract-user-pass
build-suspender build-suspender
make-html-response/incremental make-html-response/incremental
@ -53,26 +52,6 @@
(string->symbol (bytes->string/utf-8 v))])] (string->symbol (bytes->string/utf-8 v))])]
[else DEFAULT-HOST-NAME])) [else DEFAULT-HOST-NAME]))
; extract-binding/single : sym (listof (cons str str)) -> str
(define (extract-binding/single name bindings)
(let ([lst (extract-bindings name bindings)])
(cond
[(null? lst)
(error 'extract-binding/single "~e not found in ~e" name bindings)]
[(null? (cdr lst)) (car lst)]
[else (error 'extract-binding/single "~e occurs multiple times in ~e" name bindings)])))
; extract-bindings : sym (listof (cons str str)) -> (listof str)
(define (extract-bindings name bindings)
(map cdr (filter (lambda (x) (equal? name (car x))) bindings)))
; exists-binding? : sym (listof (cons sym str)) -> bool
; for checkboxes
(define (exists-binding? name bindings)
(if (assq name bindings)
#t
#f))
; build-suspender : (listof html) (listof html) [(listof (cons sym str))] [(listof (cons sym str))] -> str -> response ; build-suspender : (listof html) (listof html) [(listof (cons sym str))] [(listof (cons sym str))] -> str -> response
(define build-suspender (define build-suspender
(opt-lambda (title content [body-attributes '([bgcolor "white"])] [head-attributes null]) (opt-lambda (title content [body-attributes '([bgcolor "white"])] [head-attributes null])

View File

@ -41,30 +41,34 @@
;; the timer-manager thread ;; the timer-manager thread
;; add-timer : number (-> void) -> timer ;; add-timer : number (-> void) -> timer
(define (add-timer msecs thunk) (define (add-timer msecs thunk)
(let* ([now (current-inexact-milliseconds)] (define now (current-inexact-milliseconds))
[timer (define timer
(make-timer (alarm-evt (+ now msecs)) (make-timer (alarm-evt (+ now msecs))
(+ now msecs) (+ now msecs)
thunk)]) thunk))
(async-channel-put timer-ch (async-channel-put
timer-ch
(lambda (timers) (lambda (timers)
(cons timer timers))) (list* timer timers)))
timer)) timer)
; revise-timer! : timer msecs (-> void) -> timer ; revise-timer! : timer msecs (-> void) -> timer
; revise the timer to ring msecs from now ; revise the timer to ring msecs from now
(define (revise-timer! timer msecs thunk) (define (revise-timer! timer msecs thunk)
(let ([now (current-inexact-milliseconds)]) (define now (current-inexact-milliseconds))
(async-channel-put (async-channel-put
timer-ch timer-ch
(lambda (timers) (lambda (timers)
(set-timer-evt! timer (alarm-evt (+ now msecs))) (set-timer-evt! timer (alarm-evt (+ now msecs)))
(set-timer-expire-seconds! timer (+ now msecs)) (set-timer-expire-seconds! timer (+ now msecs))
(set-timer-action! timer thunk) (set-timer-action! timer thunk)
timers)))) timers)))
(define (cancel-timer! timer) (define (cancel-timer! timer)
(revise-timer! timer 0 void)) (async-channel-put
timer-ch
(lambda (timers)
(remq timer timers))))
; start-timer : num (-> void) -> timer ; start-timer : num (-> void) -> timer
; to make a timer that calls to-do after sec from make-timer's application ; to make a timer that calls to-do after sec from make-timer's application

View File

@ -17,7 +17,9 @@
(require (lib "tcp-sig.ss" "net") (require (lib "tcp-sig.ss" "net")
(lib "unitsig.ss") (lib "unitsig.ss")
(lib "string.ss") (lib "string.ss")
(lib "list.ss")
(lib "url.ss" "net")) (lib "url.ss" "net"))
(provide web-server@) (provide web-server@)
;; **************************************** ;; ****************************************
@ -123,41 +125,42 @@
(define initial-connection-timeout config:initial-connection-timeout) (define initial-connection-timeout config:initial-connection-timeout)
;; dispatch : connection request -> void ;; dispatch : connection request -> void
(define dispatch-cache (make-cache-table))
(define dispatch (define dispatch
(let ([cache (make-cache-table)]) (host:make
(host:gen-dispatcher
(lambda (host) (lambda (host)
(cache-table-lookup! (cache-table-lookup!
cache host dispatch-cache host
(lambda () (lambda ()
(parameterize ([current-custodian (current-server-custodian)])
(host-info->dispatcher (host-info->dispatcher
(config:virtual-hosts (symbol->string host))))))))) (config:virtual-hosts (symbol->string host)))))))))
;; host-info->dispatcher : host-info -> conn request -> void ;; host-info->dispatcher : host-info -> conn request -> void
(define (host-info->dispatcher host-info) (define (host-info->dispatcher host-info)
(sequencer:gen-dispatcher (sequencer:make
(log:gen-dispatcher (host-log-format host-info) (log:make #:log-format (host-log-format host-info)
(host-log-path host-info)) #:log-path (host-log-path host-info))
(passwords:gen-dispatcher (host-passwords host-info) (passwords:make #:password-file (host-passwords host-info)
(timeouts-password (host-timeouts host-info)) #:password-connection-timeout (timeouts-password (host-timeouts host-info))
(responders-authentication (host-responders host-info)) #:authentication-responder (responders-authentication (host-responders host-info))
(responders-passwords-refreshed (host-responders host-info))) #:passwords-refresh-responder (responders-passwords-refreshed (host-responders host-info)))
(path-procedure:gen-dispatcher "/conf/collect-garbage" (path-procedure:make "/conf/collect-garbage"
(lambda () (lambda ()
(collect-garbage) (collect-garbage)
((responders-collect-garbage (host-responders host-info))))) ((responders-collect-garbage (host-responders host-info)))))
(servlets:gen-dispatcher config:instances config:scripts config:make-servlet-namespace (servlets:make config:instances config:scripts config:make-servlet-namespace
(paths-servlet (host-paths host-info)) #:servlet-root (paths-servlet (host-paths host-info))
(responders-servlets-refreshed (host-responders host-info)) #:responders-servlets-refreshed (responders-servlets-refreshed (host-responders host-info))
(responders-servlet-loading (host-responders host-info)) #:responders-servlet-loading (responders-servlet-loading (host-responders host-info))
(responders-servlet (host-responders host-info)) #:responders-servlet (responders-servlet (host-responders host-info))
(responders-file-not-found (host-responders host-info)) #:responders-file-not-found (responders-file-not-found (host-responders host-info))
(timeouts-servlet-connection (host-timeouts host-info)) #:timeouts-servlet-connection (timeouts-servlet-connection (host-timeouts host-info))
(timeouts-default-servlet (host-timeouts host-info))) #:timeouts-default-servlet (timeouts-default-servlet (host-timeouts host-info)))
(files:gen-dispatcher (paths-htdocs (host-paths host-info)) (files:make #:htdocs-path (paths-htdocs (host-paths host-info))
(paths-mime-types (host-paths host-info)) #:mime-types-path (paths-mime-types (host-paths host-info))
(host-indices host-info) #:indices (host-indices host-info)
(responders-file-not-found (host-responders host-info))))))) #:file-not-found-responder (responders-file-not-found (host-responders host-info)))))))
(define web-server@ (define web-server@
(compound-unit/sig (compound-unit/sig