You are looking at historical revision 15648 of this page. It may differ significantly from its current revision.

Description

uri-dispatch is a simple mechanism to dispatch uris to procedures. This is useful for webprogramming where you might want to map uris of a certain kind to procedures that implement the logic for those uris.

Author

David Krentzlin

Requirements

Requires the uri-common and environments extensions.

Documentation

[procedure] (dispatch-uri URI)

The main interface to dispatch-uri. This procedure invokes the dispatch-mechanism with the supplied uri. The dispatch-algorithm is implemented as follows:

(Note See also the whitelisting-section, to learn how to limit the exposure of procdures)

All those lookups are done in the current dispatch-environment, which can be parameterized.

Whitelisting

Though nice for development it is not advisable to allow everybody out there to invoke abritary procedures of your application. So you might want to whitelist only those procedures that really acts as the interface of your application.

To enable whitelisting you simply parameterize the whitelist parameter with your whitelisting-specification. If a procedure is requested that does exist but is not whitelisted dispatch-error is invoked.

Whitelisting specification

The whitelist allows to selectivly whitelist procedures modules and procedures inside modules. The examples explain all three cases

(whitelist '(proc1 proc2 proc3)) 

This will whitelist the procedures proc1..proc3. Those procedures must be defined outside a module.

(whitelist '((mod1 . (proc1 proc2))

This will whitelist the procedures proc1 and proc2 that must reside inside the module mod1.

(whitelist '((mod1 . *))

This will whitelist all procedures inside the module mod1.

Of course you can mix those declarations.

[parameter] whitelist

The parameter holding the whitelist. It defaults to #f which means whitelisting is disabled.

[parameter] dispatch-error

If no handler for a uri can be found, the dispatcher will invoke the procedure that dispatch-error is currently parameterized with. NOTE dispatch-error is also invoked if the requested handler exists but is not whitelisted. Defaults to (constantly #f).

[parameter] enable-whitelisting

If set to #t then whitelist-checks are enabled. Defaults to #f.

[parameter] default-dispatch-target

A thunk that is invoke when the uri-path was empty. If set to #f then an empty path leads to the invocation of dispatch-error. Defaults to #f.

[parameter] dispatch-environment

The environment that is used to lookup the procedures. It defaults to interaction-environment.

Examples

<pre>

(use spiffy intarweb uri-common uri-dispatch)

(define (my-dispatch-error . path)

 (send-status 404 (sprintf "My Dispatch-error ~A" path)))

(module example

 (echo webiota)
 (import scheme chicken srfi-1 extras)
 (require-library spiffy)
 (import (only spiffy send-status))
 (define (webiota #!optional (start "0") (steps "10") #!rest rest)
   (send-status 200 (sprintf "webiota called: ~A" (iota (string->number steps) (string->number start)))))
 (define (echo . args)
   (send-status 200 (sprintf "echo: ~A" args))))

(define (outsidemodule . args) (send-status 200 "Outside module"))

(vhost-map `(("localhost" . ,(lambda (continue)

                             (parameterize ((handle-not-found  (lambda (path) (dispatch-uri (request-uri (current-request)))))
                                            (dispatch-error (lambda path (send-status 404 (sprintf "Path not found: ~A" path)))))
                               (continue))))))

(start-server) </pre>

Now start the server and visit the following pages: