From 5e825e2acc6039fdd52a7a19a44174aea23a68a7 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 28 Nov 2014 00:45:20 -0500 Subject: [PATCH] Add a new `extra-dispatcher-file' configuration option. This allows handling other requests to implement additional course-related functionality by the already running server (instead of adding more servers for whatever's needed). The documentation needs more work though: it refers to `dispatcher/c' which needs to be added, and there is no real sample code for it. (My use is too specific to be used.) --- handin-server/private/config.rkt | 1 + handin-server/private/hooker.rkt | 15 +++++++++-- handin-server/run-servlet.rkt | 3 +++ handin-server/scribblings/server-setup.scrbl | 26 +++++++++++++++++--- handin-server/web-status-server.rkt | 9 ++++--- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/handin-server/private/config.rkt b/handin-server/private/config.rkt index bdcc875..d69553b 100644 --- a/handin-server/private/config.rkt +++ b/handin-server/private/config.rkt @@ -79,6 +79,7 @@ [(port-number) (values 7979 id )] [(use-https) (values #t id )] [(hook-file) (values #f path/false )] + [(extra-dispatcher-file) (values #f path/false )] [(session-timeout) (values 300 id )] [(session-memory-limit) (values 40000000 id )] [(default-file-name) (values "handin.rkt" id )] diff --git a/handin-server/private/hooker.rkt b/handin-server/private/hooker.rkt index 780a0d1..0861ec3 100644 --- a/handin-server/private/hooker.rkt +++ b/handin-server/private/hooker.rkt @@ -2,11 +2,10 @@ (require "config.rkt" "logger.rkt" "reloadable.rkt") -(provide hook) +(provide hook extra-dispatcher) (define hook-file #f) (define hook-proc #f) - (define (hook what alist) (let ([file (get-conf 'hook-file)]) (when file @@ -15,3 +14,15 @@ (set! hook-proc (auto-reload-procedure `(file ,(path->string file)) 'hook))) (hook-proc what (current-session) alist)))) + +(define dispatcher-file #f) +(define dispatcher-proc #f) +(define ((extra-dispatcher otherwise) connection request) + (let ([file (get-conf 'extra-dispatcher-file)]) + (cond [(not file) (otherwise)] + [else (unless (equal? file dispatcher-file) + (set! dispatcher-file file) + (set! dispatcher-proc + (auto-reload-procedure `(file ,(path->string file)) + 'dispatcher))) + (dispatcher-proc connection request)]))) diff --git a/handin-server/run-servlet.rkt b/handin-server/run-servlet.rkt index 6580b81..49e58a6 100644 --- a/handin-server/run-servlet.rkt +++ b/handin-server/run-servlet.rkt @@ -13,6 +13,7 @@ web-server/managers/lru (prefix-in sequencer: web-server/dispatchers/dispatch-sequencer) (prefix-in log: web-server/dispatchers/dispatch-log) + web-server/dispatchers/dispatch web-server/http/request-structs net/url openssl @@ -67,6 +68,7 @@ (provide run-servlet) (define (run-servlet dispatcher + #:extra-dispatcher [extra-dispatcher #f] #:log-file [log-file #f]) ;; a channel for incoming requests (define ach (make-async-channel)) @@ -93,6 +95,7 @@ (wrap-sequence (and log-file (log:make #:format (log:log-format->format 'apache-default) #:log-path log-file)) + (and extra-dispatcher (extra-dispatcher next-dispatcher)) (let ([init-path (make-parameter "/")]) (dispatch/servlet (lambda (req) diff --git a/handin-server/scribblings/server-setup.scrbl b/handin-server/scribblings/server-setup.scrbl index 329de8c..2089115 100644 --- a/handin-server/scribblings/server-setup.scrbl +++ b/handin-server/scribblings/server-setup.scrbl @@ -170,7 +170,7 @@ This directory contains the following files and sub-directories: @filepath{users.rktd} file and fill in such information. (The third element for such descriptors is ignored.)} - @item{@indexed-racket[hook-file] --- a path (relative to handin + @item{@indexed-racket[hook-file] --- a path (relative to the handin server directory or absolute) that specifies a filename that contains a `hook' module. This is useful as a general device for customizing the server through Racket code. The file is expected @@ -217,11 +217,29 @@ This directory contains the following files and sub-directories: '("course-staff@university.edu") '() '() (map (lambda (key+val) (apply format "~a: ~s" key+val)) - alist))))]}}] - + alist))))]}} + + @item{@indexed-racket[extra-dispatcher-file] --- a path (relative to + the handin server directory or absolute) that specifies a filename + that contains a `dispatcher' module. When specified, this file will + be loaded, and it is expected to provide a @racket[dispatcher] + function, which can be used by the web server, i.e., one that + satisfies @racket[dispatcher/c]. This dispatcher will get used in + the embedded handin server, before the handin servlet. It can + therefore be used to handle additional servlets that implement + additional functionality. Here is a sample skeleton: + + @racketmod[ + racket/base + (require web-server/http web-server/servlet-dispatch) + (provide dispatcher) + (define (start req) + ;; implement the "foo" operation + ....) + (define dispatcher (dispatch/servlet start #:regexp #rx"^/foo"))]}] The @secref{grading-utils} uses the following keys: - + @itemlist[ @item{@indexed-racket[deadline]: sets a per-assignment deadline for submissions, diff --git a/handin-server/web-status-server.rkt b/handin-server/web-status-server.rkt index 70dc21b..9c8be0a 100644 --- a/handin-server/web-status-server.rkt +++ b/handin-server/web-status-server.rkt @@ -9,10 +9,10 @@ web-server/servlet web-server/compat/0/coerce web-server/compat/0/http/response-structs - handin-server/private/md5 - handin-server/private/logger - handin-server/private/config - handin-server/private/hooker + "private/md5.rkt" + "private/logger.rkt" + "private/config.rkt" + "private/hooker.rkt" "run-servlet.rkt") (define (aget alist key) @@ -343,6 +343,7 @@ (begin0 (parameterize ([error-print-context-length 0]) (run-servlet dispatcher + #:extra-dispatcher extra-dispatcher #:log-file (get-conf 'web-log-file))) (log-line "*** embedded web server started")) ;; simple "server" so it's known that there is no server