contracts
svn: r3559
This commit is contained in:
parent
27270cad3f
commit
e123925d31
|
@ -1,8 +1,6 @@
|
|||
(module bindings mzscheme
|
||||
(require (lib "list.ss"))
|
||||
(provide extract-binding/single
|
||||
extract-bindings
|
||||
exists-binding?)
|
||||
(require (lib "list.ss")
|
||||
(lib "contract.ss"))
|
||||
|
||||
; extract-binding/single : sym (listof (cons str str)) -> str
|
||||
(define (extract-binding/single name bindings)
|
||||
|
@ -24,4 +22,9 @@
|
|||
(define (exists-binding? name bindings)
|
||||
(if (assq name bindings)
|
||||
#t
|
||||
#f)))
|
||||
#f))
|
||||
|
||||
(provide/contract
|
||||
[extract-binding/single (symbol? (listof (cons/c symbol? any/c)) . -> . any/c)]
|
||||
[extract-bindings (symbol? (listof (cons/c symbol? any/c)) . -> . (listof any/c))]
|
||||
[exists-binding? (symbol? (listof (cons/c symbol? any/c)) . -> . boolean?)]))
|
|
@ -1,15 +1,18 @@
|
|||
(module configuration-structures mzscheme
|
||||
(require "util.ss"
|
||||
(require (lib "unitsig.ss")
|
||||
(lib "contract.ss")
|
||||
(lib "url.ss" "net"))
|
||||
(require "response-structs.ss"
|
||||
"configuration-table-structs.ss")
|
||||
(provide (struct timeouts (default-servlet password servlet-connection file-per-byte file-base))
|
||||
(struct paths (host-base log htdocs mime-types servlet)))
|
||||
|
||||
; configuration is now a unit. See sig.ss
|
||||
; XXX contract
|
||||
(define configuration?
|
||||
unit/sig?)
|
||||
|
||||
; host = (make-host (listof str) sym string
|
||||
; passwords resopnders timeouts paths)
|
||||
(provide-define-struct
|
||||
host (indices log-format log-path passwords responders timeouts paths))
|
||||
; passwords responders timeouts paths)
|
||||
(define-struct host (indices log-format log-path passwords responders timeouts paths))
|
||||
|
||||
; passwords = (listof (list* relm:str protected-dir-regexp:str
|
||||
; (listof (list user:sym password:str))))
|
||||
|
@ -22,6 +25,31 @@
|
|||
; (url -> response)
|
||||
; response
|
||||
; response)
|
||||
(provide-define-struct
|
||||
responders
|
||||
(servlet servlet-loading authentication servlets-refreshed passwords-refreshed file-not-found protocol collect-garbage)))
|
||||
(define-struct responders
|
||||
(servlet servlet-loading authentication servlets-refreshed passwords-refreshed file-not-found protocol collect-garbage))
|
||||
|
||||
(provide ; all-from
|
||||
(struct timeouts (default-servlet password servlet-connection file-per-byte file-base))
|
||||
(struct paths (host-base log htdocs mime-types servlet)))
|
||||
(provide/contract
|
||||
[configuration? (any/c . -> . boolean?)]
|
||||
[struct host
|
||||
([indices (listof string?)]
|
||||
[log-format symbol?]
|
||||
[log-path (or/c false/c path? string?)]
|
||||
[passwords (or/c false/c path? string?)]
|
||||
#;[passwords (listof (cons/c string?
|
||||
(cons/c string?
|
||||
(listof (list/c symbol? string?)))))]
|
||||
[responders responders?]
|
||||
[timeouts timeouts?]
|
||||
[paths paths?])]
|
||||
[struct responders
|
||||
([servlet (url? any/c . -> . response?)]
|
||||
[servlet-loading (url? any/c . -> . response?)]
|
||||
[authentication (url? (cons/c symbol? string?) . -> . response?)]
|
||||
[servlets-refreshed (-> response?)]
|
||||
[passwords-refreshed (-> response?)]
|
||||
[file-not-found (url? . -> . response?)]
|
||||
[protocol (url? . -> . response?)]
|
||||
[collect-garbage (-> response?)])]))
|
||||
|
|
|
@ -1,24 +1,55 @@
|
|||
(module configuration-table-structs mzscheme
|
||||
(require "util.ss")
|
||||
(require (lib "contract.ss"))
|
||||
|
||||
; configuration-table = (make-configuration-table nat nat num host-table (listof (cons str host-table)))
|
||||
(provide-define-struct
|
||||
configuration-table
|
||||
(define-struct configuration-table
|
||||
(port max-waiting initial-connection-timeout default-host virtual-hosts))
|
||||
|
||||
; host-table = (make-host-table (listof str) sym messages timeouts paths)
|
||||
(provide-define-struct host-table (indices log-format messages timeouts paths))
|
||||
|
||||
; passwords = (listof (list* relm:str protected-dir-regexp:str (listof (list user:sym password:str))))
|
||||
; passwords moved back to a separate file
|
||||
(define-struct host-table (indices log-format messages timeouts paths))
|
||||
|
||||
; messages = (make-messages str^6)
|
||||
(provide-define-struct messages
|
||||
(servlet ;servlet-loading
|
||||
authentication servlets-refreshed passwords-refreshed file-not-found protocol collect-garbage))
|
||||
(define-struct messages
|
||||
(servlet authentication servlets-refreshed passwords-refreshed file-not-found protocol collect-garbage))
|
||||
|
||||
; timeouts = (make-timeouts nat^5)
|
||||
(provide-define-struct timeouts (default-servlet password servlet-connection file-per-byte file-base))
|
||||
(define-struct timeouts (default-servlet password servlet-connection file-per-byte file-base))
|
||||
|
||||
; paths = (make-paths str^6)
|
||||
(provide-define-struct paths (conf host-base log htdocs servlet mime-types passwords)))
|
||||
(define-struct paths (conf host-base log htdocs servlet mime-types passwords))
|
||||
|
||||
(provide/contract
|
||||
[struct configuration-table
|
||||
([port natural-number/c]
|
||||
[max-waiting natural-number/c]
|
||||
[initial-connection-timeout natural-number/c]
|
||||
[default-host host-table?]
|
||||
[virtual-hosts (listof (cons/c string? host-table?))])]
|
||||
[struct host-table
|
||||
([indices (listof string?)]
|
||||
[log-format symbol?]
|
||||
[messages messages?]
|
||||
[timeouts timeouts?]
|
||||
[paths paths?])]
|
||||
[struct messages
|
||||
([servlet string?]
|
||||
[authentication string?]
|
||||
[servlets-refreshed string?]
|
||||
[passwords-refreshed string?]
|
||||
[file-not-found string?]
|
||||
[protocol string?]
|
||||
[collect-garbage string?])]
|
||||
[struct timeouts
|
||||
([default-servlet number?]
|
||||
[password number?]
|
||||
[servlet-connection number?]
|
||||
[file-per-byte number?]
|
||||
[file-base number?])]
|
||||
[struct paths
|
||||
([conf (or/c false/c path? string?)]
|
||||
[host-base (or/c false/c path? string?)]
|
||||
[log (or/c false/c path? string?)]
|
||||
[htdocs (or/c false/c path? string?)]
|
||||
[servlet (or/c false/c path? string?)]
|
||||
[mime-types (or/c false/c path? string?)]
|
||||
[passwords (or/c false/c path? string?)])]))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
(module configuration-util mzscheme
|
||||
(require (lib "file.ss")
|
||||
(require (lib "contract.ss")
|
||||
(lib "file.ss")
|
||||
(lib "pretty.ss"))
|
||||
(require "configuration-table-structs.ss")
|
||||
(provide (all-defined))
|
||||
|
||||
; write-configuration-table : configuration-table path -> void
|
||||
; writes out the new configuration file
|
||||
|
@ -55,4 +55,9 @@
|
|||
(define (write-to-file file-name x)
|
||||
(call-with-output-file file-name
|
||||
(lambda (out) (pretty-print x out))
|
||||
'truncate)))
|
||||
'truncate))
|
||||
|
||||
(provide/contract
|
||||
[write-configuration-table (configuration-table? string? . -> . void)]
|
||||
[format-host (host-table? . -> . list?)]
|
||||
[write-to-file (string? list? . -> . void)]))
|
|
@ -1,5 +1,6 @@
|
|||
; configuration language example
|
||||
(module configuration mzscheme
|
||||
(require (lib "unitsig.ss")
|
||||
(lib "contract.ss"))
|
||||
(require "configuration-structures.ss"
|
||||
"configuration-table-structs.ss"
|
||||
"sig.ss"
|
||||
|
@ -7,30 +8,6 @@
|
|||
"parse-table.ss"
|
||||
"private/cache-table.ss"
|
||||
"response.ss")
|
||||
(require (lib "unitsig.ss")
|
||||
(lib "contract.ss"))
|
||||
|
||||
(provide complete-configuration
|
||||
get-configuration
|
||||
build-developer-configuration
|
||||
build-developer-configuration/vhosts ;; added 2/3/05 by Jacob
|
||||
default-configuration-table-path
|
||||
update-configuration)
|
||||
|
||||
(provide/contract
|
||||
[load-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
|
||||
(build-path (collection-path "web-server") "configuration-table"))
|
||||
|
@ -111,8 +88,6 @@
|
|||
|
||||
; begin stolen from commander.ss, which was stolen from private/drscheme/eval.ss
|
||||
; FIX - abstract this out to a namespace library somewhere (ask Robby and Matthew)
|
||||
|
||||
|
||||
(define to-be-copied-module-specs
|
||||
'(mzscheme
|
||||
;; allow people (SamTH) to use MrEd primitives from servlets.
|
||||
|
@ -122,7 +97,6 @@
|
|||
(lib "mred.ss" "mred")
|
||||
(lib "servlet.ss" "web-server")))
|
||||
|
||||
|
||||
; JBC : added error-handler hack; the right answer is only to transfer the 'mred'
|
||||
; module binding when asked to, e.g. by a field in the configuration file.
|
||||
; GregP: put this back in if Sam's code breaks
|
||||
|
@ -203,7 +177,7 @@
|
|||
; gen-servlet-responder : str -> url tst -> response
|
||||
(define (gen-servlet-responder servlet-error-file)
|
||||
(lambda (url exn)
|
||||
; more here - use separate log file
|
||||
; XXX use separate log file
|
||||
((error-display-handler)
|
||||
(format "Servlet exception:\n~a\n" (exn-message exn))
|
||||
exn)
|
||||
|
@ -296,4 +270,28 @@
|
|||
(and (regexp-match (car x) host-name-possibly-followed-by-a-collon-and-a-port-number)
|
||||
(cadr x)))
|
||||
expanded-virtual-host-table)
|
||||
default-host))))
|
||||
default-host)))
|
||||
|
||||
(provide/contract
|
||||
[complete-configuration (string? configuration-table? . -> . configuration?)]
|
||||
[get-configuration (string? . -> . configuration-table?)]
|
||||
; XXX contract
|
||||
[build-developer-configuration (list? . -> . configuration?)]
|
||||
; XXX contract
|
||||
[build-developer-configuration/vhosts (list? . -> . configuration?)]
|
||||
[default-configuration-table-path path?]
|
||||
[update-configuration (configuration? (listof (cons/c symbol? any/c)) . -> . configuration?)]
|
||||
[load-configuration (path? . -> . configuration?)]
|
||||
[load-developer-configuration (path? . -> . configuration?)])
|
||||
(provide/contract
|
||||
[error-response ((natural-number/c string? string?) (listof (cons/c symbol? string?)) . ->* . (response?))]
|
||||
; XXX contract
|
||||
[servlet-loading-responder (string? any/c . -> . response?)]
|
||||
[gen-servlet-not-found (string? . -> . (string? . -> . response?))]
|
||||
[gen-servlet-responder (string? . -> . (string? any/c . -> . response?))]
|
||||
[gen-servlets-refreshed (string? . -> . (-> response?))]
|
||||
[gen-passwords-refreshed (string? . -> . (-> response?))]
|
||||
[gen-authentication-responder (string? . -> . (string? (cons/c symbol? string?) . -> . response?))]
|
||||
[gen-protocol-responder (string? . -> . (string? . -> . response?))]
|
||||
[gen-file-not-found-responder (string? . -> . (string? . -> . response?))]
|
||||
[gen-collect-garbage-responder (string? . -> . (-> response?))]))
|
|
@ -1,5 +1,4 @@
|
|||
(module configure mzscheme
|
||||
(provide servlet servlet-maker)
|
||||
(require (lib "unitsig.ss")
|
||||
(lib "servlet-sig.ss" "web-server")
|
||||
(lib "url.ss" "net")
|
||||
|
@ -7,12 +6,17 @@
|
|||
(lib "list.ss")
|
||||
(lib "pretty.ss")
|
||||
(lib "file.ss")
|
||||
(lib "contract.ss")
|
||||
(only (lib "configuration.ss" "web-server")
|
||||
default-configuration-table-path)
|
||||
(lib "configuration-table-structs.ss" "web-server")
|
||||
(lib "parse-table.ss" "web-server")
|
||||
(lib "configuration-util.ss" "web-server")
|
||||
(all-except (lib "util.ss" "web-server") translate-escapes))
|
||||
(provide/contract
|
||||
[servlet unit/sig?]
|
||||
; XXX contract
|
||||
[servlet-maker (string? . -> . unit/sig?)])
|
||||
|
||||
;; FIX
|
||||
; - fuss with changing absolute paths into relative ones internally
|
||||
|
|
13
collects/web-server/dispatch-server-sig.ss
Normal file
13
collects/web-server/dispatch-server-sig.ss
Normal file
|
@ -0,0 +1,13 @@
|
|||
(module dispatch-server-sig mzscheme
|
||||
(require (lib "unitsig.ss"))
|
||||
|
||||
(define-signature dispatch-server^
|
||||
(serve
|
||||
serve-ports))
|
||||
|
||||
(define-signature dispatch-server-config^
|
||||
(port listen-ip max-waiting initial-connection-timeout
|
||||
read-request dispatch))
|
||||
|
||||
(provide ; XXX contract signature
|
||||
dispatch-server^ dispatch-server-config^))
|
81
collects/web-server/dispatch-server-unit.ss
Normal file
81
collects/web-server/dispatch-server-unit.ss
Normal file
|
@ -0,0 +1,81 @@
|
|||
(module dispatch-server-unit mzscheme
|
||||
(require (lib "tcp-sig.ss" "net")
|
||||
(lib "unitsig.ss")
|
||||
(lib "thread.ss")
|
||||
(lib "contract.ss")
|
||||
(lib "kw.ss"))
|
||||
(require "web-server-structs.ss"
|
||||
"connection-manager.ss"
|
||||
"dispatch-server-sig.ss")
|
||||
|
||||
(provide/contract
|
||||
; XXX contract
|
||||
[dispatch-server@ unit/sig?])
|
||||
|
||||
;; ****************************************
|
||||
(define dispatch-server@
|
||||
(unit/sig dispatch-server^
|
||||
(import net:tcp^ (config : dispatch-server-config^))
|
||||
|
||||
;; serve: -> -> void
|
||||
;; start the server and return a thunk to shut it down
|
||||
(define (serve)
|
||||
(define the-server-custodian (make-custodian))
|
||||
(start-connection-manager the-server-custodian)
|
||||
(parameterize ([current-custodian the-server-custodian]
|
||||
[current-server-custodian the-server-custodian]
|
||||
[current-thread-initial-stack-size 3])
|
||||
(thread
|
||||
(lambda ()
|
||||
(run-server config:port
|
||||
handle-connection
|
||||
#f
|
||||
(lambda (exn)
|
||||
#f)
|
||||
(lambda (p mw re)
|
||||
(tcp-listen p config:max-waiting #t config:listen-ip))
|
||||
tcp-close
|
||||
tcp-accept
|
||||
tcp-accept/enable-break))))
|
||||
(lambda ()
|
||||
(custodian-shutdown-all the-server-custodian)))
|
||||
|
||||
;; serve-ports : input-port output-port -> void
|
||||
;; returns immediately, spawning a thread to handle
|
||||
;; the connection
|
||||
;; NOTE: (GregP) should allow the user to pass in a connection-custodian
|
||||
(define (serve-ports ip op)
|
||||
(define server-cust (make-custodian))
|
||||
(start-connection-manager server-cust)
|
||||
(parameterize ([current-custodian server-cust]
|
||||
[current-server-custodian server-cust])
|
||||
(define connection-cust (make-custodian))
|
||||
(parameterize ([current-custodian connection-cust])
|
||||
(thread
|
||||
(lambda ()
|
||||
(handle-connection ip op
|
||||
(lambda (ip)
|
||||
(values "127.0.0.1"
|
||||
"127.0.0.1"))))))))
|
||||
|
||||
;; handle-connection : input-port output-port (input-port -> string string) -> void
|
||||
;; returns immediately, spawning a thread to handle
|
||||
(define/kw (handle-connection ip op
|
||||
#:optional
|
||||
[port-addresses tcp-addresses])
|
||||
(define conn
|
||||
(new-connection config:initial-connection-timeout
|
||||
ip op (current-custodian) #f))
|
||||
(with-handlers ([exn:fail:network?
|
||||
(lambda (e)
|
||||
(kill-connection! conn)
|
||||
(raise e))])
|
||||
(let connection-loop ()
|
||||
(define-values (req close?) (config:read-request conn config:port port-addresses))
|
||||
(adjust-connection-timeout! conn config:initial-connection-timeout)
|
||||
(config:dispatch conn req)
|
||||
(unless (connection-close? conn)
|
||||
(set-connection-close?! conn close?))
|
||||
(cond
|
||||
[(connection-close? conn) (kill-connection! conn)]
|
||||
[else (connection-loop)])))))))
|
|
@ -2,13 +2,16 @@
|
|||
(require (lib "url.ss" "net")
|
||||
(lib "xml.ss" "xml")
|
||||
(lib "kw.ss")
|
||||
(lib "list.ss"))
|
||||
(lib "list.ss")
|
||||
(lib "contract.ss"))
|
||||
(require "dispatch.ss"
|
||||
"../configuration.ss"
|
||||
"../util.ss"
|
||||
"../mime-types.ss"
|
||||
"../response.ss")
|
||||
(provide interface-version
|
||||
(provide/contract
|
||||
[interface-version dispatcher-interface-version?])
|
||||
(provide ; XXX contract kw
|
||||
make)
|
||||
|
||||
(define interface-version 'v1)
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
(module dispatch-host mzscheme
|
||||
(require (lib "contract.ss"))
|
||||
(require "dispatch.ss"
|
||||
"../servlet-helpers.ss")
|
||||
(provide interface-version
|
||||
make)
|
||||
(provide/contract
|
||||
[interface-version dispatcher-interface-version?]
|
||||
[make ((symbol? . -> . dispatcher?) . -> . dispatcher?)])
|
||||
|
||||
(define interface-version 'v1)
|
||||
(define (make lookup-dispatcher)
|
||||
(lambda (conn req)
|
||||
(let* ([host (get-host (request-uri req) (request-headers/raw req))])
|
||||
((lookup-dispatcher host) conn req)))))
|
||||
(define ((make lookup-dispatcher) conn req)
|
||||
(define host (get-host (request-uri req) (request-headers/raw req)))
|
||||
((lookup-dispatcher host) conn req)))
|
|
@ -3,10 +3,13 @@
|
|||
(lib "date.ss")
|
||||
(lib "kw.ss")
|
||||
(lib "async-channel.ss")
|
||||
(lib "plt-match.ss"))
|
||||
(lib "plt-match.ss")
|
||||
(lib "contract.ss"))
|
||||
(require "dispatch.ss"
|
||||
"../servlet-helpers.ss")
|
||||
(provide interface-version
|
||||
(provide/contract
|
||||
[interface-version dispatcher-interface-version?])
|
||||
(provide ; XXX contract kw
|
||||
make)
|
||||
|
||||
(define interface-version 'v1)
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
(module dispatch-passwords mzscheme
|
||||
(require (lib "kw.ss"))
|
||||
(require (lib "kw.ss")
|
||||
(lib "contract.ss"))
|
||||
(require "dispatch.ss"
|
||||
(all-except "../util.ss" translate-escapes)
|
||||
"../configuration.ss"
|
||||
"../servlet-helpers.ss"
|
||||
"../connection-manager.ss"
|
||||
"../response.ss")
|
||||
(provide interface-version
|
||||
(provide/contract
|
||||
[interface-version dispatcher-interface-version?])
|
||||
(provide ; XXX contract kw
|
||||
make)
|
||||
|
||||
(define interface-version 'v1)
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
(module dispatch-pathprocedure mzscheme
|
||||
(require (lib "contract.ss"))
|
||||
(require "dispatch.ss"
|
||||
"../util.ss"
|
||||
"../response.ss")
|
||||
(provide interface-version
|
||||
make)
|
||||
(provide/contract
|
||||
[interface-version dispatcher-interface-version?]
|
||||
[make (string? (-> response?) . -> . dispatcher?)])
|
||||
|
||||
(define interface-version 'v1)
|
||||
(define ((make the-path procedure) conn req)
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
(module dispatch-sequencer mzscheme
|
||||
(require (lib "list.ss"))
|
||||
(require (lib "list.ss")
|
||||
(lib "contract.ss"))
|
||||
(require "dispatch.ss")
|
||||
(provide interface-version
|
||||
(provide/contract
|
||||
[interface-version dispatcher-interface-version?])
|
||||
(provide ; XXX contract kw
|
||||
make)
|
||||
|
||||
(define interface-version 'v1)
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
(require (lib "url.ss" "net")
|
||||
(lib "kw.ss")
|
||||
(lib "plt-match.ss")
|
||||
(lib "unitsig.ss"))
|
||||
(lib "unitsig.ss")
|
||||
(lib "contract.ss"))
|
||||
(require "dispatch.ss"
|
||||
"../web-server-structs.ss"
|
||||
"../connection-manager.ss"
|
||||
|
@ -13,10 +14,14 @@
|
|||
(all-except "../util.ss" translate-escapes)
|
||||
"../managers/manager.ss"
|
||||
"../managers/timeouts.ss"
|
||||
"../managers/lru.ss"
|
||||
"../private/url.ss"
|
||||
"../private/servlet.ss"
|
||||
"../private/cache-table.ss")
|
||||
(provide interface-version
|
||||
(provide/contract
|
||||
[interface-version dispatcher-interface-version?])
|
||||
(provide ; XXX contract improve
|
||||
; XXX contract kw
|
||||
make)
|
||||
|
||||
(define interface-version 'v1)
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
(module dispatch mzscheme
|
||||
(require (lib "contract.ss"))
|
||||
(require "../connection-structs.ss"
|
||||
"../request-structs.ss"
|
||||
"../response-structs.ss")
|
||||
(require (lib "contract.ss")
|
||||
(lib "list.ss"))
|
||||
|
||||
(provide dispatcher?)
|
||||
(define dispatcher? (connection? request? . -> . response?))
|
||||
|
||||
(provide next-dispatcher
|
||||
[struct exn:dispatcher ()])
|
||||
(define dispatcher?
|
||||
(connection? request? . -> . void))
|
||||
(define dispatcher-interface-version?
|
||||
symbol?)
|
||||
(define-struct exn:dispatcher ())
|
||||
(define (next-dispatcher) (raise (make-exn:dispatcher))))
|
||||
(define (next-dispatcher) (raise (make-exn:dispatcher)))
|
||||
|
||||
(provide/contract
|
||||
[dispatcher? contract?]
|
||||
[dispatcher-interface-version? (any/c . -> . boolean?)]
|
||||
[next-dispatcher (-> void)]
|
||||
[struct exn:dispatcher ()]))
|
|
@ -2,12 +2,14 @@
|
|||
(module launch mzscheme
|
||||
(require (lib "cmdline.ss")
|
||||
(lib "pregexp.ss")
|
||||
"util.ss"
|
||||
(lib "contract.ss")
|
||||
(lib "unitsig.ss")
|
||||
(lib "tcp-sig.ss" "net"))
|
||||
(require "util.ss"
|
||||
"web-server-unit.ss"
|
||||
"sig.ss"
|
||||
"configuration.ss"
|
||||
(lib "unitsig.ss")
|
||||
(lib "tcp-sig.ss" "net"))
|
||||
"configuration-structures.ss")
|
||||
|
||||
(define configuration@
|
||||
(parse-command-line
|
||||
|
@ -58,4 +60,5 @@
|
|||
(export (open S)))
|
||||
#f net:tcp^)
|
||||
|
||||
(provide serve))
|
||||
(provide ; XXX contract
|
||||
serve))
|
|
@ -1,8 +1,12 @@
|
|||
(module lru mzscheme
|
||||
(require (lib "plt-match.ss")
|
||||
(lib "contract.ss")
|
||||
(lib "kw.ss"))
|
||||
(require "manager.ss")
|
||||
(provide create-LRU-manager)
|
||||
(require "manager.ss"
|
||||
"../servlet-structs.ss")
|
||||
(provide/contract
|
||||
; XXX contract kw
|
||||
[create-LRU-manager ((expiration-handler? number? number? (-> boolean?)) any/c . ->* . (manager?))])
|
||||
|
||||
;; Utility
|
||||
(define (make-counter)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(module manager mzscheme
|
||||
(provide (all-defined))
|
||||
(require (lib "contract.ss"))
|
||||
(require "../servlet-structs.ss")
|
||||
|
||||
(define-struct manager (create-instance
|
||||
adjust-timeout!
|
||||
|
@ -9,4 +10,20 @@
|
|||
continuation-lookup))
|
||||
|
||||
(define-struct (exn:fail:servlet-manager:no-instance exn:fail) (expiration-handler))
|
||||
(define-struct (exn:fail:servlet-manager:no-continuation exn:fail) (expiration-handler)))
|
||||
(define-struct (exn:fail:servlet-manager:no-continuation exn:fail) (expiration-handler))
|
||||
|
||||
(provide/contract
|
||||
[struct manager ([create-instance (any/c (-> void) . -> . number?)]
|
||||
[adjust-timeout! (number? number? . -> . void)]
|
||||
[instance-lookup-data (number? . -> . any/c)]
|
||||
[clear-continuations! (number? . -> . void)]
|
||||
[continuation-store! (number? procedure? expiration-handler? . -> . (list/c number? number?))]
|
||||
[continuation-lookup (number? number? number? . -> . procedure?)])]
|
||||
[struct (exn:fail:servlet-manager:no-instance exn:fail)
|
||||
([msg string?]
|
||||
[continuation-marks continuation-mark-set?]
|
||||
[expiration-handler expiration-handler?])]
|
||||
[struct (exn:fail:servlet-manager:no-continuation exn:fail)
|
||||
([msg string?]
|
||||
[continuation-marks continuation-mark-set?]
|
||||
[expiration-handler expiration-handler?])]))
|
|
@ -1,8 +1,11 @@
|
|||
(module timeouts mzscheme
|
||||
(require (lib "plt-match.ss"))
|
||||
(require (lib "plt-match.ss")
|
||||
(lib "contract.ss"))
|
||||
(require "manager.ss")
|
||||
(require "../timer.ss")
|
||||
(provide create-timeout-manager)
|
||||
(require "../timer.ss"
|
||||
"../servlet-structs.ss")
|
||||
(provide/contract
|
||||
[create-timeout-manager (expiration-handler? number? number? . -> . manager?)])
|
||||
|
||||
;; Utility
|
||||
(define (make-counter)
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
(module monitor-server mzscheme
|
||||
(require (lib "etc.ss")
|
||||
"monitor-poke-web-server.ss"
|
||||
"monitor-emailer.ss"
|
||||
(lib "contract.ss")
|
||||
(lib "match.ss"))
|
||||
|
||||
(provide monitor
|
||||
default-server-port
|
||||
default-poll-frequency-seconds
|
||||
default-server-response-timeout-seconds)
|
||||
(require "monitor-poke-web-server.ss"
|
||||
"monitor-emailer.ss")
|
||||
|
||||
(define default-server-port 80)
|
||||
(define default-poll-frequency-seconds 3600)
|
||||
|
@ -33,4 +29,10 @@
|
|||
[`(ok) (void)]
|
||||
[else (send-email (result->message result))])
|
||||
(sleep poll-frequency-seconds)
|
||||
(check-server))))))
|
||||
(check-server)))))
|
||||
|
||||
(provide/contract
|
||||
[monitor ((string? string?) (number? number? number?) . -> . void)]
|
||||
[default-server-port number?]
|
||||
[default-poll-frequency-seconds number?]
|
||||
[default-server-response-timeout-seconds number?]))
|
|
@ -1,8 +1,8 @@
|
|||
(module parse-table mzscheme
|
||||
(require (lib "list.ss"))
|
||||
(require (lib "list.ss")
|
||||
(lib "contract.ss"))
|
||||
(require "configuration-table-structs.ss"
|
||||
"bindings.ss")
|
||||
(provide parse-configuration-table)
|
||||
|
||||
(define (get-binding key bindings default)
|
||||
(first (get-binding* key bindings (list default))))
|
||||
|
@ -83,4 +83,8 @@
|
|||
|
||||
; nat? : tst -> bool
|
||||
(define (nat? x)
|
||||
(and (number? x) (exact? x) (integer? x) (<= 0 x))))
|
||||
(and (number? x) (exact? x) (integer? x) (<= 0 x)))
|
||||
|
||||
(provide/contract
|
||||
; XXX contract
|
||||
[parse-configuration-table (list? . -> . configuration-table?)]))
|
|
@ -36,5 +36,5 @@
|
|||
[rename new-cache-table make-cache-table
|
||||
(-> cache-table?)]
|
||||
[cache-table-lookup! (cache-table? symbol? (-> any/c) . -> . any/c)]
|
||||
[cache-table-clear! (cache-table? . -> . void?)])
|
||||
(provide cache-table?))
|
||||
[cache-table-clear! (cache-table? . -> . void?)]
|
||||
[cache-table? (any/c . -> . boolean?)]))
|
|
@ -1,10 +1,13 @@
|
|||
(module servlet mzscheme
|
||||
(require "../managers/manager.ss")
|
||||
(require (lib "contract.ss"))
|
||||
(require "../managers/manager.ss"
|
||||
"../servlet-structs.ss"
|
||||
"../connection-structs.ss"
|
||||
"../request-structs.ss")
|
||||
|
||||
(define-struct (exn:fail:servlet:instance exn:fail) ())
|
||||
(define-struct servlet (custodian namespace manager handler))
|
||||
(define-struct servlet-instance-data (mutex context))
|
||||
|
||||
(define-struct execution-context (connection request suspend))
|
||||
|
||||
(define current-servlet (make-thread-cell #f))
|
||||
|
@ -27,4 +30,26 @@
|
|||
(define instance-id (thread-cell-ref current-servlet-instance-id))
|
||||
((manager-instance-lookup-data manager) instance-id))
|
||||
|
||||
(provide (all-defined)))
|
||||
(provide/contract
|
||||
[struct (exn:fail:servlet:instance exn:fail)
|
||||
([msg string?]
|
||||
[continuation-marks continuation-mark-set?])]
|
||||
[struct servlet
|
||||
([custodian custodian?]
|
||||
[namespace namespace?]
|
||||
[manager manager?]
|
||||
[handler (request? . -> . servlet-response?)])]
|
||||
[struct servlet-instance-data
|
||||
([mutex semaphore?]
|
||||
[context execution-context?])]
|
||||
[struct execution-context
|
||||
([connection connection?]
|
||||
[request request?]
|
||||
[suspend procedure?])]
|
||||
; XXX contract maybe
|
||||
[current-servlet thread-cell?]
|
||||
; XXX contract maybe
|
||||
[current-servlet-instance-id thread-cell?]
|
||||
[get-current-servlet-instance-id (-> number?)]
|
||||
[current-servlet-manager (-> manager?)]
|
||||
[current-servlet-instance-data (-> servlet-instance-data?)]))
|
|
@ -4,9 +4,9 @@
|
|||
(lib "list.ss")
|
||||
(lib "plt-match.ss"))
|
||||
|
||||
(provide
|
||||
match-url-params)
|
||||
(provide/contract
|
||||
; XXX contract maybe
|
||||
[match-url-params (string? . -> . (or/c false/c (list/c string? string? string? string?)))]
|
||||
[continuation-url? (url? . -> . (or/c boolean? (list/c number? number? number?)))]
|
||||
[embed-ids ((list/c number? number? number?) url? . -> . string?)])
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(module servlet-helpers mzscheme
|
||||
(require (lib "list.ss")
|
||||
(require (lib "contract.ss")
|
||||
(lib "etc.ss")
|
||||
(lib "plt-match.ss")
|
||||
(lib "xml.ss" "xml")
|
||||
|
@ -8,21 +8,10 @@
|
|||
(require "util.ss"
|
||||
"response.ss"
|
||||
"request-structs.ss"
|
||||
"bindings.ss")
|
||||
(provide get-host
|
||||
(all-from "bindings.ss")
|
||||
extract-user-pass
|
||||
build-suspender
|
||||
make-html-response/incremental
|
||||
report-errors-to-browser
|
||||
redirect-to
|
||||
permanently
|
||||
temporarily
|
||||
see-other
|
||||
(all-from "request-structs.ss")
|
||||
request-bindings
|
||||
request-headers
|
||||
translate-escapes)
|
||||
"bindings.ss"
|
||||
"servlet-structs.ss")
|
||||
(provide (all-from "bindings.ss")
|
||||
(all-from "request-structs.ss"))
|
||||
|
||||
(define (request-headers request)
|
||||
(map (match-lambda
|
||||
|
@ -134,4 +123,24 @@
|
|||
;; does the second part of the authorization header start with #"Basic "
|
||||
(define basic?
|
||||
(let ([rx (byte-regexp #"^Basic .*")])
|
||||
(lambda (a) (regexp-match rx a)))))
|
||||
(lambda (a) (regexp-match rx a))))
|
||||
|
||||
(provide ; all-from
|
||||
translate-escapes)
|
||||
(provide/contract
|
||||
[get-host (url? (listof header?) . -> . symbol?)]
|
||||
; XXX contract maybe
|
||||
[extract-user-pass ((listof header?) . -> . (or/c false/c (cons/c string? string?)))]
|
||||
[build-suspender (((listof xexpr?) (listof xexpr?))
|
||||
((listof (list/c symbol? string?)) (listof (list/c symbol? string?)))
|
||||
. opt-> .
|
||||
(k-url? . -> . xexpr?))]
|
||||
[make-html-response/incremental (((string? . -> . void) . -> . void) . -> . response/incremental?)]
|
||||
[report-errors-to-browser ((servlet-response? . -> . void) . -> . void)]
|
||||
[redirect-to ((string?) (redirection-status?) . opt-> . response/full?)]
|
||||
[permanently redirection-status?]
|
||||
[temporarily redirection-status?]
|
||||
[see-other redirection-status?]
|
||||
[request-bindings (request? . -> . (listof (or/c (cons/c symbol? string?)
|
||||
(cons/c symbol? bytes?))))]
|
||||
[request-headers (request? . -> . (listof (cons/c symbol? string?)))]))
|
|
@ -1,10 +1,11 @@
|
|||
(module servlet-language mzscheme
|
||||
(require (lib "class.ss")
|
||||
(lib "tool.ss" "drscheme")
|
||||
(lib "contract.ss")
|
||||
;(lib "mred.ss" "mred")
|
||||
(lib "unitsig.ss"))
|
||||
|
||||
(provide tool@)
|
||||
(provide/contract
|
||||
[tool@ unit/sig?])
|
||||
|
||||
(define tool@
|
||||
(unit/sig drscheme:tool-exports^
|
||||
|
@ -99,5 +100,4 @@
|
|||
;(language-numbers (list -1000 1000))
|
||||
))
|
||||
|
||||
)))
|
||||
)
|
||||
))))
|
42
collects/web-server/servlet-structs.ss
Normal file
42
collects/web-server/servlet-structs.ss
Normal file
|
@ -0,0 +1,42 @@
|
|||
(module servlet-structs mzscheme
|
||||
(require (lib "contract.ss")
|
||||
(lib "xml.ss" "xml"))
|
||||
(require "request-structs.ss"
|
||||
"response-structs.ss")
|
||||
|
||||
(define servlet-response?
|
||||
any/c)
|
||||
|
||||
(define (xexpr/callback? x)
|
||||
(correct-xexpr? x
|
||||
(lambda () #t)
|
||||
(lambda (exn)
|
||||
(if (procedure? (exn:invalid-xexpr-code exn))
|
||||
#t
|
||||
(begin ((error-display-handler) (exn-message exn) exn)
|
||||
#f)))))
|
||||
|
||||
(define k-url?
|
||||
string?)
|
||||
|
||||
(define response-generator?
|
||||
(k-url? . -> . servlet-response?))
|
||||
|
||||
(define url-transform?
|
||||
(k-url? . -> . k-url?))
|
||||
|
||||
(define expiration-handler?
|
||||
(or/c false/c
|
||||
(request? . -> . response?)))
|
||||
|
||||
(define embed/url?
|
||||
(((request? . -> . any/c)) (expiration-handler?) . opt-> . string?))
|
||||
|
||||
(provide/contract
|
||||
[servlet-response? contract?]
|
||||
[xexpr/callback? (any/c . -> . boolean?)]
|
||||
[response-generator? contract?]
|
||||
[k-url? (any/c . -> . boolean?)]
|
||||
[url-transform? contract?]
|
||||
[expiration-handler? contract?]
|
||||
[embed/url? contract?]))
|
|
@ -7,35 +7,8 @@
|
|||
"private/servlet.ss"
|
||||
"private/url.ss"
|
||||
"servlet-helpers.ss"
|
||||
"timer.ss"
|
||||
"web-cells.ss")
|
||||
|
||||
;; CONTRACT HELPERS
|
||||
(define servlet-response? any/c)
|
||||
|
||||
(define (xexpr/callback? x)
|
||||
(correct-xexpr? x
|
||||
(lambda () #t)
|
||||
(lambda (exn)
|
||||
(if (procedure? (exn:invalid-xexpr-code exn))
|
||||
#t
|
||||
(begin ((error-display-handler) (exn-message exn) exn)
|
||||
#f)))))
|
||||
|
||||
(define response-generator?
|
||||
(string? . -> . servlet-response?))
|
||||
|
||||
(define url-transform?
|
||||
(string? . -> . string?))
|
||||
|
||||
(define expiration-handler?
|
||||
(request? . -> . void?))
|
||||
|
||||
(define (parameter/c c)
|
||||
parameter?)
|
||||
|
||||
(define embed/url?
|
||||
(((request? . -> . any/c)) (expiration-handler?) . opt-> . string?))
|
||||
"web-cells.ss"
|
||||
"servlet-structs.ss")
|
||||
|
||||
;; ************************************************************
|
||||
;; HELPERS
|
||||
|
@ -52,10 +25,11 @@
|
|||
;; Weak contracts: the input is checked in output-response, and a message is
|
||||
;; sent directly to the client (Web browser) instead of the terminal/log.
|
||||
(provide/contract
|
||||
[xexpr/callback? (any/c . -> . boolean?)]
|
||||
[xexpr/callback->xexpr (embed/url? xexpr/callback? . -> . xexpr?)]
|
||||
[current-url-transform (parameter/c url-transform?)]
|
||||
[current-servlet-continuation-expiration-handler (parameter/c expiration-handler?)]
|
||||
; XXX contract
|
||||
[current-url-transform parameter?]
|
||||
; XXX contract
|
||||
[current-servlet-continuation-expiration-handler parameter?]
|
||||
[redirect/get (-> request?)]
|
||||
[redirect/get/forget (-> request?)]
|
||||
[adjust-timeout! (number? . -> . void?)]
|
||||
|
@ -68,17 +42,18 @@
|
|||
[send/suspend/callback (xexpr/callback? . -> . any/c)])
|
||||
|
||||
(require "url.ss")
|
||||
(provide
|
||||
(all-from "web-cells.ss")
|
||||
(provide (all-from "web-cells.ss")
|
||||
(all-from "servlet-helpers.ss")
|
||||
(all-from "url.ss"))
|
||||
(all-from "url.ss")
|
||||
(all-from "servlet-structs.ss"))
|
||||
|
||||
;; ************************************************************
|
||||
;; EXPORTS
|
||||
|
||||
;; current-url-transform : string? -> string?
|
||||
(define (default-url-transformer x) x)
|
||||
(define current-url-transform
|
||||
(make-parameter identity))
|
||||
(make-parameter default-url-transformer))
|
||||
|
||||
;; current-servlet-continuation-expiration-handler : request -> response
|
||||
(define current-servlet-continuation-expiration-handler
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
(module sig mzscheme
|
||||
(require (lib "unitsig.ss"))
|
||||
(provide
|
||||
dispatch-server^ dispatch-server-config^
|
||||
(require "dispatch-server-sig.ss")
|
||||
(provide ; XXX contract signature
|
||||
web-server^ servlet^ web-config^ web-config/pervasive^ web-config/local^)
|
||||
|
||||
(define-signature dispatch-server^
|
||||
(serve
|
||||
serve-ports
|
||||
; for environment:
|
||||
server-loop))
|
||||
(define-signature web-server^
|
||||
((open dispatch-server^)))
|
||||
|
||||
(define-signature dispatch-server-config^
|
||||
(port listen-ip max-waiting initial-connection-timeout
|
||||
read-request dispatch))
|
||||
|
||||
(define-signature servlet^
|
||||
(initial-request send/suspend send/finish send/back send/forward adjust-timeout!))
|
||||
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
(module timer mzscheme
|
||||
(require "timer-structs.ss")
|
||||
(require (lib "list.ss")
|
||||
(lib "contract.ss")
|
||||
(lib "async-channel.ss"))
|
||||
(provide timer?
|
||||
start-timer reset-timer! increment-timer!
|
||||
cancel-timer!
|
||||
start-timer-manager)
|
||||
(require "timer-structs.ss")
|
||||
|
||||
(define timer-ch (make-async-channel))
|
||||
|
||||
|
@ -86,7 +83,15 @@
|
|||
(revise-timer! timer
|
||||
(+ (- (timer-expire-seconds timer) (current-inexact-milliseconds))
|
||||
(* 1000 secs))
|
||||
(timer-action timer))))
|
||||
(timer-action timer)))
|
||||
|
||||
(provide/contract
|
||||
[timer? (any/c . -> . boolean?)]
|
||||
[start-timer-manager (custodian? . -> . void)]
|
||||
[start-timer (number? (-> void) . -> . timer?)]
|
||||
[reset-timer! (timer? number? . -> . void)]
|
||||
[increment-timer! (timer? number? . -> . void)]
|
||||
[cancel-timer! (timer? . -> . void)]))
|
||||
|
||||
; --- timeout plan
|
||||
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
(module url mzscheme
|
||||
(require (lib "list.ss")
|
||||
(lib "etc.ss")
|
||||
(lib "contract.ss")
|
||||
(lib "url.ss" "net")
|
||||
(lib "struct.ss"))
|
||||
(require "private/url.ss"
|
||||
"request-structs.ss")
|
||||
|
||||
;; URL parsing
|
||||
(provide (struct servlet-url (protocol host port servlets-root instance-id k-id nonce servlet-path extra-path))
|
||||
servlet-url->url-string
|
||||
servlet-url->url-string/no-continuation
|
||||
servlet-url->servlet-url/no-extra-path
|
||||
request->servlet-url
|
||||
uri->servlet-url)
|
||||
(define-struct servlet-url (protocol host port
|
||||
servlets-root
|
||||
instance-id k-id nonce
|
||||
|
@ -88,4 +82,22 @@
|
|||
(list (first (url-path uri)))
|
||||
k-instance k-id k-salt
|
||||
servlet-path
|
||||
path)))))
|
||||
path))))
|
||||
|
||||
(provide/contract
|
||||
; XXX contract maybe
|
||||
[struct servlet-url ([protocol (or/c false/c string?)]
|
||||
[host (or/c false/c string?)]
|
||||
[port (or/c false/c natural-number/c)]
|
||||
[servlets-root (listof path/param?)]
|
||||
[instance-id number?]
|
||||
[k-id number?]
|
||||
[nonce number?]
|
||||
[servlet-path (listof path/param?)]
|
||||
[extra-path (listof path/param?)])]
|
||||
[servlet-url->url-string (servlet-url? . -> . string?)]
|
||||
[servlet-url->url-string/no-continuation (servlet-url? . -> . string?)]
|
||||
[servlet-url->servlet-url/no-extra-path (servlet-url? . -> . servlet-url?)]
|
||||
[request->servlet-url (request? . -> . servlet-url?)]
|
||||
; XXX contract maybe
|
||||
[uri->servlet-url ((url?) ((or/c false/c string?) (or/c false/c natural-number/c)) . opt-> . servlet-url?)]))
|
|
@ -8,24 +8,6 @@
|
|||
(lib "uri-codec.ss" "net"))
|
||||
(require "request-structs.ss")
|
||||
|
||||
(provide provide-define-struct
|
||||
extract-flag
|
||||
translate-escapes
|
||||
hash-table-empty?
|
||||
url-path->string)
|
||||
|
||||
(provide/contract
|
||||
[valid-port? (any/c . -> . boolean?)]
|
||||
[decompose-request ((request?) . ->* . (url? symbol? string?))]
|
||||
[network-error ((symbol? string?) (listof any/c) . ->* . (void))]
|
||||
[path->list (path? . -> . (cons/c (or/c path? (symbols 'up 'same))
|
||||
(listof (or/c path? (symbols 'up 'same)))))]
|
||||
[url-path->path ((or/c (symbols 'up 'same) path?) string? . -> . path?)]
|
||||
[directory-part (path? . -> . path?)]
|
||||
[lowercase-symbol! ((or/c string? bytes?) . -> . symbol?)]
|
||||
[exn->string ((or/c exn? any/c) . -> . string?)]
|
||||
[build-path-unless-absolute (path? (or/c string? path?) . -> . path?)])
|
||||
|
||||
;; valid-port? : any/c -> boolean?
|
||||
(define (valid-port? p)
|
||||
(and (number? p) (integer? p) (exact? p) (<= 1 p 65535)))
|
||||
|
@ -89,7 +71,7 @@
|
|||
;; Notes: (GregP)
|
||||
;; 1. What's the significance of char # 255 ???
|
||||
;; 2. 255 isn't an ascii character. ascii is 7-bit
|
||||
;; 3. OK fuck this. It is only used in three places, some of them
|
||||
;; 3. OK f this. It is only used in three places, some of them
|
||||
;; will involve bytes while the others may involve strings. So
|
||||
;; I will just use regular expressions and get on with life.
|
||||
(define (prefix?-old prefix)
|
||||
|
@ -153,20 +135,6 @@
|
|||
null
|
||||
(regexp-split #rx"/" p)))))))
|
||||
|
||||
; update-params : Url (U #f String) -> String
|
||||
; to create a new url just like the old one, but with a different parameter part
|
||||
;; GREGP: this is broken! replace with the version from new-kernel
|
||||
; (define (update-params uri params)
|
||||
; (url->string
|
||||
; (make-url (url-scheme uri)
|
||||
; (url-user uri)
|
||||
; (url-host uri)
|
||||
; (url-port uri)
|
||||
; (url-path uri)
|
||||
; params
|
||||
; (url-query uri)
|
||||
; (url-fragment uri))))
|
||||
|
||||
; to convert a platform dependent path into a listof path parts such that
|
||||
; (forall x (equal? (path->list x) (path->list (apply build-path (path->list x)))))
|
||||
(define (path->list p)
|
||||
|
@ -178,19 +146,9 @@
|
|||
[else ; conflate 'relative and #f
|
||||
new-acc])))))
|
||||
|
||||
; this should go somewhere that other collections can use it too
|
||||
(define-syntax provide-define-struct
|
||||
(lambda (stx)
|
||||
(syntax-case stx ()
|
||||
[(_ (struct-name parent-name) (field ...))
|
||||
(syntax (begin (define-struct (struct-name parent-name) (field ...))
|
||||
(provide (struct struct-name (field ...)))))]
|
||||
[(_ struct-name (field ...))
|
||||
(syntax (begin (define-struct struct-name (field ...))
|
||||
(provide (struct struct-name (field ...)))))])))
|
||||
|
||||
; this is used by launchers
|
||||
; extract-flag : sym (listof (cons sym alpha)) alpha -> alpha
|
||||
; XXX remove
|
||||
(define (extract-flag name flags default)
|
||||
(let ([x (assq name flags)])
|
||||
(if x
|
||||
|
@ -199,9 +157,7 @@
|
|||
|
||||
; hash-table-empty? : hash-table -> bool
|
||||
(define (hash-table-empty? table)
|
||||
(let/ec out
|
||||
(hash-table-for-each table (lambda (k v) (out #f)))
|
||||
#t))
|
||||
(zero? (hash-table-count table)))
|
||||
|
||||
; This comes from Shriram's collection, and should be exported form there.
|
||||
; translate-escapes : String -> String
|
||||
|
@ -220,4 +176,20 @@
|
|||
(cond
|
||||
[(char=? ic #\+) #\space]
|
||||
[else ic]))
|
||||
(list* c (loop cs))])))))
|
||||
(list* c (loop cs))]))))
|
||||
|
||||
(provide/contract
|
||||
[url-path->string ((listof (or/c string? path/param?)) . -> . string?)]
|
||||
[extract-flag (symbol? (listof (cons/c symbol? any/c)) any/c . -> . any/c)]
|
||||
[translate-escapes (string? . -> . string?)]
|
||||
[hash-table-empty? (any/c . -> . boolean?)]
|
||||
[valid-port? (any/c . -> . boolean?)]
|
||||
[decompose-request ((request?) . ->* . (url? symbol? string?))]
|
||||
[network-error ((symbol? string?) (listof any/c) . ->* . (void))]
|
||||
[path->list (path? . -> . (cons/c (or/c path? (symbols 'up 'same))
|
||||
(listof (or/c path? (symbols 'up 'same)))))]
|
||||
[url-path->path ((or/c (symbols 'up 'same) path?) string? . -> . path?)]
|
||||
[directory-part (path? . -> . path?)]
|
||||
[lowercase-symbol! ((or/c string? bytes?) . -> . symbol?)]
|
||||
[exn->string ((or/c exn? any/c) . -> . string?)]
|
||||
[build-path-unless-absolute (path? (or/c string? path?) . -> . path?)]))
|
|
@ -1,12 +1,12 @@
|
|||
(module web-cells mzscheme
|
||||
(require (lib "struct.ss"))
|
||||
(require (lib "struct.ss")
|
||||
(lib "contract.ss"))
|
||||
|
||||
(define-struct (exn:fail:frame:top exn) ())
|
||||
(define (exn:fail:frame:top-raise)
|
||||
(raise (make-exn:fail:frame:top
|
||||
"Reached top of stack"
|
||||
(current-continuation-marks))))
|
||||
(provide exn:fail:frame:top?)
|
||||
|
||||
;; frames
|
||||
(define-struct frame ())
|
||||
|
@ -62,9 +62,7 @@
|
|||
#t (frame:ns-namespace a-frame)))
|
||||
|
||||
;; frame stacks
|
||||
|
||||
(define *global-root-id* (gensym))
|
||||
(define *session-root-id* (gensym))
|
||||
|
||||
; *frame-stack* : (box frame)
|
||||
(define *frame-stack*
|
||||
|
@ -80,26 +78,11 @@
|
|||
(define (global-root? a-frame)
|
||||
(annotation-present? *global-root-id* a-frame))
|
||||
|
||||
; session-root? : frame:ns -> boolean
|
||||
(define (session-root? a-frame)
|
||||
(annotation-present? *session-root-id* a-frame))
|
||||
|
||||
; make-frame/top : -> frame:ns
|
||||
(define (make-frame/top)
|
||||
(let* ([cur-top-box (*frame-stack*)]
|
||||
[cur-top (unbox cur-top-box)])
|
||||
(cond
|
||||
#;[(not (frame:ns? cur-top))
|
||||
; Construct global
|
||||
(copy-struct frame:ns (make-frame/parent cur-top-box)
|
||||
[frame:ns-annotations (list (cons *global-root-id* #t))])]
|
||||
[(global-root? cur-top)
|
||||
; Construct session
|
||||
(copy-struct frame:ns (make-frame/parent cur-top-box)
|
||||
[frame:ns-annotations (list (cons *session-root-id* #t))])]
|
||||
[else
|
||||
; Construct normal
|
||||
(make-frame/parent cur-top-box)])))
|
||||
(define cur-top-box (*frame-stack*))
|
||||
(define cur-top (unbox cur-top-box))
|
||||
(make-frame/parent cur-top-box))
|
||||
|
||||
; push-frame! : -> void
|
||||
; Pushs a new frame onto the session stack
|
||||
|
@ -114,10 +97,10 @@
|
|||
; save-stack/push/return : (-> 'a) -> 'a
|
||||
; Pushes a frame after the thunk's execution with the same parent as the call site
|
||||
(define (save-stack/push/return thunk)
|
||||
(let ([initial-stack (*frame-stack*)])
|
||||
(define initial-stack (*frame-stack*))
|
||||
(begin0 (thunk)
|
||||
(*frame-stack* initial-stack)
|
||||
(push-frame!))))
|
||||
(push-frame!)))
|
||||
|
||||
; syntax version of above
|
||||
(define-syntax with-frame-after
|
||||
|
@ -143,106 +126,42 @@
|
|||
|
||||
; cells
|
||||
(define-struct cell (id))
|
||||
(define-struct (cell:global cell) ())
|
||||
(define-struct (cell:session cell) ())
|
||||
(define-struct (cell:local cell) ())
|
||||
|
||||
(define web-cell:local? cell:local?)
|
||||
|
||||
; ext:make-'a 'b -> 'a
|
||||
(define (ext:make-cell:global default)
|
||||
(let ([new-name (gensym)])
|
||||
(define (make-web-cell:local default)
|
||||
(define new-name (gensym))
|
||||
(frame-set! (search-stack global-root?)
|
||||
new-name default)
|
||||
(make-cell:global new-name)))
|
||||
(define (ext:make-cell:session default)
|
||||
(let ([new-name (gensym)])
|
||||
(frame-set! (search-stack global-root?)
|
||||
new-name default)
|
||||
(make-cell:session new-name)))
|
||||
(define (ext:make-cell:local default)
|
||||
(let ([new-name (gensym)])
|
||||
(frame-set! (search-stack global-root?)
|
||||
new-name default)
|
||||
(make-cell:local new-name)))
|
||||
|
||||
; cell:global-ref : cell:global -> any
|
||||
; returns the value of the global cell
|
||||
(define (cell:global-ref gc)
|
||||
(frame-ref (search-stack global-root?)
|
||||
(cell-id gc)))
|
||||
; cell:global-set! : cell:global any -> void
|
||||
; sets the value of the global cell
|
||||
(define (cell:global-set! gc nv)
|
||||
(frame-set! (search-stack global-root?)
|
||||
(cell-id gc)
|
||||
nv))
|
||||
|
||||
; cell:session-ref : cell:session -> any
|
||||
; returns the value of the session cell
|
||||
(define (cell:session-ref sc)
|
||||
(frame-ref (search-stack session-root?)
|
||||
(cell-id sc)))
|
||||
; cell:session-set! : cell:session any -> void
|
||||
; sets the value of the session cell
|
||||
(define (cell:session-set! sc nv)
|
||||
(frame-set! (search-stack session-root?)
|
||||
(cell-id sc)
|
||||
nv))
|
||||
(make-cell:local new-name))
|
||||
|
||||
; cell:local-ref : cell:local -> any
|
||||
; returns the value of the local cell
|
||||
(define (cell:local-ref lc)
|
||||
(define (web-cell:local-ref lc)
|
||||
(frame-ref (search-stack frame?)
|
||||
(cell-id lc)))
|
||||
; cell:local-set! : cell:local any -> void
|
||||
; sets the value of the local cell at the last place it was set, including the default
|
||||
(define (cell:local-set! lc nv)
|
||||
(define (web-cell:local-set! lc nv)
|
||||
(frame-set! (search-stack
|
||||
(lambda (f) (frame-set? f (cell-id lc))))
|
||||
(cell-id lc)
|
||||
nv))
|
||||
; cell:local-mask : cell:local any -> void
|
||||
; masks the local cell to the given value
|
||||
(define (cell:local-mask lc nv)
|
||||
(define (web-cell:local-mask lc nv)
|
||||
(frame-set! (search-stack frame?)
|
||||
(cell-id lc)
|
||||
nv))
|
||||
|
||||
; cell-ref : cell -> any
|
||||
(define (cell-ref c)
|
||||
(cond
|
||||
[(cell:global? c) (cell:global-ref c)]
|
||||
[(cell:session? c) (cell:session-ref c)]
|
||||
[(cell:local? c) (cell:local-ref c)]))
|
||||
|
||||
; ;; linking parameters to cells
|
||||
; (define *parameter-links* (ext:make-cell:session (list)))
|
||||
; (define-struct parameter-link (parameter cell))
|
||||
;
|
||||
; ; link-parameter : parameter cell -> void
|
||||
; (define (link-parameter p c)
|
||||
; (cell:session-set! *parameter-links*
|
||||
; (cons (make-parameter-link p c)
|
||||
; (cell:session-ref *parameter-links*))))
|
||||
;
|
||||
; ; reinstall-linked-parameters : -> void
|
||||
; (define (reinstall-linked-parameters)
|
||||
; (for-each (lambda (link)
|
||||
; ((parameter-link-parameter link)
|
||||
; (cell-ref (parameter-link-cell link))))
|
||||
; (cell:session-ref *parameter-links*)))
|
||||
|
||||
(provide with-frame
|
||||
with-frame-after
|
||||
(rename cell:global? web-cell:global?)
|
||||
(rename ext:make-cell:global make-web-cell:global)
|
||||
(rename cell:global-ref web-cell:global-ref)
|
||||
(rename cell:global-set! web-cell:global-set!)
|
||||
(rename cell:session? web-cell:session?)
|
||||
(rename ext:make-cell:session make-web-cell:session)
|
||||
(rename cell:session-ref web-cell:session-ref)
|
||||
(rename cell:session-set! web-cell:session-set!)
|
||||
(rename cell:local? web-cell:local?)
|
||||
(rename ext:make-cell:local make-web-cell:local)
|
||||
(rename cell:local-ref web-cell:local-ref)
|
||||
(rename cell:local-set! web-cell:local-set!)
|
||||
(rename cell:local-mask web-cell:local-mask)))
|
||||
(provide with-frame ; syntax
|
||||
with-frame-after)
|
||||
(provide/contract
|
||||
[exn:fail:frame:top? (any/c . -> . boolean?)]
|
||||
[web-cell:local? (any/c . -> . boolean?)]
|
||||
[make-web-cell:local (any/c . -> . web-cell:local?)]
|
||||
[web-cell:local-ref (web-cell:local? . -> . any/c)]
|
||||
[web-cell:local-set! (web-cell:local? any/c . -> . void)]
|
||||
[web-cell:local-mask (web-cell:local? any/c . -> . void)]))
|
|
@ -1,9 +1,14 @@
|
|||
(module web-server-structs mzscheme
|
||||
(provide (all-defined))
|
||||
(require (lib "contract.ss"))
|
||||
(require "contract.ss")
|
||||
|
||||
(define current-server-custodian (make-parameter #f))
|
||||
(provide current-server-custodian) ; parameter
|
||||
|
||||
;; make-servlet-custodian: -> custodian
|
||||
;; create a custodian for the dynamic extent of a servlet continuation
|
||||
(define (make-servlet-custodian)
|
||||
(make-custodian (current-server-custodian))))
|
||||
(make-custodian (current-server-custodian)))
|
||||
|
||||
(provide/contract
|
||||
[make-servlet-custodian (-> custodian?)]))
|
|
@ -1,9 +1,12 @@
|
|||
(module web-server-unit mzscheme
|
||||
(require (lib "tcp-sig.ss" "net")
|
||||
(lib "contract.ss")
|
||||
(lib "unitsig.ss"))
|
||||
(require "sig.ss"
|
||||
"dispatch-server-unit.ss"
|
||||
"dispatch-server-sig.ss"
|
||||
"web-server-structs.ss"
|
||||
"connection-manager.ss"
|
||||
"configuration-structures.ss"
|
||||
"servlet.ss"
|
||||
"private/cache-table.ss"
|
||||
(rename "private/request.ss"
|
||||
the-read-request read-request))
|
||||
|
@ -14,105 +17,9 @@
|
|||
(prefix path-procedure: "dispatchers/dispatch-pathprocedure.ss")
|
||||
(prefix log: "dispatchers/dispatch-log.ss")
|
||||
(prefix host: "dispatchers/dispatch-host.ss"))
|
||||
(require (lib "tcp-sig.ss" "net")
|
||||
(lib "unitsig.ss")
|
||||
(lib "string.ss")
|
||||
(lib "list.ss")
|
||||
(lib "url.ss" "net"))
|
||||
|
||||
(provide web-server@)
|
||||
|
||||
;; ****************************************
|
||||
(define dispatch-server@
|
||||
(unit/sig dispatch-server^
|
||||
(import net:tcp^ (config : dispatch-server-config^))
|
||||
|
||||
;; serve: -> -> void
|
||||
;; start the server and return a thunk to shut it down
|
||||
(define (serve)
|
||||
(define the-server-custodian (make-custodian))
|
||||
(start-connection-manager the-server-custodian)
|
||||
(parameterize ([current-custodian the-server-custodian]
|
||||
[current-server-custodian the-server-custodian]
|
||||
[current-thread-initial-stack-size 3])
|
||||
(thread
|
||||
(lambda ()
|
||||
(start-listener))))
|
||||
(lambda ()
|
||||
(custodian-shutdown-all the-server-custodian)))
|
||||
|
||||
;; start-listener : -> void
|
||||
;; loops around starting a listener if the current listener dies
|
||||
(define (start-listener)
|
||||
(define listener
|
||||
(tcp-listen config:port config:max-waiting
|
||||
#t config:listen-ip))
|
||||
(define get-ports
|
||||
(lambda () (tcp-accept listener)))
|
||||
(with-handlers ([void (lambda (e)
|
||||
; If the exception did not kill the listener
|
||||
(with-handlers ([void void])
|
||||
(tcp-close listener))
|
||||
; Rethrow the error to this thread's error printer
|
||||
(raise e))])
|
||||
(server-loop get-ports
|
||||
tcp-addresses)))
|
||||
|
||||
;; server-loop: (-> input-port output-port) (input-port -> string string) -> void
|
||||
;; start a thread to handle each incoming connection
|
||||
(define (server-loop get-ports port-addresses)
|
||||
(let loop ()
|
||||
(define connection-cust (make-custodian))
|
||||
(parameterize ([current-custodian connection-cust])
|
||||
(define-values (ip op) (get-ports))
|
||||
(serve-ports/inner ip op
|
||||
port-addresses))
|
||||
(loop)))
|
||||
|
||||
;; serve-ports : input-port output-port -> void
|
||||
;; returns immediately, spawning a thread to handle
|
||||
;; the connection
|
||||
;; NOTE: (GregP) should allow the user to pass in a connection-custodian
|
||||
(define (serve-ports ip op)
|
||||
(define server-cust (make-custodian))
|
||||
(start-connection-manager server-cust)
|
||||
(parameterize ([current-custodian server-cust]
|
||||
[current-server-custodian server-cust])
|
||||
(define connection-cust (make-custodian))
|
||||
(parameterize ([current-custodian connection-cust])
|
||||
(serve-ports/inner ip op
|
||||
(lambda (ip)
|
||||
(values "127.0.0.1"
|
||||
"127.0.0.1"))))))
|
||||
|
||||
;; serve-ports/inner : input-port output-port (input-port -> string string) -> void
|
||||
;; returns immediately, spawning a thread to handle
|
||||
(define (serve-ports/inner ip op port-addresses)
|
||||
(thread
|
||||
(lambda ()
|
||||
(define conn
|
||||
(new-connection config:initial-connection-timeout
|
||||
ip op (current-custodian) #f))
|
||||
(with-handlers ([exn:fail:network?
|
||||
(lambda (e)
|
||||
(kill-connection! conn)
|
||||
(raise e))])
|
||||
(serve-connection conn port-addresses)))))
|
||||
|
||||
;; serve-connection: connection (input-port -> string string) -> void
|
||||
;; respond to all requests on this connection
|
||||
(define (serve-connection conn port-addresses)
|
||||
(let connection-loop ()
|
||||
(define-values (req close?) (config:read-request conn config:port port-addresses))
|
||||
(unless close?
|
||||
(set-connection-close?! conn #f))
|
||||
(adjust-connection-timeout! conn config:initial-connection-timeout)
|
||||
(config:dispatch conn req)
|
||||
(when close?
|
||||
(set-connection-close?! conn #t))
|
||||
(cond
|
||||
[(connection-close? conn) (kill-connection! conn)]
|
||||
[else (connection-loop)])))))
|
||||
(provide/contract
|
||||
; XXX contract
|
||||
[web-server@ unit/sig?])
|
||||
|
||||
(define web-config@->dispatch-server-config@
|
||||
(unit/sig dispatch-server-config^
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
(module web-server mzscheme
|
||||
(require (lib "tcp-sig.ss" "net")
|
||||
(lib "unitsig.ss")
|
||||
(lib "contract.ss")
|
||||
"sig.ss"
|
||||
"web-server-unit.ss"
|
||||
"configuration.ss")
|
||||
(provide serve)
|
||||
"configuration.ss"
|
||||
"configuration-structures.ss")
|
||||
(provide/contract
|
||||
[serve (case-> [configuration? . -> . (-> void?)]
|
||||
[configuration? natural-number/c . -> . (-> void?)]
|
||||
[configuration? natural-number/c string? . -> . (-> void?)])])
|
||||
|
||||
; : configuration [nat] [(U str #f)] -> -> void
|
||||
(define serve
|
||||
|
@ -29,6 +34,4 @@
|
|||
(serve))
|
||||
s)])
|
||||
(export))
|
||||
net:tcp^))
|
||||
|
||||
)
|
||||
net:tcp^)))
|
|
@ -1,17 +0,0 @@
|
|||
;; Mike Burns 2004
|
||||
|
||||
;; Used for send/suspend/callback.
|
||||
|
||||
(module xexpr-callback mzscheme
|
||||
(require (lib "xml.ss" "xml"))
|
||||
(provide xexpr/callback?)
|
||||
|
||||
;; Is it a Xexpr, or an Xexpr with procedures?
|
||||
(define (xexpr/callback? x)
|
||||
(correct-xexpr? x
|
||||
(lambda () #t)
|
||||
(lambda (exn)
|
||||
(if (procedure? (exn:invalid-xexpr-code exn))
|
||||
#t
|
||||
(begin ((error-display-handler) (exn-message exn) exn)
|
||||
#f))))))
|
Loading…
Reference in New Issue
Block a user