Tuesday, August 25, 2009

A Unified Startup Script

Up to now we have kept the startup script in two separate places: one is the servlet.ss so it can be readily used as a servlet, and the other is web.ss that will serve the single servlet. Satisfying our adherence to the Pareto principle, we will support out of the box only the single servlet method, so we'll combine the two files into one.

By combining the two into one we'll also solve an interesting issue: up to now shp-handler does not really have access to the htdocs path, since that value is consumed by the serve/servlet but is not really passed to make-shp-handler in the separated approach. Now we'll remedy this problem:

(define (start-shp-server! path
#:htdocs (htdocs #f)
#:port (port 8080)
#:default (default "index")
#:not-found (not-found #f)
#:required (required "/include/required")
#:topfilter (topfilter #f)
#:chrome (chrome #f))
(define start
(make-shp-handler path
#:default default
#:not-found not-found
#:required required
#:topfilter topfilter
#:chrome chrome
#:htdocs htdocs))
(thread (lambda ()
(serve/servlet start #:port port
#:servlet-path "/"
#:launch-browser? #f
#:listen-ip #f
#:servlet-namespace (list (path->string (this-expression-file-name)))
#:servlets-root path
#:servlet-regexp #px".*"
#:server-root-path path
#:extra-files-paths (list (if (path? htdocs)
(string->path htdocs)))

The single function now creates the shp-handler and start web-server at the same time. All that's left to do is to pass the value of the htdocs into shp-handler. We want to be able to access the value in shp script as follows:


So to accomplish the following, we will first add an additional attribute to shp-handler struct:

(define-struct shp-handler (... htdocs)

Then we will modify the constructor function to take in an htdocs parameter:

(define (*make-shp-handler path
#:htdocs (htdocs #f))
(make-shp-handler path
(if (not htdocs)
(build-path path 'up "file")


Which defaults to the the "file" directory in the same directory that "shp" directory live in.

Finally - we have the accessor function to be used in the SHP scripts:

(define ($htdocs)
(shp-handler-htdocs ($server)))

Lastly - let's make sure we have error checking to test for both the shp and htdocs path's existence.

(define (*make-shp-handler path
#:htdocs (htdocs #f))
(unless (directory-exists? path)
(error 'make-shp-handler "path ~a does not exist." path))
(let ((htdocs
(let ((htdocs (if (not htdocs)
(build-path path 'up "file")
(if (directory-exists? htdocs)
(error 'make-shp-handler "htdocs path ~a does not exist." htdocs)))))

Now we can simple do the following to start the site with any path.

(require (planet bzlib/shp/start))
(start-shp-server! <path> #:htdocs <htdocs-path>)

No comments:

Post a Comment