source: project/wiki/eggref/4/uri-dispatch @ 15377

Last change on this file since 15377 was 15377, checked in by certainty, 11 years ago

Changes applied for certainty (82.82.131.238) through svnwiki:

  • Property svnwiki:tags set to web
  • Property svnwiki:title set to uri-dispatch
File size: 4.5 KB
Line 
1=== Description
2
3uri-dispatch is a simple mechanism to dispatch uris to procedures.
4This is useful for webprogramming where you might want to map uris of a certain kind
5to procedures that implement the logic for those uris.
6
7=== Author
8
9[[David Krentzlin]]
10
11=== Requirements
12
13Requires the [[uri-common]] and [[environments]] extensions.
14
15=== Documentation
16
17<procedure>(dispatch-uri URI)</procedure>
18
19The main interface to dispatch-uri. This procedure invokes the dispatch-mechanism with the supplied uri.
20The dispatch-algorithm is implemented as follows:
21
22('''Note''' Although not explicitly stated here the algorithm performs a whitelist-check on any procedure before it is invoked. See '''enable-checks''' and '''whitelist!''')
23
24*  The path is empty. It checks if '''default-dispatch-target''' is non-false.
25   If it is, then it is invoked. If it is not '''dispatch-error''' is invoked.
26
27* The path has exactly one element. It assumes that this is this element is the name
28   of a thunk that was defined outside a module. If the such a thunk exists it is invoked.
29   If no such a thunk exists it invokes '''dispatch-error'''.
30
31* The path contains at least two elements.
32** It checks if the second element is a procedure defined
33  in a module named by the first element. So if it sees (foo bar) it tries to find the procedure foo
34  inside the module bar. If the procedure exists it is invoked with the rest of the elements as arguments.
35** If it does not exist, it interpretes the first element as the name of a procedure that was defined
36  outside any module. If such a procedure exists, it is invoked passing the rest of the elements as arguments.
37  If no such procedure exists '''dispatch-error''' is invoked with the full path as argument. The path is applied
38  to the procedure so you can use for example dsssl-style lambdalists to declare optional arguments or a rest-argument.
39
40
41<procedure>(whitelist! DEFINITION)</procedure>
42Though nice for development it is not advisable to allow anybody out there to invoke abritary procedures of your application.
43So you might want to '''enable-checks''' in production and whitelist only those modules and/or procedures you really want
44to be callable from the outside. Whitelisting can be done with this procedure. It expects a list that defines the procedure/modules
45you want to whitelist. You have basically three possibilities to perform whitelisting all of which can be combined.
46
471) whitelist procedures outside modules
48<pre>(whitelist! '(procedure1 procedure2 procedure3))</pre>
49
502) whitelist all procedures inside a module
51<pre>(whitelist! '((module my-module my-module2))</pre>
52
533) whitelist specific procedures inside a module
54<pre>(whitelist! '((module-name procedure1 procedure2)))</pre>
55
56As noted above you can mix those possibilities
57
58<pre>(whitelist! '(proc1 proc2 proc3 (module foo-mod bar-mod) (baz-module proc4 proc5)))</pre>
59
60It is planned to implement some keywords that allow easier use of this procedure.
61
62
63
64<parameter>dispatch-error</parameter>
65
66If no handler for a uri can be found, the dispatcher will invoke the procedure that dispatch-error is currently parameterized with.
67'''NOTE''' dispatch-error is also invoked if the requested handler exists but is not whitelisted.
68
69<parameter>enable-checks</parameter>
70
71<parameter>default-dispatch-target</parameter>
72
73<parameter>dispatch-environment</parameter>
74
75
76=== Examples
77<pre>
78
79(use spiffy intarweb uri-common uri-dispatch)
80
81(define (my-dispatch-error . path)
82  (send-status 404 (sprintf "My Dispatch-error ~A" path)))
83
84
85(module example
86  (echo webiota)
87  (import scheme chicken srfi-1 extras)
88  (require-library spiffy)
89  (import (only spiffy send-status))
90
91  (define (webiota #!optional (start "0") (steps "10") #!rest rest)
92    (send-status 200 (sprintf "webiota called: ~A" (iota (string->number steps) (string->number start)))))
93
94  (define (echo . args)
95    (send-status 200 (sprintf "echo: ~A" args))))
96
97(define (outsidemodule . args) (send-status 200 "Outside module"))
98
99(vhost-map `(("localhost" . ,(lambda (continue)
100                              (parameterize ((handle-not-found  (lambda (path) (dispatch-uri (request-uri (current-request)))))
101                                             (dispatch-error (lambda path (send-status 404 (sprintf "Path not found: ~A" path)))))
102                                (continue))))))
103(start-server)
104
105</pre>
106
107Now start the server and visit the following pages:
108* http://localhost:8080/example/webiota/2/10/
109* http://localhost:8080/example/webiota/2/20/
110* http://localhost:8080/example/webiota/echo/this/please
111* http://localhost:8080/outsidemodule
112* http://localhost:8080/i/do/not/exist
Note: See TracBrowser for help on using the repository browser.