Lots of documentation formatting.
Started as fixing misindented definitions, then more indentations, then a bunch of similar things (square brackets, huge spaces at end-of-lines, etc).
This commit is contained in:
parent
d3d9514b1c
commit
d61eb53686
|
@ -8,7 +8,8 @@
|
||||||
(require (for-label racket/serialize))
|
(require (for-label racket/serialize))
|
||||||
(define id (racket define-serializable-struct))
|
(define id (racket define-serializable-struct))
|
||||||
(define id2 (racket define-serializable-struct/versions))))
|
(define id2 (racket define-serializable-struct/versions))))
|
||||||
(bind racket-define-serializable-struct racket-define-serializable-struct/versions))
|
(bind racket-define-serializable-struct
|
||||||
|
racket-define-serializable-struct/versions))
|
||||||
|
|
||||||
@mzlib[#:mode title serialize]
|
@mzlib[#:mode title serialize]
|
||||||
|
|
||||||
|
|
|
@ -110,11 +110,11 @@ Raised for errors when handling cookies.}
|
||||||
@subsection{Creating a cookie}
|
@subsection{Creating a cookie}
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(let ((c (cookie:add-max-age
|
(let ([c (cookie:add-max-age
|
||||||
(cookie:add-path
|
(cookie:add-path
|
||||||
(set-cookie "foo" "bar")
|
(set-cookie "foo" "bar")
|
||||||
"/servlets")
|
"/servlets")
|
||||||
3600)))
|
3600)])
|
||||||
(print-cookie c))
|
(print-cookie c))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -199,8 +199,8 @@ the bounds of the image, returns a transparent color.}
|
||||||
[f (-> natural-number/c natural-number/c color?)])
|
[f (-> natural-number/c natural-number/c color?)])
|
||||||
image?]{
|
image?]{
|
||||||
|
|
||||||
Builds an image of the specified size and shape by calling the specified function
|
Builds an image of the specified size and shape by calling the specified
|
||||||
on the coordinates of each pixel. For example,
|
function on the coordinates of each pixel. For example,
|
||||||
@codeblock|{
|
@codeblock|{
|
||||||
; fuzz : image -> image
|
; fuzz : image -> image
|
||||||
(define (fuzz pic)
|
(define (fuzz pic)
|
||||||
|
|
|
@ -229,7 +229,6 @@ The @racket[pkg] argument must end with @racket[".plt"].
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(get-package-spec [owner string?]
|
@defproc[(get-package-spec [owner string?]
|
||||||
[pkg (and/c string? #rx"[.]plt$")]
|
[pkg (and/c string? #rx"[.]plt$")]
|
||||||
[maj (or/c #f natural-number/c) #f]
|
[maj (or/c #f natural-number/c) #f]
|
||||||
|
@ -284,7 +283,8 @@ See also @racket[build-scribble-docs?] and @racket[force-package-building?]
|
||||||
}
|
}
|
||||||
|
|
||||||
@defparam[force-package-building? b boolean?]{
|
@defparam[force-package-building? b boolean?]{
|
||||||
Determines if @racket[make-planet-archive] is more strict and thus aborts more often.
|
Determines if @racket[make-planet-archive] is more strict and thus
|
||||||
|
aborts more often.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(download-package [pkg-spec pkg-spec?])
|
@defproc[(download-package [pkg-spec pkg-spec?])
|
||||||
|
@ -418,7 +418,8 @@ produces a list corresponding to its name and version, exactly like
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(pkg? [v any/c]) boolean?]{
|
@defproc[(pkg? [v any/c]) boolean?]{
|
||||||
Determines if its argument is a pkg, the representation of an installed package.
|
Determines if its argument is a pkg, the representation of an
|
||||||
|
installed package.
|
||||||
}
|
}
|
||||||
|
|
||||||
@section[#:tag "version.rkt"]{Package Version}
|
@section[#:tag "version.rkt"]{Package Version}
|
||||||
|
|
|
@ -181,15 +181,15 @@ function, we could do the following:
|
||||||
#:segments [segments 20]
|
#:segments [segments 20]
|
||||||
#:color [color 'red]
|
#:color [color 'red]
|
||||||
#:width [width 1])
|
#:width [width 1])
|
||||||
(let* ((dash-size (/ (- x-max x-min) segments))
|
(let* ([dash-size (/ (- x-max x-min) segments)]
|
||||||
(x-lists (build-list
|
[x-lists (build-list
|
||||||
(/ segments 2)
|
(/ segments 2)
|
||||||
(lambda (index)
|
(lambda (index)
|
||||||
(x-values
|
(x-values
|
||||||
(/ samples segments)
|
(/ samples segments)
|
||||||
(+ x-min (* 2 index dash-size))
|
(+ x-min (* 2 index dash-size))
|
||||||
(+ x-min (* (add1 (* 2 index))
|
(+ x-min (* (add1 (* 2 index))
|
||||||
dash-size)))))))
|
dash-size)))))])
|
||||||
(lambda (2dview)
|
(lambda (2dview)
|
||||||
(send 2dview set-line-color color)
|
(send 2dview set-line-color color)
|
||||||
(send 2dview set-line-width width)
|
(send 2dview set-line-width width)
|
||||||
|
|
|
@ -399,7 +399,7 @@ Dispatching-related bindings:
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(define (ttref)
|
(define (ttref)
|
||||||
(let ((url (get-arg)) (text (get-arg)))
|
(let ([url (get-arg)] [text (get-arg)])
|
||||||
(list "<a href=\"" url "\">@tt{" text "}</a>")))
|
(list "<a href=\"" url "\">@tt{" text "}</a>")))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ cases. Here's a simple test case written using the
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(test-begin
|
(test-begin
|
||||||
(let ((lst (list 2 4 6 9)))
|
(let ([lst (list 2 4 6 9)])
|
||||||
(check = (length lst) 4)
|
(check = (length lst) 4)
|
||||||
(for-each
|
(for-each
|
||||||
(lambda (elt)
|
(lambda (elt)
|
||||||
|
@ -111,7 +111,7 @@ we're testing. We can give a test case a name with the
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(test-case
|
(test-case
|
||||||
"List has length 4 and all elements even"
|
"List has length 4 and all elements even"
|
||||||
(let ((lst (list 2 4 6 9)))
|
(let ([lst (list 2 4 6 9)])
|
||||||
(check = (length lst) 4)
|
(check = (length lst) 4)
|
||||||
(for-each
|
(for-each
|
||||||
(lambda (elt)
|
(lambda (elt)
|
||||||
|
@ -133,7 +133,7 @@ group them into a test suite:
|
||||||
|
|
||||||
(test-case
|
(test-case
|
||||||
"List has length 4 and all elements even"
|
"List has length 4 and all elements even"
|
||||||
(let ((lst (list 2 4 6 9)))
|
(let ([lst (list 2 4 6 9)])
|
||||||
(check = (length lst) 4)
|
(check = (length lst) 4)
|
||||||
(for-each
|
(for-each
|
||||||
(lambda (elt)
|
(lambda (elt)
|
||||||
|
|
|
@ -62,7 +62,7 @@ racket
|
||||||
(r (f lov)
|
(r (f lov)
|
||||||
(lambda (r)
|
(lambda (r)
|
||||||
(define f@r (f r))
|
(define f@r (f r))
|
||||||
(for/and ((v lov)) (>= f@r (f v))))))])
|
(for/and ([v lov]) (>= f@r (f v))))))])
|
||||||
]
|
]
|
||||||
It is a @emph{dependent} contract that names the two arguments and uses
|
It is a @emph{dependent} contract that names the two arguments and uses
|
||||||
the names to impose a predicate on the result. This predicate computes
|
the names to impose a predicate on the result. This predicate computes
|
||||||
|
@ -84,9 +84,8 @@ racket
|
||||||
(r (f lov)
|
(r (f lov)
|
||||||
(lambda (r)
|
(lambda (r)
|
||||||
(define f@r (f r))
|
(define f@r (f r))
|
||||||
(and
|
(and (memq r lov)
|
||||||
(memq r lov)
|
(for/and ([v lov]) (>= f@r (f v)))))))])
|
||||||
(for/and ((v lov)) (>= f@r (f v)))))))])
|
|
||||||
]
|
]
|
||||||
The @racket[memq] function ensures that @racket[r] is @emph{intensionally equal}
|
The @racket[memq] function ensures that @racket[r] is @emph{intensionally equal}
|
||||||
@margin-note*{That is, "pointer equality" for those who prefer to think at
|
@margin-note*{That is, "pointer equality" for those who prefer to think at
|
||||||
|
@ -113,7 +112,7 @@ racket
|
||||||
(r (f lov)
|
(r (f lov)
|
||||||
(lambda (r)
|
(lambda (r)
|
||||||
(define f@r (f r))
|
(define f@r (f r))
|
||||||
(and (for/and ((v lov)) (>= f@r (f v)))
|
(and (for/and ([v lov]) (>= f@r (f v)))
|
||||||
(eq? (first (memf (lambda (v) (= (f v) f@r)) lov))
|
(eq? (first (memf (lambda (v) (= (f v) f@r)) lov))
|
||||||
r)))))])
|
r)))))])
|
||||||
]
|
]
|
||||||
|
@ -157,7 +156,7 @@ racket
|
||||||
|
|
||||||
@code:comment{@#,dominates1}
|
@code:comment{@#,dominates1}
|
||||||
(define (dominates-all f@r f lov)
|
(define (dominates-all f@r f lov)
|
||||||
(for/and ((v lov)) (>= (f v) f@r)))
|
(for/and ([v lov]) (>= (f v) f@r)))
|
||||||
|
|
||||||
@code:comment{@#,first?1}
|
@code:comment{@#,first?1}
|
||||||
(define (is-first-max? r f@r f lov)
|
(define (is-first-max? r f@r f lov)
|
||||||
|
@ -199,7 +198,7 @@ racket
|
||||||
|
|
||||||
@code:comment{@#,dominates2}
|
@code:comment{@#,dominates2}
|
||||||
(define (dominates-all f@r flov)
|
(define (dominates-all f@r flov)
|
||||||
(for/and ((f@v flov)) (>= f@r f@v)))
|
(for/and ([f@v flov]) (>= f@r f@v)))
|
||||||
|
|
||||||
@code:comment{@#,first?2}
|
@code:comment{@#,first?2}
|
||||||
(define (is-first-max? r f@r lov+flov)
|
(define (is-first-max? r f@r lov+flov)
|
||||||
|
|
|
@ -82,8 +82,7 @@ streams like this:
|
||||||
#:eval e
|
#:eval e
|
||||||
(define stream/c
|
(define stream/c
|
||||||
(promise/c
|
(promise/c
|
||||||
(or/c
|
(or/c null?
|
||||||
null?
|
|
||||||
(cons/c number? stream/c))))
|
(cons/c number? stream/c))))
|
||||||
]
|
]
|
||||||
@close-eval[e]
|
@close-eval[e]
|
||||||
|
@ -99,8 +98,7 @@ Instead, use
|
||||||
(promise/c
|
(promise/c
|
||||||
(or/c
|
(or/c
|
||||||
null?
|
null?
|
||||||
(cons/c 1
|
(cons/c 1 (recursive-contract stream/c)))))
|
||||||
(recursive-contract stream/c)))))
|
|
||||||
]
|
]
|
||||||
|
|
||||||
The use of @racket[recursive-contract] delays the evaluation of the
|
The use of @racket[recursive-contract] delays the evaluation of the
|
||||||
|
|
|
@ -261,7 +261,7 @@ resulting iteration can be performed more efficiently than plain
|
||||||
@racket[for/vector] or @racket[for*/vector]:
|
@racket[for/vector] or @racket[for*/vector]:
|
||||||
|
|
||||||
@interaction[
|
@interaction[
|
||||||
(let ((chapters '("Intro" "Details" "Conclusion")))
|
(let ([chapters '("Intro" "Details" "Conclusion")])
|
||||||
(for/vector #:length (length chapters) ([i (in-naturals 1)]
|
(for/vector #:length (length chapters) ([i (in-naturals 1)]
|
||||||
[chapter chapters])
|
[chapter chapters])
|
||||||
(string-append (number->string i) ". " chapter)))
|
(string-append (number->string i) ". " chapter)))
|
||||||
|
|
|
@ -64,18 +64,18 @@ Consider the following core of a Mandelbrot-set computation:
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(define (mandelbrot iterations x y n)
|
(define (mandelbrot iterations x y n)
|
||||||
(let ((ci (- (/ (* 2.0 y) n) 1.0))
|
(let ([ci (- (/ (* 2.0 y) n) 1.0)]
|
||||||
(cr (- (/ (* 2.0 x) n) 1.5)))
|
[cr (- (/ (* 2.0 x) n) 1.5)])
|
||||||
(let loop ((i 0) (zr 0.0) (zi 0.0))
|
(let loop ([i 0] [zr 0.0] [zi 0.0])
|
||||||
(if (> i iterations)
|
(if (> i iterations)
|
||||||
i
|
i
|
||||||
(let ((zrq (* zr zr))
|
(let ([zrq (* zr zr)]
|
||||||
(ziq (* zi zi)))
|
[ziq (* zi zi)])
|
||||||
(cond
|
(cond
|
||||||
((> (+ zrq ziq) 4.0) i)
|
[(> (+ zrq ziq) 4.0) i]
|
||||||
(else (loop (add1 i)
|
[else (loop (add1 i)
|
||||||
(+ (- zrq ziq) cr)
|
(+ (- zrq ziq) cr)
|
||||||
(+ (* 2.0 zr zi) ci)))))))))
|
(+ (* 2.0 zr zi) ci))]))))))
|
||||||
]
|
]
|
||||||
|
|
||||||
The expressions @racket[(mandelbrot 10000000 62 500 1000)] and
|
The expressions @racket[(mandelbrot 10000000 62 500 1000)] and
|
||||||
|
@ -110,8 +110,8 @@ first the problem:
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(define (mandelbrot iterations x y n)
|
(define (mandelbrot iterations x y n)
|
||||||
(let ((ci (- (/ (* 2.0 (->fl y)) (->fl n)) 1.0))
|
(let ([ci (- (/ (* 2.0 (->fl y)) (->fl n)) 1.0)]
|
||||||
(cr (- (/ (* 2.0 (->fl x)) (->fl n)) 1.5)))
|
[cr (- (/ (* 2.0 (->fl x)) (->fl n)) 1.5)])
|
||||||
....))
|
....))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -128,18 +128,18 @@ much less allocation:
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(define (mandelbrot iterations x y n)
|
(define (mandelbrot iterations x y n)
|
||||||
(let ((ci (fl- (fl/ (* 2.0 (->fl y)) (->fl n)) 1.0))
|
(let ([ci (fl- (fl/ (* 2.0 (->fl y)) (->fl n)) 1.0)]
|
||||||
(cr (fl- (fl/ (* 2.0 (->fl x)) (->fl n)) 1.5)))
|
[cr (fl- (fl/ (* 2.0 (->fl x)) (->fl n)) 1.5)])
|
||||||
(let loop ((i 0) (zr 0.0) (zi 0.0))
|
(let loop ([i 0] [zr 0.0] [zi 0.0])
|
||||||
(if (> i iterations)
|
(if (> i iterations)
|
||||||
i
|
i
|
||||||
(let ((zrq (fl* zr zr))
|
(let ([zrq (fl* zr zr)]
|
||||||
(ziq (fl* zi zi)))
|
[ziq (fl* zi zi)])
|
||||||
(cond
|
(cond
|
||||||
((fl> (fl+ zrq ziq) 4.0) i)
|
[(fl> (fl+ zrq ziq) 4.0) i]
|
||||||
(else (loop (add1 i)
|
[else (loop (add1 i)
|
||||||
(fl+ (fl- zrq ziq) cr)
|
(fl+ (fl- zrq ziq) cr)
|
||||||
(fl+ (fl* 2.0 (fl* zr zi)) ci)))))))))
|
(fl+ (fl* 2.0 (fl* zr zi)) ci))]))))))
|
||||||
]
|
]
|
||||||
|
|
||||||
This conversion can speed @racket[mandelbrot] by a factor of 8, even
|
This conversion can speed @racket[mandelbrot] by a factor of 8, even
|
||||||
|
|
|
@ -280,7 +280,8 @@ For communication among @tech{places}, the new byte string is allocated in the
|
||||||
the other operations.
|
the other operations.
|
||||||
@examples[
|
@examples[
|
||||||
(define b
|
(define b
|
||||||
(bytes->string/utf-8 (bytes #xc3 #xa7 #xc3 #xb0 #xc3 #xb6 #xc2 #xa3)))
|
(bytes->string/utf-8
|
||||||
|
(bytes #xc3 #xa7 #xc3 #xb0 #xc3 #xb6 #xc2 #xa3)))
|
||||||
|
|
||||||
(string->bytes/utf-8 b)
|
(string->bytes/utf-8 b)
|
||||||
(bytes->string/utf-8 (string->bytes/utf-8 b))
|
(bytes->string/utf-8 (string->bytes/utf-8 b))
|
||||||
|
|
|
@ -292,13 +292,13 @@ interface @racket[(class->interface object%)], and is transparent
|
||||||
(lambda kw-formals expr ...+)
|
(lambda kw-formals expr ...+)
|
||||||
(case-lambda (formals expr ...+) ...)
|
(case-lambda (formals expr ...+) ...)
|
||||||
(#%plain-lambda formals expr ...+)
|
(#%plain-lambda formals expr ...+)
|
||||||
(let-values (((id) method-procedure) ...)
|
(let-values ([(id) method-procedure] ...)
|
||||||
method-procedure)
|
method-procedure)
|
||||||
(letrec-values (((id) method-procedure) ...)
|
(letrec-values ([(id) method-procedure] ...)
|
||||||
method-procedure)
|
method-procedure)
|
||||||
(let-values (((id) method-procedure) ...+)
|
(let-values ([(id) method-procedure] ...+)
|
||||||
id)
|
id)
|
||||||
(letrec-values (((id) method-procedure) ...+)
|
(letrec-values ([(id) method-procedure] ...+)
|
||||||
id)])]{
|
id)])]{
|
||||||
|
|
||||||
Produces a class value.
|
Produces a class value.
|
||||||
|
|
|
@ -196,4 +196,3 @@ For communication among @tech{places}, the new @tech{fxvector} is
|
||||||
allocated in the @tech{shared memory space}.
|
allocated in the @tech{shared memory space}.
|
||||||
|
|
||||||
@mz-examples[#:eval flfx-eval (make-shared-fxvector 4 3)]}
|
@mz-examples[#:eval flfx-eval (make-shared-fxvector 4 3)]}
|
||||||
|
|
||||||
|
|
|
@ -481,7 +481,8 @@ instead of @racket[match].}
|
||||||
type named @racket[struct-id], where the field @racket[field] in the
|
type named @racket[struct-id], where the field @racket[field] in the
|
||||||
instance matches the corresponding @racket[pat].
|
instance matches the corresponding @racket[pat].
|
||||||
|
|
||||||
Any field of @racket[struct-id] may be omitted, and such fields can occur in any order.
|
Any field of @racket[struct-id] may be omitted, and such fields can
|
||||||
|
occur in any order.
|
||||||
|
|
||||||
@defexamples[
|
@defexamples[
|
||||||
#:eval match-eval
|
#:eval match-eval
|
||||||
|
|
|
@ -44,7 +44,7 @@ new parameter value. A guard procedure can raise an exception to
|
||||||
reject a change to the parameter's value. The @racket[guard] is not
|
reject a change to the parameter's value. The @racket[guard] is not
|
||||||
applied to the initial @racket[v].}
|
applied to the initial @racket[v].}
|
||||||
|
|
||||||
@defform[(parameterize ((parameter-expr value-expr) ...)
|
@defform[(parameterize ([parameter-expr value-expr] ...)
|
||||||
body ...+)
|
body ...+)
|
||||||
#:contracts
|
#:contracts
|
||||||
([parameter-expr parameter?])]{
|
([parameter-expr parameter?])]{
|
||||||
|
|
|
@ -24,7 +24,7 @@ used as a macro that expands to a use of the target identifier, but
|
||||||
@racket[syntax-local-value] of @racket[id] does not produce
|
@racket[syntax-local-value] of @racket[id] does not produce
|
||||||
the target's value.}
|
the target's value.}
|
||||||
|
|
||||||
@defform[(syntax-parameterize ((id expr) ...) body-expr ...+)]{
|
@defform[(syntax-parameterize ([id expr] ...) body-expr ...+)]{
|
||||||
|
|
||||||
@margin-note/ref{See also @racket[splicing-syntax-parameterize].}
|
@margin-note/ref{See also @racket[splicing-syntax-parameterize].}
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ For example, the expression
|
||||||
expands to
|
expands to
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(let ((or-part x)) (if or-part or-part (or y)))
|
(let ([or-part x]) (if or-part or-part (or y)))
|
||||||
]
|
]
|
||||||
|
|
||||||
which, in turn, expands to
|
which, in turn, expands to
|
||||||
|
|
|
@ -210,9 +210,9 @@ the binding (according to @racket[free-identifier=?]) matters.}
|
||||||
(if expr expr expr)
|
(if expr expr expr)
|
||||||
(begin expr ...+)
|
(begin expr ...+)
|
||||||
(begin0 expr expr ...)
|
(begin0 expr expr ...)
|
||||||
(let-values (((id ...) expr) ...)
|
(let-values ([(id ...) expr] ...)
|
||||||
expr ...+)
|
expr ...+)
|
||||||
(letrec-values (((id ...) expr) ...)
|
(letrec-values ([(id ...) expr] ...)
|
||||||
expr ...+)
|
expr ...+)
|
||||||
(set! id expr)
|
(set! id expr)
|
||||||
(@#,racket[quote] datum)
|
(@#,racket[quote] datum)
|
||||||
|
|
|
@ -109,7 +109,7 @@ is prefixed with the special form name as described under
|
||||||
|
|
||||||
@examples[#:eval the-eval
|
@examples[#:eval the-eval
|
||||||
(wrong-syntax #'here "expected ~s" 'there)
|
(wrong-syntax #'here "expected ~s" 'there)
|
||||||
(parameterize ((current-syntax-context #'(look over here)))
|
(parameterize ([current-syntax-context #'(look over here)])
|
||||||
(wrong-syntax #'here "expected ~s" 'there))
|
(wrong-syntax #'here "expected ~s" 'there))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ A macro using @racket[wrong-syntax] might set the syntax context at the very
|
||||||
beginning of its transformation as follows:
|
beginning of its transformation as follows:
|
||||||
@RACKETBLOCK[
|
@RACKETBLOCK[
|
||||||
(define-syntax (my-macro stx)
|
(define-syntax (my-macro stx)
|
||||||
(parameterize ((current-syntax-context stx))
|
(parameterize ([current-syntax-context stx])
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
___)))
|
___)))
|
||||||
]
|
]
|
||||||
|
|
|
@ -117,8 +117,8 @@ form.}
|
||||||
(->d (arg ...) () #:rest id rest [id result])])]{
|
(->d (arg ...) () #:rest id rest [id result])])]{
|
||||||
|
|
||||||
Like @racket[proc-doc], but supporting contract forms that embed
|
Like @racket[proc-doc], but supporting contract forms that embed
|
||||||
argument names. Only a subset of @racket[->i] and @racket[->d] forms are currently
|
argument names. Only a subset of @racket[->i] and @racket[->d] forms are
|
||||||
supported.}
|
currently supported.}
|
||||||
|
|
||||||
@defform[(thing-doc id contract-expr dec-expr)]{
|
@defform[(thing-doc id contract-expr dec-expr)]{
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,6 @@ Transfers cross-reference information to @racket[ci], which is the
|
||||||
initially collected information from @racket[renderer].}
|
initially collected information from @racket[renderer].}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@defproc[(xref-index [xref xref?]) (listof entry?)]{
|
@defproc[(xref-index [xref xref?]) (listof entry?)]{
|
||||||
|
|
||||||
Converts indexing information @racket[xref] into a list of
|
Converts indexing information @racket[xref] into a list of
|
||||||
|
|
|
@ -83,12 +83,12 @@ language [*]:
|
||||||
"#<procedure:closure-storing-proc>"
|
"#<procedure:closure-storing-proc>"
|
||||||
(#%plain-lambda (x)
|
(#%plain-lambda (x)
|
||||||
(begin
|
(begin
|
||||||
(let-values (((arg0-1643 arg1-1644 arg2-1645)
|
(let-values ([(arg0-1643 arg1-1644 arg2-1645)
|
||||||
(#%plain-app
|
(#%plain-app
|
||||||
values
|
values
|
||||||
"#<*unevaluated-struct*>"
|
"#<*unevaluated-struct*>"
|
||||||
"#<*unevaluated-struct*>"
|
"#<*unevaluated-struct*>"
|
||||||
"#<*unevaluated-struct*>")))
|
"#<*unevaluated-struct*>")])
|
||||||
(with-continuation-mark "#<debug-key-struct>"
|
(with-continuation-mark "#<debug-key-struct>"
|
||||||
(#%plain-lambda ()
|
(#%plain-lambda ()
|
||||||
(#%plain-app
|
(#%plain-app
|
||||||
|
@ -161,7 +161,7 @@ language [*]:
|
||||||
#f
|
#f
|
||||||
(#%plain-lambda () (#%plain-app list f))))))))
|
(#%plain-lambda () (#%plain-app list f))))))))
|
||||||
|
|
||||||
(let-values (((done-already?) (quote #f)))
|
(let-values ([(done-already?) (quote #f)])
|
||||||
(#%app dynamic-wind void
|
(#%app dynamic-wind void
|
||||||
(lambda () (#%app dynamic-require (quote (quote #%htdp)) (quote #f)))
|
(lambda () (#%app dynamic-require (quote (quote #%htdp)) (quote #f)))
|
||||||
(lambda () (if done-already?
|
(lambda () (if done-already?
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
|
|
||||||
@(begin
|
@(begin
|
||||||
(define the-eval
|
(define the-eval
|
||||||
(parameterize ((sandbox-output 'string)
|
(parameterize ([sandbox-output 'string]
|
||||||
(sandbox-error-output 'string))
|
[sandbox-error-output 'string])
|
||||||
(make-evaluator 'racket/base #:requires '(syntax/keyword))))
|
(make-evaluator 'racket/base #:requires '(syntax/keyword))))
|
||||||
;;(void (the-eval '(error-print-source-location #f)))
|
;;(void (the-eval '(error-print-source-location #f)))
|
||||||
(define-syntax-rule (myexamples e ...)
|
(define-syntax-rule (myexamples e ...)
|
||||||
|
|
|
@ -23,11 +23,11 @@ the parameter expressions.
|
||||||
[(_ ((p v:expr) ...) body:expr)
|
[(_ ((p v:expr) ...) body:expr)
|
||||||
#:declare p (expr/c #'parameter?
|
#:declare p (expr/c #'parameter?
|
||||||
#:name "parameter argument")
|
#:name "parameter argument")
|
||||||
#'(parameterize ((p.c v) ...) body)]))
|
#'(parameterize ([p.c v] ...) body)]))
|
||||||
(myparameterize ((current-input-port
|
(myparameterize ([current-input-port
|
||||||
(open-input-string "(1 2 3)")))
|
(open-input-string "(1 2 3)")])
|
||||||
(read))
|
(read))
|
||||||
(myparameterize (('whoops 'something))
|
(myparameterize (['whoops 'something])
|
||||||
'whatever)
|
'whatever)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -425,7 +425,6 @@ They all construct a triangle oriented as follows:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@defproc*[([(square [side-len (and/c real? (not/c negative?))]
|
@defproc*[([(square [side-len (and/c real? (not/c negative?))]
|
||||||
[mode mode?]
|
[mode mode?]
|
||||||
[color image-color?])
|
[color image-color?])
|
||||||
|
@ -657,7 +656,6 @@ the @racket[point-count] argument determines how many points the star has.
|
||||||
(rectangle 40 40 "solid" "silver")
|
(rectangle 40 40 "solid" "silver")
|
||||||
(rectangle 50 50 "solid" "seagreen"))]
|
(rectangle 50 50 "solid" "seagreen"))]
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(overlay/offset [i1 image?] [x real?] [y real?] [i2 image?]) image?]{
|
@defproc[(overlay/offset [i1 image?] [x real?] [y real?] [i2 image?]) image?]{
|
||||||
|
@ -777,7 +775,6 @@ the @racket[point-count] argument determines how many points the star has.
|
||||||
(rectangle 30 30 50 "seagreen")
|
(rectangle 30 30 50 "seagreen")
|
||||||
(rectangle 20 20 50 "seagreen"))]
|
(rectangle 20 20 50 "seagreen"))]
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -869,7 +866,6 @@ the @racket[point-count] argument determines how many points the star has.
|
||||||
(ellipse 20 30 "solid" "dimgray")
|
(ellipse 20 30 "solid" "dimgray")
|
||||||
(ellipse 20 10 "solid" "black"))]
|
(ellipse 20 10 "solid" "black"))]
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(beside/align [y-place y-place?] [i1 image?] [i2 image?] [is image?] ...) image?]{
|
@defproc[(beside/align [y-place y-place?] [i1 image?] [i2 image?] [is image?] ...) image?]{
|
||||||
|
@ -894,7 +890,6 @@ the @racket[point-count] argument determines how many points the star has.
|
||||||
(text "ijy" 18 "black")
|
(text "ijy" 18 "black")
|
||||||
(text "ijy" 24 "black"))]
|
(text "ijy" 24 "black"))]
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -907,7 +902,6 @@ the @racket[point-count] argument determines how many points the star has.
|
||||||
(ellipse 30 20 "solid" "dimgray")
|
(ellipse 30 20 "solid" "dimgray")
|
||||||
(ellipse 10 20 "solid" "black"))]
|
(ellipse 10 20 "solid" "black"))]
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(above/align [x-place x-place?] [i1 image?] [i2 image?] [is image?] ...) image?]{
|
@defproc[(above/align [x-place x-place?] [i1 image?] [i2 image?] [is image?] ...) image?]{
|
||||||
|
@ -928,7 +922,6 @@ the @racket[point-count] argument determines how many points the star has.
|
||||||
(ellipse 30 20 "solid" "darkolivegreen")
|
(ellipse 30 20 "solid" "darkolivegreen")
|
||||||
(ellipse 10 20 "solid" "darkgreen"))]
|
(ellipse 10 20 "solid" "darkgreen"))]
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@section{Placing Images & Scenes}
|
@section{Placing Images & Scenes}
|
||||||
|
@ -1201,9 +1194,10 @@ more expensive than with the other shapes.
|
||||||
([bitmap-spec rel-string
|
([bitmap-spec rel-string
|
||||||
id])]{
|
id])]{
|
||||||
|
|
||||||
Loads the bitmap specified by @racket[bitmap-spec]. If @racket[bitmap-spec] is a string, it is treated as a
|
Loads the bitmap specified by @racket[bitmap-spec]. If
|
||||||
relative path. If it is an identifier, it is treated like a require spec and used to refer to a file
|
@racket[bitmap-spec] is a string, it is treated as a relative path.
|
||||||
in a collection.
|
If it is an identifier, it is treated like a require spec and used to
|
||||||
|
refer to a file in a collection.
|
||||||
|
|
||||||
@image-examples[(bitmap icons/stop-16x16.png)
|
@image-examples[(bitmap icons/stop-16x16.png)
|
||||||
(bitmap icons/b-run.png)]
|
(bitmap icons/b-run.png)]
|
||||||
|
|
|
@ -34,8 +34,7 @@ Example:
|
||||||
(view dir)
|
(view dir)
|
||||||
(printf "~a ~n" (control)))))
|
(printf "~a ~n" (control)))))
|
||||||
|
|
||||||
(connect
|
(connect (make-model "left")
|
||||||
(make-model "left")
|
|
||||||
(make-model "right")
|
(make-model "right")
|
||||||
(make-model "up")
|
(make-model "up")
|
||||||
(make-model "down"))
|
(make-model "down"))
|
||||||
|
|
|
@ -34,15 +34,20 @@ This module provides a macro for regular expression compilation.
|
||||||
pat])]{
|
pat])]{
|
||||||
Compiles a regular expression over match patterns to a @racket[machine].
|
Compiles a regular expression over match patterns to a @racket[machine].
|
||||||
|
|
||||||
The interpretation of the pattern language is mostly intuitive. The pattern language may be extended
|
The interpretation of the pattern language is mostly intuitive. The
|
||||||
with @racket[define-re-transformer]. @racket[dseq] allows bindings of the @racket[match] pattern to be
|
pattern language may be extended with @racket[define-re-transformer].
|
||||||
used in the rest of the regular expression. (Thus, they are not @emph{really} regular expressions.)
|
@racket[dseq] allows bindings of the @racket[match] pattern to be used
|
||||||
@racket[unquote] escapes to Racket to evaluate an expression that evaluates to a regular expression (this happens
|
in the rest of the regular expression. (Thus, they are not
|
||||||
once, at compile time.) @racket[rec] binds a Racket identifier to a delayed version of the inner expression; even
|
@emph{really} regular expressions.) @racket[unquote] escapes to Racket
|
||||||
if the expression is initially accepting, this delayed version is never accepting.
|
to evaluate an expression that evaluates to a regular expression (this
|
||||||
|
happens once, at compile time.) @racket[rec] binds a Racket identifier
|
||||||
|
to a delayed version of the inner expression; even if the expression is
|
||||||
|
initially accepting, this delayed version is never accepting.
|
||||||
|
|
||||||
The compiler will use an NFA, provided @racket[complement] and @racket[dseq] are not used. Otherwise,
|
The compiler will use an NFA, provided @racket[complement] and
|
||||||
many NFAs connected with the machine simulation functions from @racketmodname[unstable/automata/machine] are used.
|
@racket[dseq] are not used. Otherwise, many NFAs connected with the
|
||||||
|
machine simulation functions from
|
||||||
|
@racketmodname[unstable/automata/machine] are used.
|
||||||
}
|
}
|
||||||
|
|
||||||
@(define-syntax-rule (defidforms (id ...) . dat)
|
@(define-syntax-rule (defidforms (id ...) . dat)
|
||||||
|
|
|
@ -24,18 +24,26 @@
|
||||||
[name? identifier?]
|
[name? identifier?]
|
||||||
[method identifier?])]{
|
[method identifier?])]{
|
||||||
|
|
||||||
Defines @racket[name] as a transformer binding for the static information about a new generic group.
|
Defines @racket[name] as a transformer binding for the static
|
||||||
|
information about a new generic group.
|
||||||
|
|
||||||
Defines @racket[prop:name] as a structure
|
Defines @racket[prop:name] as a structure type property. Structure
|
||||||
type property. Structure types implementing this generic group should have this property where the value is a vector
|
types implementing this generic group should have this property where
|
||||||
with one element per @racket[method] where each value is
|
the value is a vector with one element per @racket[method] where each
|
||||||
either @racket[#f] or a procedure with the same arity as specified by @racket[kw-formals*].
|
value is either @racket[#f] or a procedure with the same arity as
|
||||||
(@racket[kw-formals*] is similar to the @racket[kw-formals] used by @racket[lambda], except no expression is given for optional arguments.)
|
specified by @racket[kw-formals*]. (@racket[kw-formals*] is similar to
|
||||||
The arity of each method is checked by the guard on the structure type property.
|
the @racket[kw-formals] used by @racket[lambda], except no expression is
|
||||||
|
given for optional arguments.) The arity of each method is checked by
|
||||||
|
the guard on the structure type property.
|
||||||
|
|
||||||
Defines @racket[name?] as a predicate identifying instances of structure types that implement this generic group.
|
Defines @racket[name?] as a predicate identifying instances of structure
|
||||||
|
types that implement this generic group.
|
||||||
|
|
||||||
Defines each @racket[method] as a generic procedure that calls the corresponding method on values where @racket[name?] is true. Each method must have a required by-position argument that is @racket[free-identifier=?] to @racket[name]. This argument is used in the generic definition to locate the specialization.
|
Defines each @racket[method] as a generic procedure that calls the
|
||||||
|
corresponding method on values where @racket[name?] is true. Each method
|
||||||
|
must have a required by-position argument that is
|
||||||
|
@racket[free-identifier=?] to @racket[name]. This argument is used in
|
||||||
|
the generic definition to locate the specialization.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,13 +69,18 @@ context of @racket[name].
|
||||||
#:contracts
|
#:contracts
|
||||||
([name identifier?])]{
|
([name identifier?])]{
|
||||||
|
|
||||||
@racket[name] must be a transformer binding for the static information about a new generic group.
|
@racket[name] must be a transformer binding for the static information
|
||||||
|
about a new generic group.
|
||||||
|
|
||||||
Expands to a value usable as the property value for the structure type property of the @racket[name] generic group.
|
Expands to a value usable as the property value for the structure type
|
||||||
|
property of the @racket[name] generic group.
|
||||||
|
|
||||||
If the @racket[definition]s define the methods of @racket[name], then they are used in the property value.
|
If the @racket[definition]s define the methods of @racket[name], then
|
||||||
|
they are used in the property value.
|
||||||
|
|
||||||
If any method of @racket[name] is not defined, then @racket[#f] is used to signify that the structure type does not implement the particular method.
|
If any method of @racket[name] is not defined, then @racket[#f] is used
|
||||||
|
to signify that the structure type does not implement the particular
|
||||||
|
method.
|
||||||
|
|
||||||
Allows @racket[define/generic] to appear in @racket[definition ...].
|
Allows @racket[define/generic] to appear in @racket[definition ...].
|
||||||
|
|
||||||
|
@ -78,7 +91,9 @@ Allows @racket[define/generic] to appear in @racket[definition ...].
|
||||||
([local-name identifier?]
|
([local-name identifier?]
|
||||||
[method-name identifier?])]{
|
[method-name identifier?])]{
|
||||||
|
|
||||||
When used inside @racket[define-methods], binds @racket[local-name] to the generic for @racket[method-name]. This is useful for method specializations to use the generic methods on other values.
|
When used inside @racket[define-methods], binds @racket[local-name] to
|
||||||
|
the generic for @racket[method-name]. This is useful for method
|
||||||
|
specializations to use the generic methods on other values.
|
||||||
|
|
||||||
Syntactically an error when used outside @racket[define-methods].
|
Syntactically an error when used outside @racket[define-methods].
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,18 @@ This library provides a simplified version of parameters that are backed by cont
|
||||||
[none-v [any/c #f]]
|
[none-v [any/c #f]]
|
||||||
[tag continuation-prompt-tag? default-continuation-prompt-tag])
|
[tag continuation-prompt-tag? default-continuation-prompt-tag])
|
||||||
(listof vector?)]{
|
(listof vector?)]{
|
||||||
Returns the values of the @racket[mps] up to @racket[tag]. The length of each vector in the result list is the same as the length of @racket[mps], and a value in a particular vector position is the value for the corresponding mark parameter in @racket[mps]. Values for multiple mark parameter appear in a single vector only when the mark parameters are for the same continuation frame in the current continuation. The @racket[none-v] argument is used for vector elements to indicate the lack of a value.
|
Returns the values of the @racket[mps] up to @racket[tag]. The length
|
||||||
}
|
of each vector in the result list is the same as the length of
|
||||||
|
@racket[mps], and a value in a particular vector position is the value
|
||||||
|
for the corresponding mark parameter in @racket[mps]. Values for
|
||||||
|
multiple mark parameter appear in a single vector only when the mark
|
||||||
|
parameters are for the same continuation frame in the current
|
||||||
|
continuation. The @racket[none-v] argument is used for vector elements
|
||||||
|
to indicate the lack of a value.
|
||||||
|
}
|
||||||
|
|
||||||
@defform[(mark-parameterize ([mp expr] ...) body-expr ...)]{
|
@defform[(mark-parameterize ([mp expr] ...) body-expr ...)]{
|
||||||
Parameterizes @racket[(begin body-expr ...)] by associating each @racket[mp] with the evaluation of @racket[expr] in the parameterization of the entire expression.
|
Parameterizes @racket[(begin body-expr ...)] by associating each
|
||||||
}
|
@racket[mp] with the evaluation of @racket[expr] in the
|
||||||
|
parameterization of the entire expression.
|
||||||
|
}
|
||||||
|
|
|
@ -40,16 +40,16 @@ The other arguments have the same meaning as for @racket[expr/c].
|
||||||
@examples[#:eval the-eval
|
@examples[#:eval the-eval
|
||||||
(define-syntax (myparameterize1 stx)
|
(define-syntax (myparameterize1 stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_ ((p v)) body)
|
[(_ ([p v]) body)
|
||||||
(with-syntax ([cp (wrap-expr/c
|
(with-syntax ([cp (wrap-expr/c
|
||||||
#'parameter? #'p
|
#'parameter? #'p
|
||||||
#:name "the parameter argument"
|
#:name "the parameter argument"
|
||||||
#:context stx)])
|
#:context stx)])
|
||||||
#'(parameterize ((cp v)) body))]))
|
#'(parameterize ([cp v]) body))]))
|
||||||
(myparameterize1 ((current-input-port
|
(myparameterize1 ([current-input-port
|
||||||
(open-input-string "(1 2 3)")))
|
(open-input-string "(1 2 3)")])
|
||||||
(read))
|
(read))
|
||||||
(myparameterize1 (('whoops 'something))
|
(myparameterize1 (['whoops 'something])
|
||||||
'whatever)
|
'whatever)
|
||||||
|
|
||||||
(module mod racket
|
(module mod racket
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
web-server/lang/serial-lambda
|
web-server/lang/serial-lambda
|
||||||
web-server/private/define-closure))
|
web-server/private/define-closure))
|
||||||
|
|
||||||
|
The defunctionalization process of the Web Language (see
|
||||||
The defunctionalization process of the Web Language (see @secref["stateless" #:doc '(lib "web-server/scribblings/web-server.scrbl")])
|
@secref["stateless" #:doc '(lib "web-server/scribblings/web-server.scrbl")])
|
||||||
requires an explicit representation of closures that is serializable.
|
requires an explicit representation of closures that is serializable.
|
||||||
|
|
||||||
@defmodule[web-server/lang/serial-lambda]{
|
@defmodule[web-server/lang/serial-lambda]{
|
||||||
|
@ -18,7 +18,8 @@ requires an explicit representation of closures that is serializable.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defform[(serial-case-lambda [formals body ...] ...)]{
|
@defform[(serial-case-lambda [formals body ...] ...)]{
|
||||||
Returns @racket[(case-lambda [formals body ...] ...)], except it is serializable.
|
Returns @racket[(case-lambda [formals body ...] ...)], except it is
|
||||||
|
serializable.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,10 @@
|
||||||
[path->serlvet path->servlet/c])
|
[path->serlvet path->servlet/c])
|
||||||
(values (-> void)
|
(values (-> void)
|
||||||
url->servlet/c)]{
|
url->servlet/c)]{
|
||||||
The first return value flushes the cache.
|
The first return value flushes the cache. The second is a procedure
|
||||||
The second is a procedure that uses @racket[url->path] to resolve the URL to a path, then uses @racket[path->servlet] to resolve
|
that uses @racket[url->path] to resolve the URL to a path, then uses
|
||||||
that path to a servlet, caching the results in an internal table.
|
@racket[path->servlet] to resolve that path to a servlet, caching the
|
||||||
|
results in an internal table.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(make [url->servlet url->servlet/c]
|
@defproc[(make [url->servlet url->servlet/c]
|
||||||
|
@ -35,9 +36,12 @@
|
||||||
(url? exn? . -> . can-be-response?)
|
(url? exn? . -> . can-be-response?)
|
||||||
servlet-error-responder])
|
servlet-error-responder])
|
||||||
dispatcher/c]{
|
dispatcher/c]{
|
||||||
This dispatcher runs racket servlets, using @racket[url->servlet] to resolve URLs to the underlying servlets.
|
This dispatcher runs racket servlets, using @racket[url->servlet] to
|
||||||
If servlets have errors loading, then @racket[responders-servlet-loading] is used. Other errors are handled with
|
resolve URLs to the underlying servlets. If servlets have errors
|
||||||
@racket[responders-servlet]. If a servlet raises calls @racket[next-dispatcher], then the signal is propagated by this dispatcher.
|
loading, then @racket[responders-servlet-loading] is used. Other errors
|
||||||
|
are handled with @racket[responders-servlet]. If a servlet raises calls
|
||||||
|
@racket[next-dispatcher], then the signal is propagated by this
|
||||||
|
dispatcher.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,10 +102,12 @@ URLs to paths on the filesystem.
|
||||||
@defproc[(filter-url->path [regex regexp?]
|
@defproc[(filter-url->path [regex regexp?]
|
||||||
[url->path url->path/c])
|
[url->path url->path/c])
|
||||||
url->path/c]{
|
url->path/c]{
|
||||||
Runs the underlying @racket[url->path] but will only return if the path, when considered as a string,
|
Runs the underlying @racket[url->path] but will only return if the
|
||||||
matches the @racket[regex]. This is useful to disallow strange files, like GIFs, from being considered
|
path, when considered as a string, matches the @racket[regex]. This is
|
||||||
servlets when using the servlet dispatchers. It will return a @racket[exn:fail:filesystem:exists?] exception if
|
useful to disallow strange files, like GIFs, from being considered
|
||||||
the path does not match.
|
servlets when using the servlet dispatchers. It will return a
|
||||||
|
@racket[exn:fail:filesystem:exists?] exception if the path does not
|
||||||
|
match.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -249,9 +251,9 @@ a URL that refreshes the password file, servlet cache, etc.}
|
||||||
web-server/configuration/responders))
|
web-server/configuration/responders))
|
||||||
|
|
||||||
@defthing[denied?/c contract?]{
|
@defthing[denied?/c contract?]{
|
||||||
Equivalent to @racket[(request? . -> . (or/c false/c string?))].
|
Equivalent to @racket[(request? . -> . (or/c false/c string?))]. The
|
||||||
The return is the authentication realm as a string if the request is not authorized and
|
return is the authentication realm as a string if the request is not
|
||||||
@racket[#f] if the request @emph{is} authorized.
|
authorized and @racket[#f] if the request @emph{is} authorized.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(make [denied? denied?/c]
|
@defproc[(make [denied? denied?/c]
|
||||||
|
@ -260,24 +262,26 @@ a URL that refreshes the password file, servlet cache, etc.}
|
||||||
(url? header? . -> . response?)
|
(url? header? . -> . response?)
|
||||||
(gen-authentication-responder "forbidden.html")])
|
(gen-authentication-responder "forbidden.html")])
|
||||||
dispatcher/c]{
|
dispatcher/c]{
|
||||||
A dispatcher that checks if the request is denied based on @racket[denied?]. If so, then
|
A dispatcher that checks if the request is denied based on
|
||||||
@racket[authentication-responder] is called with a @racket[header] that
|
@racket[denied?]. If so, then @racket[authentication-responder] is
|
||||||
requests credentials. If not, then @racket[next-dispatcher] is
|
called with a @racket[header] that requests credentials. If not, then
|
||||||
invoked.
|
@racket[next-dispatcher] is invoked.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defthing[authorized?/c contract?]{
|
@defthing[authorized?/c contract?]{
|
||||||
Equivalent to @racket[(string? (or/c false/c bytes?) (or/c false/c bytes?) . -> . (or/c false/c string?))].
|
Equivalent to
|
||||||
The input is the URI as a string and the username and passwords as bytes.
|
@racket[(string? (or/c false/c bytes?) (or/c false/c bytes?) . -> . (or/c false/c string?))].
|
||||||
The return is the authentication realm as a string if the user is not authorized and
|
The input is the URI as a string and the username and passwords as
|
||||||
@racket[#f] if the request @emph{is} authorized.
|
bytes. The return is the authentication realm as a string if the user
|
||||||
|
is not authorized and @racket[#f] if the request @emph{is} authorized.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(make-basic-denied?/path [password-file path-string?])
|
@defproc[(make-basic-denied?/path [password-file path-string?])
|
||||||
(values (-> void)
|
(values (-> void)
|
||||||
authorized?/c)]{
|
authorized?/c)]{
|
||||||
Creates an authorization procedure based on the given password file. The first returned value
|
Creates an authorization procedure based on the given password
|
||||||
is a procedure that refreshes the password cache used by the authorization procedure.
|
file. The first returned value is a procedure that refreshes the
|
||||||
|
password cache used by the authorization procedure.
|
||||||
|
|
||||||
@racket[password-file] is parsed as:
|
@racket[password-file] is parsed as:
|
||||||
@racketblock[(list ([domain : string?]
|
@racketblock[(list ([domain : string?]
|
||||||
|
|
|
@ -23,8 +23,7 @@ Suppose we want to create an abstraction of entering a date in an HTML form. The
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(define date-formlet
|
(define date-formlet
|
||||||
(formlet
|
(formlet
|
||||||
(div
|
(div "Month:" ,{input-int . => . month}
|
||||||
"Month:" ,{input-int . => . month}
|
|
||||||
"Day:" ,{input-int . => . day})
|
"Day:" ,{input-int . => . day})
|
||||||
(list month day)))
|
(list month day)))
|
||||||
]
|
]
|
||||||
|
@ -233,7 +232,8 @@ types. Refer to @secref["input-formlets"] for example low-level formlets using t
|
||||||
|
|
||||||
@defproc[(xml-forest [r xexpr-forest/c])
|
@defproc[(xml-forest [r xexpr-forest/c])
|
||||||
(formlet/c procedure?)]{
|
(formlet/c procedure?)]{
|
||||||
Constructs a @tech{formlet} with the rendering @racket[r] and the identity procedure as the processing step.
|
Constructs a @tech{formlet} with the rendering @racket[r] and the
|
||||||
|
identity procedure as the processing step.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(xml [r xexpr/c])
|
@defproc[(xml [r xexpr/c])
|
||||||
|
@ -250,8 +250,10 @@ types. Refer to @secref["input-formlets"] for example low-level formlets using t
|
||||||
[attrs (listof (list/c symbol? string?))]
|
[attrs (listof (list/c symbol? string?))]
|
||||||
[inner (formlet/c any/c)])
|
[inner (formlet/c any/c)])
|
||||||
(formlet/c any/c)]{
|
(formlet/c any/c)]{
|
||||||
Constructs a @tech{formlet} with the rendering @racket[(list (list* tag attrs inner-rendering))] where @racket[inner-rendering] is
|
Constructs a @tech{formlet} with the rendering @racket[(list (list*
|
||||||
the rendering of @racket[inner] and the processing stage identical to @racket[inner].
|
tag attrs inner-rendering))] where @racket[inner-rendering] is the
|
||||||
|
rendering of @racket[inner] and the processing stage identical to
|
||||||
|
@racket[inner].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(formlet-display [f (formlet/c any/c)])
|
@defproc[(formlet-display [f (formlet/c any/c)])
|
||||||
|
@ -276,14 +278,15 @@ These @tech{formlet}s are the main combinators for form input.
|
||||||
|
|
||||||
@defproc[(make-input [render (string? . -> . xexpr/c)])
|
@defproc[(make-input [render (string? . -> . xexpr/c)])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
This @tech{formlet} is rendered with @racket[render], which is passed the input name, and results in the
|
This @tech{formlet} is rendered with @racket[render], which is passed
|
||||||
extracted @racket[binding].
|
the input name, and results in the extracted @racket[binding].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(make-input* [render (string? . -> . xexpr/c)])
|
@defproc[(make-input* [render (string? . -> . xexpr/c)])
|
||||||
(formlet/c (listof binding?))]{
|
(formlet/c (listof binding?))]{
|
||||||
This @tech{formlet} is rendered with @racket[render], which is passed the input name, and results in all the
|
This @tech{formlet} is rendered with @racket[render], which is passed
|
||||||
@racket[binding]s that use the name.
|
the input name, and results in all the @racket[binding]s that use the
|
||||||
|
name.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(text-input [#:value value (or/c false/c bytes?) #f]
|
@defproc[(text-input [#:value value (or/c false/c bytes?) #f]
|
||||||
|
@ -292,7 +295,8 @@ These @tech{formlet}s are the main combinators for form input.
|
||||||
[#:read-only? read-only? boolean? #f]
|
[#:read-only? read-only? boolean? #f]
|
||||||
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
This @tech{formlet} renders using an INPUT element with the TEXT type and the attributes given in the arguments.
|
This @tech{formlet} renders using an INPUT element with the TEXT type
|
||||||
|
and the attributes given in the arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(password-input [#:value value (or/c false/c bytes?) #f]
|
@defproc[(password-input [#:value value (or/c false/c bytes?) #f]
|
||||||
|
@ -301,7 +305,8 @@ These @tech{formlet}s are the main combinators for form input.
|
||||||
[#:read-only? read-only? boolean? #f]
|
[#:read-only? read-only? boolean? #f]
|
||||||
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
This @tech{formlet} renders using an INPUT element with the PASSWORD type and the attributes given in the arguments.
|
This @tech{formlet} renders using an INPUT element with the PASSWORD
|
||||||
|
type and the attributes given in the arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(textarea-input [#:value value (or/c false/c bytes?) #f]
|
@defproc[(textarea-input [#:value value (or/c false/c bytes?) #f]
|
||||||
|
@ -309,14 +314,16 @@ These @tech{formlet}s are the main combinators for form input.
|
||||||
[#:cols cols (or/c false/c number?) #f]
|
[#:cols cols (or/c false/c number?) #f]
|
||||||
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
This @tech{formlet} renders using an TEXTAREA element with attributes given in the arguments.
|
This @tech{formlet} renders using an TEXTAREA element with attributes
|
||||||
|
given in the arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(checkbox [value bytes?]
|
@defproc[(checkbox [value bytes?]
|
||||||
[checked? boolean?]
|
[checked? boolean?]
|
||||||
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
This @tech{formlet} renders using an INPUT element with the CHECKBOX type and the attributes given in the arguments.
|
This @tech{formlet} renders using an INPUT element with the CHECKBOX
|
||||||
|
type and the attributes given in the arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(radio [value bytes?]
|
@defproc[(radio [value bytes?]
|
||||||
|
@ -329,23 +336,27 @@ These @tech{formlet}s are the main combinators for form input.
|
||||||
@defproc[(submit [value bytes?]
|
@defproc[(submit [value bytes?]
|
||||||
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
This @tech{formlet} renders using an INPUT element with the SUBMIT type and the attributes given in the arguments.
|
This @tech{formlet} renders using an INPUT element with the SUBMIT
|
||||||
|
type and the attributes given in the arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(reset [value bytes?]
|
@defproc[(reset [value bytes?]
|
||||||
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
This @tech{formlet} renders using an INPUT element with the RESET type and the attributes given in the arguments.
|
This @tech{formlet} renders using an INPUT element with the RESET type
|
||||||
|
and the attributes given in the arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(file-upload [#:attributes attrs (listof (list/c symbol? string?)) empty])
|
@defproc[(file-upload [#:attributes attrs (listof (list/c symbol? string?)) empty])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
This @tech{formlet} renders using an INPUT element with the FILE type and the attributes given in the arguments.
|
This @tech{formlet} renders using an INPUT element with the FILE type
|
||||||
|
and the attributes given in the arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(hidden [value bytes?] [#:attributes attrs (listof (list/c symbol? string?)) empty])
|
@defproc[(hidden [value bytes?] [#:attributes attrs (listof (list/c symbol? string?)) empty])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
This @tech{formlet} renders using an INPUT element with HIDDEN type and the attributes given in the arguments.
|
This @tech{formlet} renders using an INPUT element with HIDDEN type
|
||||||
|
and the attributes given in the arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(img [alt bytes?]
|
@defproc[(img [alt bytes?]
|
||||||
|
@ -356,7 +367,8 @@ These @tech{formlet}s are the main combinators for form input.
|
||||||
[#:width width (or/c false/c exact-nonnegative-integer?) #f]
|
[#:width width (or/c false/c exact-nonnegative-integer?) #f]
|
||||||
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
This @tech{formlet} renders using an IMG element with the attributes given in the arguments.
|
This @tech{formlet} renders using an IMG element with the attributes
|
||||||
|
given in the arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(button [type bytes?]
|
@defproc[(button [type bytes?]
|
||||||
|
@ -365,7 +377,9 @@ These @tech{formlet}s are the main combinators for form input.
|
||||||
[#:value value (or/c false/c bytes?) #f]
|
[#:value value (or/c false/c bytes?) #f]
|
||||||
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
[#:attributes attrs (listof (list/c symbol? string?)) empty])
|
||||||
(formlet/c (or/c false/c binding?))]{
|
(formlet/c (or/c false/c binding?))]{
|
||||||
This @tech{formlet} renders using a BUTTON element with the attributes given in the arguments. @racket[button-text] is the text that will appear on the button when rendered.
|
This @tech{formlet} renders using a BUTTON element with the attributes
|
||||||
|
given in the arguments. @racket[button-text] is the text that will
|
||||||
|
appear on the button when rendered.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(multiselect-input [l sequence?]
|
@defproc[(multiselect-input [l sequence?]
|
||||||
|
@ -374,7 +388,11 @@ These @tech{formlet}s are the main combinators for form input.
|
||||||
[#:selected? selected? (any/c . -> . boolean?) (λ (x) #f)]
|
[#:selected? selected? (any/c . -> . boolean?) (λ (x) #f)]
|
||||||
[#:display display (any/c . -> . xexpr/c) (λ (x) x)])
|
[#:display display (any/c . -> . xexpr/c) (λ (x) x)])
|
||||||
(formlet/c list?)]{
|
(formlet/c list?)]{
|
||||||
This @tech{formlet} renders using an SELECT element with the attributes given with an OPTION for each element of the sequence. If @racket[multiple?] is @racket[#t], then multiple options may be selected. An element is selected if @racket[selected?] returns @racket[#t]. Elements are displayed with @racket[display].
|
This @tech{formlet} renders using an SELECT element with the
|
||||||
|
attributes given with an OPTION for each element of the sequence. If
|
||||||
|
@racket[multiple?] is @racket[#t], then multiple options may be
|
||||||
|
selected. An element is selected if @racket[selected?] returns
|
||||||
|
@racket[#t]. Elements are displayed with @racket[display].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(select-input [l sequence?]
|
@defproc[(select-input [l sequence?]
|
||||||
|
@ -382,39 +400,50 @@ These @tech{formlet}s are the main combinators for form input.
|
||||||
[#:selected? selected? (any/c . -> . boolean?) (λ (x) #f)]
|
[#:selected? selected? (any/c . -> . boolean?) (λ (x) #f)]
|
||||||
[#:display display (any/c . -> . xexpr/c) (λ (x) x)])
|
[#:display display (any/c . -> . xexpr/c) (λ (x) x)])
|
||||||
(formlet/c any/c)]{
|
(formlet/c any/c)]{
|
||||||
This @tech{formlet} renders using an SELECT element with the attributes given with an OPTION for each element of the sequence. An element is selected if @racket[selected?] returns @racket[#t]. Elements are displayed with @racket[display].
|
This @tech{formlet} renders using an SELECT element with the
|
||||||
|
attributes given with an OPTION for each element of the sequence. An
|
||||||
|
element is selected if @racket[selected?] returns
|
||||||
|
@racket[#t]. Elements are displayed with @racket[display].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(required [f (formlet/c (or/c false/c binding?))])
|
@defproc[(required [f (formlet/c (or/c false/c binding?))])
|
||||||
(formlet/c bytes?)]{
|
(formlet/c bytes?)]{
|
||||||
Constructs a @tech{formlet} that extracts the @racket[binding:form-value] from the binding produced by @racket[f], or errors.
|
Constructs a @tech{formlet} that extracts the
|
||||||
|
@racket[binding:form-value] from the binding produced by @racket[f],
|
||||||
|
or errors.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(default
|
@defproc[(default
|
||||||
[def bytes?]
|
[def bytes?]
|
||||||
[f (formlet/c (or/c false/c binding?))])
|
[f (formlet/c (or/c false/c binding?))])
|
||||||
(formlet/c bytes?)]{
|
(formlet/c bytes?)]{
|
||||||
Constructs a @tech{formlet} that extracts the @racket[binding:form-value] from the binding produced by @racket[f], or returns @racket[def].
|
Constructs a @tech{formlet} that extracts the
|
||||||
|
@racket[binding:form-value] from the binding produced by @racket[f],
|
||||||
|
or returns @racket[def].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(to-string [f (formlet/c bytes?)])
|
@defproc[(to-string [f (formlet/c bytes?)])
|
||||||
(formlet/c string?)]{
|
(formlet/c string?)]{
|
||||||
Converts @racket[f]'s output to a string. Equivalent to @racket[(cross (pure bytes->string/utf-8) f)].
|
Converts @racket[f]'s output to a string. Equivalent to
|
||||||
|
@racket[(cross (pure bytes->string/utf-8) f)].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(to-number [f (formlet/c string?)])
|
@defproc[(to-number [f (formlet/c string?)])
|
||||||
(formlet/c number?)]{
|
(formlet/c number?)]{
|
||||||
Converts @racket[f]'s output to a number. Equivalent to @racket[(cross (pure string->number) f)].
|
Converts @racket[f]'s output to a number. Equivalent to @racket[(cross
|
||||||
|
(pure string->number) f)].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(to-symbol [f (formlet/c string?)])
|
@defproc[(to-symbol [f (formlet/c string?)])
|
||||||
(formlet/c symbol?)]{
|
(formlet/c symbol?)]{
|
||||||
Converts @racket[f]'s output to a symbol. Equivalent to @racket[(cross (pure string->symbol) f)].
|
Converts @racket[f]'s output to a symbol. Equivalent to
|
||||||
|
@racket[(cross (pure string->symbol) f)].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(to-boolean [f (formlet/c bytes?)])
|
@defproc[(to-boolean [f (formlet/c bytes?)])
|
||||||
(formlet/c boolean?)]{
|
(formlet/c boolean?)]{
|
||||||
Converts @racket[f]'s output to a boolean, if it is equal to @racket[#"on"].
|
Converts @racket[f]'s output to a boolean, if it is equal to
|
||||||
|
@racket[#"on"].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defthing[input-string (formlet/c string?)]{
|
@defthing[input-string (formlet/c string?)]{
|
||||||
|
@ -446,16 +475,18 @@ A few utilities are provided for using @tech{formlet}s in Web applications.
|
||||||
`(html (head (title "Form Entry"))
|
`(html (head (title "Form Entry"))
|
||||||
(body ,form-xexpr)))])
|
(body ,form-xexpr)))])
|
||||||
(values any/c ...)]{
|
(values any/c ...)]{
|
||||||
Uses @racket[send/suspend] and @racket[response/xexpr] to send @racket[f]'s rendering (wrapped in a FORM tag whose action is
|
Uses @racket[send/suspend] and @racket[response/xexpr] to send
|
||||||
the continuation URL (wrapped again by @racket[wrapper])) to the client.
|
@racket[f]'s rendering (wrapped in a FORM tag whose action is the
|
||||||
When the form is submitted, the request is passed to the
|
continuation URL (wrapped again by @racket[wrapper])) to the client.
|
||||||
processing stage of @racket[f].
|
When the form is submitted, the request is passed to the processing
|
||||||
|
stage of @racket[f].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(embed-formlet [embed/url ((request? . -> . any) . -> . string?)]
|
@defproc[(embed-formlet [embed/url ((request? . -> . any) . -> . string?)]
|
||||||
[f (formlet/c any/c ...)])
|
[f (formlet/c any/c ...)])
|
||||||
xexpr/c]{
|
xexpr/c]{
|
||||||
Like @racket[send/formlet], but for use with @racket[send/suspend/dispatch].
|
Like @racket[send/formlet], but for use with
|
||||||
|
@racket[send/suspend/dispatch].
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,8 +278,9 @@ transmission that the server @bold{will not catch}.}
|
||||||
[domain (or/c false/c valid-domain?)]
|
[domain (or/c false/c valid-domain?)]
|
||||||
[path (or/c false/c string?)])]{
|
[path (or/c false/c string?)])]{
|
||||||
|
|
||||||
While server cookies are represented with @racket[cookie?]s, cookies that come from the client are represented
|
While server cookies are represented with @racket[cookie?]s, cookies
|
||||||
with a @racket[client-cookie] structure.
|
that come from the client are represented with a
|
||||||
|
@racket[client-cookie] structure.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(request-cookies [req request?])
|
@defproc[(request-cookies [req request?])
|
||||||
|
@ -423,15 +424,19 @@ An implementation of HTTP Digest Authentication.
|
||||||
|
|
||||||
@defproc[(password->digest-HA1 [lookup-password username*realm->password/c])
|
@defproc[(password->digest-HA1 [lookup-password username*realm->password/c])
|
||||||
username*realm->digest-HA1/c]{
|
username*realm->digest-HA1/c]{
|
||||||
Uses @racket[lookup-password] to find the password, then computes the secret hash of it.
|
Uses @racket[lookup-password] to find the password, then computes the
|
||||||
|
secret hash of it.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(make-check-digest-credentials [lookup-HA1 username*realm->digest-HA1/c])
|
@defproc[(make-check-digest-credentials [lookup-HA1 username*realm->digest-HA1/c])
|
||||||
(string? (listof (cons/c symbol? string?)) . -> . boolean?)]{
|
(string? (listof (cons/c symbol? string?)) . -> . boolean?)]{
|
||||||
Constructs a function that checks whether particular Digest credentials (the second argument of the returned function)
|
Constructs a function that checks whether particular Digest credentials
|
||||||
are correct given the HTTP method provided as the first argument and the secret hash computed by @racket[lookup-HA1].
|
(the second argument of the returned function) are correct given the
|
||||||
|
HTTP method provided as the first argument and the secret hash computed
|
||||||
|
by @racket[lookup-HA1].
|
||||||
|
|
||||||
This is will result in an exception if the Digest credentials are missing portions.
|
This is will result in an exception if the Digest credentials are
|
||||||
|
missing portions.
|
||||||
}
|
}
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
|
@ -21,10 +21,11 @@ of @racketmodname[web-server/dispatchers/dispatch-servlets].
|
||||||
|
|
||||||
@defproc[(make-make-servlet-namespace (#:to-be-copied-module-specs to-be-copied-module-specs (listof module-path?)))
|
@defproc[(make-make-servlet-namespace (#:to-be-copied-module-specs to-be-copied-module-specs (listof module-path?)))
|
||||||
make-servlet-namespace/c]{
|
make-servlet-namespace/c]{
|
||||||
This function creates a function that when called will construct a new @racket[namespace] that
|
This function creates a function that when called will construct a new
|
||||||
has all the modules from @racket[to-be-copied-module-specs] and @racket[additional-specs], as well
|
@racket[namespace] that has all the modules from
|
||||||
as @racket[racket] and @racket[mred], provided they are already attached
|
@racket[to-be-copied-module-specs] and @racket[additional-specs], as
|
||||||
to the @racket[(current-namespace)] of the call-site.
|
well as @racket[racket] and @racket[mred], provided they are already
|
||||||
|
attached to the @racket[(current-namespace)] of the call-site.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@racketblock[
|
@racketblock[
|
||||||
|
@ -37,14 +38,17 @@ Example:
|
||||||
|
|
||||||
@section{Why this is useful}
|
@section{Why this is useful}
|
||||||
|
|
||||||
A different namespace is needed for each servlet, so that if servlet A and servlet B both use
|
A different namespace is needed for each servlet, so that if servlet A
|
||||||
a stateful module C, they will be isolated from one another. We see the @web-server as
|
and servlet B both use a stateful module C, they will be isolated from
|
||||||
an operating system for servlets, so we inherit the isolation requirement on operating systems.
|
one another. We see the @web-server as an operating system for servlets,
|
||||||
|
so we inherit the isolation requirement on operating systems.
|
||||||
|
|
||||||
However, there are some modules which must be shared. If they were not, then structures cannot
|
However, there are some modules which must be shared. If they were not,
|
||||||
be passed from the @web-server to the servlets, because Racket's structures are generative.
|
then structures cannot be passed from the @web-server to the servlets,
|
||||||
|
because Racket's structures are generative.
|
||||||
|
|
||||||
Since, on occasion, a user will actually wanted servlets A and B to interact through module C.
|
Since, on occasion, a user will actually wanted servlets A and B to
|
||||||
A custom @racket[make-servlet-namespace] can be created, through this procedure, that attaches
|
interact through module C. A custom @racket[make-servlet-namespace] can
|
||||||
module C to all servlet namespaces. Through other means (see @secref["dispatchers"]) different sets
|
be created, through this procedure, that attaches module C to all
|
||||||
of servlets can share different sets of modules.
|
servlet namespaces. Through other means (see @secref["dispatchers"])
|
||||||
|
different sets of servlets can share different sets of modules.
|
||||||
|
|
|
@ -9,12 +9,17 @@
|
||||||
|
|
||||||
@defmodule[web-server/lang/native]{
|
@defmodule[web-server/lang/native]{
|
||||||
|
|
||||||
It is sometimes inconvenient to use @racket[serial->native] and @racket[native->serial] throughout your program.
|
It is sometimes inconvenient to use @racket[serial->native] and
|
||||||
This module provides a macro for creating wrappers.
|
@racket[native->serial] throughout your program. This module provides a
|
||||||
|
macro for creating wrappers.
|
||||||
|
|
||||||
@defform[#:literals (ho) (define-native (native arg-spec ...) original) #:contracts ([arg-spec ho] [arg-spec _])]{
|
@defform[#:literals (ho)
|
||||||
Builds an interface around @racket[original] named @racket[native] such that calls to @racket[native] are wrapped in @racket[serial->native]
|
(define-native (native arg-spec ...) original)
|
||||||
and all arguments marked with @racket[ho] in @racket[arg-spec] are assumed to procedures and are wrapped in @racket[native->serial].
|
#:contracts ([arg-spec ho] [arg-spec _])]{
|
||||||
|
Builds an interface around @racket[original] named @racket[native] such
|
||||||
|
that calls to @racket[native] are wrapped in @racket[serial->native]
|
||||||
|
and all arguments marked with @racket[ho] in @racket[arg-spec] are
|
||||||
|
assumed to procedures and are wrapped in @racket[native->serial].
|
||||||
|
|
||||||
For example,
|
For example,
|
||||||
@racketblock[
|
@racketblock[
|
||||||
|
|
|
@ -39,33 +39,59 @@ A simple example:
|
||||||
"You clicked!"))])
|
"You clicked!"))])
|
||||||
"Click me")))))]
|
"Click me")))))]
|
||||||
|
|
||||||
Similarly, many Web applications make use almost exclusively of functions that are arguments to @racket[embed/url] and immediately invoke @racket[send/suspend/dispatch].
|
Similarly, many Web applications make use almost exclusively of
|
||||||
|
functions that are arguments to @racket[embed/url] and immediately
|
||||||
|
invoke @racket[send/suspend/dispatch].
|
||||||
|
|
||||||
@deftogether[[@defform[(lambda/page formals e ...)]
|
@deftogether[[@defform[(lambda/page formals e ...)]
|
||||||
@defform[(define/page (id . formals) e ...)]]]{
|
@defform[(define/page (id . formals) e ...)]]]{
|
||||||
The @racket[lambda/page] and @racket[define/page] automate this by expanding to functions that accept a request as the first argument (followed by any arguments specified in @racket[formals]) and immediately wrap their body in @racket[page]. This functions also cooperate with @racket[get-binding] by binding the request to the @racket[current-request] parameter.
|
The @racket[lambda/page] and @racket[define/page] automate this by
|
||||||
|
expanding to functions that accept a request as the first argument
|
||||||
|
(followed by any arguments specified in @racket[formals]) and
|
||||||
|
immediately wrap their body in @racket[page]. This functions also
|
||||||
|
cooperate with @racket[get-binding] by binding the request to the
|
||||||
|
@racket[current-request] parameter.
|
||||||
}
|
}
|
||||||
|
|
||||||
The binding interface of @racketmodname[web-server/http] is powerful, but subtle to use conveniently due to its protection against hostile clients.
|
The binding interface of @racketmodname[web-server/http] is powerful,
|
||||||
|
but subtle to use conveniently due to its protection against hostile
|
||||||
|
clients.
|
||||||
|
|
||||||
@deftogether[[
|
@deftogether[[
|
||||||
@defparam[current-request req request?]
|
@defparam[current-request req request?]
|
||||||
@defthing[binding-id/c contract?]
|
@defthing[binding-id/c contract?]
|
||||||
@defthing[binding-format/c contract?]
|
@defthing[binding-format/c contract?]
|
||||||
@defproc[(get-binding [id binding-id/c] [req request? (current-request)] [#:format format binding-format/c 'string])
|
@defproc[(get-binding [id binding-id/c]
|
||||||
|
[req request? (current-request)]
|
||||||
|
[#:format format binding-format/c 'string])
|
||||||
(or/c false/c string? bytes? binding?)]
|
(or/c false/c string? bytes? binding?)]
|
||||||
@defproc[(get-bindings [id binding-id/c] [req request? (current-request)] [#:format format binding-format/c 'string])
|
@defproc[(get-bindings [id binding-id/c]
|
||||||
|
[req request? (current-request)]
|
||||||
|
[#:format format binding-format/c 'string])
|
||||||
(listof (or/c string? bytes? binding?))]
|
(listof (or/c string? bytes? binding?))]
|
||||||
]]{
|
]]{
|
||||||
|
|
||||||
The @racket[get-binding](s) interface attempts to resolve this by providing a powerful interface with convenient defaults.
|
The @racket[get-binding](s) interface attempts to resolve this by
|
||||||
|
providing a powerful interface with convenient defaults.
|
||||||
|
|
||||||
@racket[get-binding] extracts the first binding of a form input from a request, while @racket[get-bindings] extracts them all.
|
@racket[get-binding] extracts the first binding of a form input from a
|
||||||
|
request, while @racket[get-bindings] extracts them all.
|
||||||
|
|
||||||
They accept a form identifier (@racket[id]) as either a byte string, a string, or a symbol. In each case, the user input is compared in a case-sensitive way with the form input.
|
They accept a form identifier (@racket[id]) as either a byte string, a
|
||||||
|
string, or a symbol. In each case, the user input is compared in a
|
||||||
|
case-sensitive way with the form input.
|
||||||
|
|
||||||
They accept an optional request argument (@racket[req]) that defaults to the value of the @racket[current-request] parameter used by @racket[lambda/page] and @racket[define/page].
|
They accept an optional request argument (@racket[req]) that defaults
|
||||||
|
to the value of the @racket[current-request] parameter used by
|
||||||
|
@racket[lambda/page] and @racket[define/page].
|
||||||
|
|
||||||
Finally, they accept an optional keyword argument (@racket[format]) that specifies the desired return format. The default, @racket['string], produces a UTF-8 string (or @racket[#f] if the byte string cannot be converted to UTF-8.) The @racket['bytes] format always produces the raw byte string. The @racket['file] format produces the file upload content (or @racket[#f] if the form input was not an uploaded file.) The @racket['binding] format produces the binding object.
|
Finally, they accept an optional keyword argument (@racket[format])
|
||||||
|
that specifies the desired return format. The default,
|
||||||
|
@racket['string], produces a UTF-8 string (or @racket[#f] if the byte
|
||||||
|
string cannot be converted to UTF-8.) The @racket['bytes] format
|
||||||
|
always produces the raw byte string. The @racket['file] format
|
||||||
|
produces the file upload content (or @racket[#f] if the form input was
|
||||||
|
not an uploaded file.) The @racket['binding] format produces the
|
||||||
|
binding object.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,70 +8,88 @@
|
||||||
|
|
||||||
@defmodule[web-server/configuration/responders]{
|
@defmodule[web-server/configuration/responders]{
|
||||||
|
|
||||||
This module provides some functions that help constructing HTTP responders.
|
This module provides some functions that help constructing HTTP
|
||||||
These functions are used by the default dispatcher constructor (see @secref["web-server-unit"]) to
|
responders. These functions are used by the default dispatcher
|
||||||
turn the paths given in the @racket[configuration-table] into responders for the associated circumstance.
|
constructor (see @secref["web-server-unit"]) to turn the paths given in
|
||||||
|
the @racket[configuration-table] into responders for the associated
|
||||||
|
circumstance.
|
||||||
|
|
||||||
@defproc[(file-response (http-code natural-number/c) (short-version string?) (text-file string?) (header header?) ...)
|
@defproc[(file-response [http-code natural-number/c]
|
||||||
|
[short-version string?]
|
||||||
|
[text-file string?]
|
||||||
|
[header header?] ...)
|
||||||
response?]{
|
response?]{
|
||||||
Generates a @racket[response?] with the given @racket[http-code] and @racket[short-version]
|
Generates a @racket[response?] with the given @racket[http-code] and
|
||||||
as the corresponding fields; with the content of the @racket[text-file] as the body; and, with
|
@racket[short-version] as the corresponding fields; with the content of
|
||||||
the @racket[header]s as, you guessed it, headers.
|
the @racket[text-file] as the body; and, with the @racket[header]s as,
|
||||||
|
you guessed it, headers.
|
||||||
|
|
||||||
This does not cause redirects to a well-known URL, such as @filepath{conf/not-found.html}, but rather use the contents
|
This does not cause redirects to a well-known URL, such as
|
||||||
of @filepath{not-found.html} (for example) as its contents. Therefore, any relative URLs in @racket[text-file] are relative
|
@filepath{conf/not-found.html}, but rather use the contents of
|
||||||
to whatever URL @racket[file-response] is used to respond @emph{to}. Thus, you should probably use absolute URLs in these files.
|
@filepath{not-found.html} (for example) as its contents. Therefore, any
|
||||||
|
relative URLs in @racket[text-file] are relative to whatever URL
|
||||||
|
@racket[file-response] is used to respond @emph{to}. Thus, you should
|
||||||
|
probably use absolute URLs in these files.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(servlet-loading-responder (url url?) (exn exn?))
|
@defproc[(servlet-loading-responder [url url?] [exn exn?])
|
||||||
response?]{
|
response?]{
|
||||||
Gives @racket[exn] to the @racket[current-error-handler] and response with a stack trace and a "Servlet didn't load" message.
|
Gives @racket[exn] to the @racket[current-error-handler] and response
|
||||||
|
with a stack trace and a "Servlet didn't load" message.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(gen-servlet-not-found (file path-string?))
|
@defproc[(gen-servlet-not-found [file path-string?])
|
||||||
((url url?) . -> . response?)]{
|
((url url?) . -> . response?)]{
|
||||||
Returns a function that generates a standard "Servlet not found." error with content from @racket[file].
|
Returns a function that generates a standard "Servlet not found." error
|
||||||
|
with content from @racket[file].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(servlet-error-responder (url url?) (exn exn?))
|
@defproc[(servlet-error-responder [url url?] [exn exn?])
|
||||||
response?]{
|
response?]{
|
||||||
Gives @racket[exn] to the @racket[current-error-handler] and response with a stack trace and a "Servlet error" message.
|
Gives @racket[exn] to the @racket[current-error-handler] and response
|
||||||
|
with a stack trace and a "Servlet error" message.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(gen-servlet-responder (file path-string?))
|
@defproc[(gen-servlet-responder [file path-string?])
|
||||||
((url url?) (exn any/c) . -> . response?)]{
|
((url url?) (exn any/c) . -> . response?)]{
|
||||||
Prints the @racket[exn] to standard output and responds with a "Servlet error." message with content from @racket[file].
|
Prints the @racket[exn] to standard output and responds with a "Servlet
|
||||||
|
error." message with content from @racket[file].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(gen-servlets-refreshed (file path-string?))
|
@defproc[(gen-servlets-refreshed [file path-string?])
|
||||||
(-> response?)]{
|
(-> response?)]{
|
||||||
Returns a function that generates a standard "Servlet cache refreshed." message with content from @racket[file].
|
Returns a function that generates a standard "Servlet cache refreshed."
|
||||||
|
message with content from @racket[file].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(gen-passwords-refreshed (file path-string?))
|
@defproc[(gen-passwords-refreshed [file path-string?])
|
||||||
(-> response?)]{
|
(-> response?)]{
|
||||||
Returns a function that generates a standard "Passwords refreshed." message with content from @racket[file].
|
Returns a function that generates a standard "Passwords refreshed."
|
||||||
|
message with content from @racket[file].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(gen-authentication-responder (file path-string?))
|
@defproc[(gen-authentication-responder [file path-string?])
|
||||||
((url url?) (header header?) . -> . response?)]{
|
((url url?) (header header?) . -> . response?)]{
|
||||||
Returns a function that generates an authentication failure error with content from @racket[file] and
|
Returns a function that generates an authentication failure error with
|
||||||
@racket[header] as the HTTP header.
|
content from @racket[file] and @racket[header] as the HTTP header.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(gen-protocol-responder (file path-string?))
|
@defproc[(gen-protocol-responder [file path-string?])
|
||||||
((url url?) . -> . response?)]{
|
((url url?) . -> . response?)]{
|
||||||
Returns a function that generates a "Malformed request" error with content from @racket[file].
|
Returns a function that generates a "Malformed request" error with
|
||||||
|
content from @racket[file].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(gen-file-not-found-responder (file path-string?))
|
@defproc[(gen-file-not-found-responder [file path-string?])
|
||||||
((req request?) . -> . response?)]{
|
((req request?) . -> . response?)]{
|
||||||
Returns a function that generates a standard "File not found" error with content from @racket[file].
|
Returns a function that generates a standard "File not found" error
|
||||||
|
with content from @racket[file].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(gen-collect-garbage-responder (file path-string?))
|
@defproc[(gen-collect-garbage-responder [file path-string?])
|
||||||
(-> response?)]{
|
(-> response?)]{
|
||||||
Returns a function that generates a standard "Garbage collection run" message with content from @racket[file].
|
Returns a function that generates a standard "Garbage collection run"
|
||||||
|
message with content from @racket[file].
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,10 @@ and increasing the size of the serialization. This module provides support for t
|
||||||
|
|
||||||
@defproc[(soft-state-ref [ss soft-state?])
|
@defproc[(soft-state-ref [ss soft-state?])
|
||||||
any/c]{
|
any/c]{
|
||||||
Extracts the value associated with @racket[ss]. If the value is not available (perhaps because of garbage collection, deserialization in an uninitialized process, etc), then the thunk associated with @racket[ss] is invoked and the value is cached.
|
Extracts the value associated with @racket[ss]. If the value is not
|
||||||
|
available (perhaps because of garbage collection, deserialization in an
|
||||||
|
uninitialized process, etc), then the thunk associated with @racket[ss]
|
||||||
|
is invoked and the value is cached.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defform[(soft-state expr ...)]{
|
@defform[(soft-state expr ...)]{
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
|
|
||||||
@title[#:tag "considerations"]{Usage Considerations}
|
@title[#:tag "considerations"]{Usage Considerations}
|
||||||
|
|
||||||
A stateless servlet has the following process performed on it automatically:
|
A stateless servlet has the following process performed on it
|
||||||
|
automatically:
|
||||||
@itemize[
|
@itemize[
|
||||||
@item{All uses of @racket[letrec] are removed and replaced with equivalent uses of
|
@item{All uses of @racket[letrec] are removed and replaced with
|
||||||
@racket[let] and imperative features.}
|
equivalent uses of @racket[let] and imperative features.}
|
||||||
@item{The program is converted into @link["http://en.wikipedia.org/wiki/Administrative_normal_form"]{ANF} (Administrative Normal Form),
|
@item{The program is converted into @link["http://en.wikipedia.org/wiki/Administrative_normal_form"]{ANF} (Administrative Normal Form),
|
||||||
making all continuations explicit.}
|
making all continuations explicit.}
|
||||||
@item{All continuations and continuations marks are recorded in the
|
@item{All continuations and continuations marks are recorded in the
|
||||||
|
@ -22,41 +23,47 @@ A stateless servlet has the following process performed on it automatically:
|
||||||
@racket[lambda].}
|
@racket[lambda].}
|
||||||
]
|
]
|
||||||
|
|
||||||
This process allows the continuations captured by your servlet to be serialized.
|
This process allows the continuations captured by your servlet to be
|
||||||
This means they may be stored on the client's browser or the server's disk.
|
serialized. This means they may be stored on the client's browser or
|
||||||
|
the server's disk.
|
||||||
|
|
||||||
This means your servlet has no cost to the server other than execution. This is
|
This means your servlet has no cost to the server other than
|
||||||
very attractive if you've used Racket servlets and had memory problems.
|
execution. This is very attractive if you've used Racket servlets and
|
||||||
|
had memory problems.
|
||||||
|
|
||||||
This means your server can restart in the middle of a long running Web interaction
|
This means your server can restart in the middle of a long running Web
|
||||||
without the URLs that have been shared with the client expiring. This is
|
interaction without the URLs that have been shared with the client
|
||||||
very attractive if you've used Racket servlets and had session timeout problems.
|
expiring. This is very attractive if you've used Racket servlets and
|
||||||
|
had session timeout problems.
|
||||||
|
|
||||||
This process is defined on all of Racket and occurs after macro-expansion,
|
This process is defined on all of Racket and occurs after
|
||||||
so you are free to use all interesting features of Racket. However, there
|
macro-expansion, so you are free to use all interesting features of
|
||||||
are some considerations you must make.
|
Racket. However, there are some considerations you must make.
|
||||||
|
|
||||||
First, this process drastically changes the structure of your program. It
|
First, this process drastically changes the structure of your program.
|
||||||
will create an immense number of lambdas and structures your program
|
It will create an immense number of lambdas and structures your program
|
||||||
did not normally contain. The performance implication of this has not been
|
did not normally contain. The performance implication of this has not
|
||||||
studied with Racket.
|
been studied with Racket.
|
||||||
|
|
||||||
Second, the defunctionalization process is sensitive to the syntactic structure
|
Second, the defunctionalization process is sensitive to the syntactic
|
||||||
of your program. Therefore, if you change your program in a trivial way, for example,
|
structure of your program. Therefore, if you change your program in a
|
||||||
changing a constant, then all serialized continuations will be obsolete and will
|
trivial way, for example, changing a constant, then all serialized
|
||||||
error when deserialization is attempted. This is a feature, not a bug! It is a small
|
continuations will be obsolete and will error when deserialization is
|
||||||
price to pay for protection from the sorts of errors that would occur if your program
|
attempted. This is a feature, not a bug! It is a small price to pay for
|
||||||
|
protection from the sorts of errors that would occur if your program
|
||||||
were changed in a meaningful way.
|
were changed in a meaningful way.
|
||||||
|
|
||||||
Third, the values in the lexical scope of your continuations must be serializable
|
Third, the values in the lexical scope of your continuations must be
|
||||||
for the continuations itself to be serializable. This means that you must use
|
serializable for the continuations itself to be serializable. This means
|
||||||
@racket[define-serializable-struct] rather than @racket[define-struct], and take
|
that you must use @racket[define-serializable-struct] rather than
|
||||||
care to use modules that do the same. Similarly, you may not use @racket[parameterize],
|
@racket[define-struct], and take care to use modules that do the same.
|
||||||
because parameterizations are not serializable.
|
Similarly, you may not use @racket[parameterize], because
|
||||||
|
parameterizations are not serializable.
|
||||||
|
|
||||||
Fourth, and related, this process only runs on your code, not on the code you
|
Fourth, and related, this process only runs on your code, not on the
|
||||||
@racket[require]. Thus, your continuations---to be serializable---must not
|
code you @racket[require]. Thus, your continuations---to be
|
||||||
be in the context of another module. For example, the following will fail with an @as-index{"unsafe context"}
|
serializable---must not be in the context of another module. For
|
||||||
|
example, the following will fail with an @as-index{"unsafe context"}
|
||||||
exception:
|
exception:
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
|
|
|
@ -52,8 +52,9 @@ You can supply your own (built with these functions) when you write a stateless
|
||||||
@defproc[(stuffer-compose [g (stuffer/c any/c any/c)]
|
@defproc[(stuffer-compose [g (stuffer/c any/c any/c)]
|
||||||
[f (stuffer/c any/c any/c)])
|
[f (stuffer/c any/c any/c)])
|
||||||
(stuffer/c any/c any/c)]{
|
(stuffer/c any/c any/c)]{
|
||||||
Composes @racket[f] and @racket[g], i.e., applies @racket[f] then @racket[g] for @racket[in]
|
Composes @racket[f] and @racket[g], i.e., applies @racket[f] then
|
||||||
and @racket[g] then @racket[f] for @racket[out].
|
@racket[g] for @racket[in] and @racket[g] then @racket[f] for
|
||||||
|
@racket[out].
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(stuffer-sequence [f (stuffer/c any/c any/c)]
|
@defproc[(stuffer-sequence [f (stuffer/c any/c any/c)]
|
||||||
|
@ -65,9 +66,10 @@ You can supply your own (built with these functions) when you write a stateless
|
||||||
@defproc[(stuffer-if [c (bytes? . -> . boolean?)]
|
@defproc[(stuffer-if [c (bytes? . -> . boolean?)]
|
||||||
[f (stuffer/c bytes? bytes?)])
|
[f (stuffer/c bytes? bytes?)])
|
||||||
(stuffer/c bytes? bytes?)]{
|
(stuffer/c bytes? bytes?)]{
|
||||||
Creates a @tech{stuffer} that stuffs with @racket[f] if @racket[c] is true on the input
|
Creates a @tech{stuffer} that stuffs with @racket[f] if @racket[c] is
|
||||||
to @racket[in]. Similarly, applies @racket[f] during @racket[out] if it was applied during
|
true on the input to @racket[in]. Similarly, applies @racket[f] during
|
||||||
@racket[in] (which is recorded by prepending a byte.)
|
@racket[out] if it was applied during @racket[in] (which is recorded by
|
||||||
|
prepending a byte.)
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(stuffer-chain [x (or/c stuffer? (bytes? . -> . boolean?))]
|
@defproc[(stuffer-chain [x (or/c stuffer? (bytes? . -> . boolean?))]
|
||||||
|
@ -85,7 +87,8 @@ You can supply your own (built with these functions) when you write a stateless
|
||||||
@defmodule[web-server/stuffers/serialize]{
|
@defmodule[web-server/stuffers/serialize]{
|
||||||
|
|
||||||
@defthing[serialize-stuffer (stuffer/c serializable? bytes?)]{
|
@defthing[serialize-stuffer (stuffer/c serializable? bytes?)]{
|
||||||
A @tech{stuffer} that uses @racket[serialize] and @racket[write/bytes] and @racket[deserialize] and @racket[read/bytes].
|
A @tech{stuffer} that uses @racket[serialize] and @racket[write/bytes]
|
||||||
|
and @racket[deserialize] and @racket[read/bytes].
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -111,14 +114,16 @@ You can supply your own (built with these functions) when you write a stateless
|
||||||
@defthing[gzip-stuffer (stuffer/c bytes? bytes?)]{
|
@defthing[gzip-stuffer (stuffer/c bytes? bytes?)]{
|
||||||
A @tech{stuffer} that uses @racket[gzip/bytes] and @racket[gunzip/bytes].
|
A @tech{stuffer} that uses @racket[gzip/bytes] and @racket[gunzip/bytes].
|
||||||
|
|
||||||
@warning{You should compose this with @racket[base64-stuffer] to get URL-safe bytes.}
|
@warning{You should compose this with @racket[base64-stuffer] to get
|
||||||
|
URL-safe bytes.}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@section{Key/Value Storage}
|
@section{Key/Value Storage}
|
||||||
|
|
||||||
The @racketmodname[web-server/stuffers/hash] @tech{stuffers} rely on a key/value store.
|
The @racketmodname[web-server/stuffers/hash] @tech{stuffers} rely on a
|
||||||
|
key/value store.
|
||||||
|
|
||||||
@defmodule[web-server/stuffers/store]{
|
@defmodule[web-server/stuffers/store]{
|
||||||
|
|
||||||
|
@ -155,8 +160,10 @@ The @racketmodname[web-server/stuffers/hash] @tech{stuffers} rely on a key/value
|
||||||
@defproc[(hash-stuffer [H hash-fun/c]
|
@defproc[(hash-stuffer [H hash-fun/c]
|
||||||
[store store?])
|
[store store?])
|
||||||
(stuffer/c bytes? bytes?)]{
|
(stuffer/c bytes? bytes?)]{
|
||||||
A content-addressed storage @tech{stuffer} that stores input bytes, @racket[input], in @racket[store] with the key @racket[(H input)]
|
A content-addressed storage @tech{stuffer} that stores input bytes,
|
||||||
and returns the key. Similarly, on @racket[out] the original bytes are looked up.
|
@racket[input], in @racket[store] with the key @racket[(H input)] and
|
||||||
|
returns the key. Similarly, on @racket[out] the original bytes are
|
||||||
|
looked up.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(md5-stuffer [root path-string?])
|
@defproc[(md5-stuffer [root path-string?])
|
||||||
|
@ -172,24 +179,32 @@ The @racketmodname[web-server/stuffers/hash] @tech{stuffers} rely on a key/value
|
||||||
|
|
||||||
@defproc[(HMAC-SHA1 [kb bytes?] [db bytes?])
|
@defproc[(HMAC-SHA1 [kb bytes?] [db bytes?])
|
||||||
bytes?]{
|
bytes?]{
|
||||||
Performs a HMAC-SHA1 calculation on @racket[db] using @racket[kb] as the key. The result is guaranteed to be 20 bytes.
|
Performs a HMAC-SHA1 calculation on @racket[db] using @racket[kb] as
|
||||||
(You could curry this to use it with @racket[hash-stuffer], but there is little value in doing so over @racket[md5].)
|
the key. The result is guaranteed to be 20 bytes. (You could curry
|
||||||
|
this to use it with @racket[hash-stuffer], but there is little value
|
||||||
|
in doing so over @racket[md5].)
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(HMAC-SHA1-stuffer [kb bytes?])
|
@defproc[(HMAC-SHA1-stuffer [kb bytes?])
|
||||||
(stuffer/c bytes? bytes?)]{
|
(stuffer/c bytes? bytes?)]{
|
||||||
A @tech{stuffer} that signs input using @racket[HMAC-SHA1] with @racket[kb] as the key. The result of the @tech{stuffer} is
|
A @tech{stuffer} that signs input using @racket[HMAC-SHA1] with
|
||||||
the hash prepended to the input data. When the @tech{stuffer} is run in reverse, it checks if the first 20 bytes are the correct
|
@racket[kb] as the key. The result of the @tech{stuffer} is the hash
|
||||||
has for the rest of the data.
|
prepended to the input data. When the @tech{stuffer} is run in
|
||||||
|
reverse, it checks if the first 20 bytes are the correct has for the
|
||||||
|
rest of the data.
|
||||||
|
|
||||||
@warning{You should compose this with @racket[base64-stuffer] to get URL-safe bytes.}
|
@warning{You should compose this with @racket[base64-stuffer] to get
|
||||||
|
URL-safe bytes.}
|
||||||
|
|
||||||
@warning{Without explicit provision, it is possible for users to modify the continuations they are sent through the other @tech{stuffers}.
|
@warning{Without explicit provision, it is possible for users to
|
||||||
This @tech{stuffer} allows the servlet to certify that stuffed data was truly generated by the servlet. Therefore, you @bold{should} use this
|
modify the continuations they are sent through the other
|
||||||
if you are not using the @racket[hash-stuffer]s.}
|
@tech{stuffers}. This @tech{stuffer} allows the servlet to certify
|
||||||
|
that stuffed data was truly generated by the servlet. Therefore, you
|
||||||
|
@bold{should} use this if you are not using the
|
||||||
|
@racket[hash-stuffer]s.}
|
||||||
|
|
||||||
@warning{This @tech{stuffer} does @bold{not} encrypt the data in anyway, so users can still observe the stuffed values.}
|
@warning{This @tech{stuffer} does @bold{not} encrypt the data in
|
||||||
|
anyway, so users can still observe the stuffed values.}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -200,14 +215,17 @@ The @racketmodname[web-server/stuffers/hash] @tech{stuffers} rely on a key/value
|
||||||
|
|
||||||
@defproc[(is-url-too-big? [v bytes?])
|
@defproc[(is-url-too-big? [v bytes?])
|
||||||
boolean?]{
|
boolean?]{
|
||||||
Determines if stuffing @racket[v] into the current servlet's URL would result in a URL that is too big for Internet Explorer.
|
Determines if stuffing @racket[v] into the current servlet's URL would
|
||||||
(@link["http://www.boutell.com/newfaq/misc/urllength.html"]{IE only supports URLs up to 2048 characters.})
|
result in a URL that is too big for Internet Explorer.
|
||||||
|
(@link["http://www.boutell.com/newfaq/misc/urllength.html"]{IE only
|
||||||
|
supports URLs up to 2048 characters.})
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(make-default-stuffer [root path-string?])
|
@defproc[(make-default-stuffer [root path-string?])
|
||||||
(stuffer/c serializable? bytes?)]{
|
(stuffer/c serializable? bytes?)]{
|
||||||
Constructs a @tech{stuffer} that serializes, then if the URL is too big, compresses (and base64-encodes), if the URL is still too big
|
Constructs a @tech{stuffer} that serializes, then if the URL is too
|
||||||
then it stores it in an MD5-indexed database rooted at @racket[root].
|
big, compresses (and base64-encodes), if the URL is still too big then
|
||||||
|
it stores it in an MD5-indexed database rooted at @racket[root].
|
||||||
|
|
||||||
Equivalent to:
|
Equivalent to:
|
||||||
@racketblock[
|
@racketblock[
|
||||||
|
|
|
@ -36,7 +36,10 @@ This function accepts a servlet function and provides a function that accepts a
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
This facility is designed to be used in concert with a technique of extracting continuation URLs and relevant values; @racketmodname[xml/path] is one way to do this. Here is an extended example that tests an Add-Two-Numbers.com:
|
This facility is designed to be used in concert with a technique of
|
||||||
|
extracting continuation URLs and relevant values;
|
||||||
|
@racketmodname[xml/path] is one way to do this. Here is an extended
|
||||||
|
example that tests an Add-Two-Numbers.com:
|
||||||
@(require (for-label xml/path
|
@(require (for-label xml/path
|
||||||
rackunit
|
rackunit
|
||||||
racket/list
|
racket/list
|
||||||
|
|
|
@ -105,7 +105,12 @@ represented as an X-expression in Racket, by using
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
The HTML @tt{hello} is represented as @racket["hello"]. Strings are automatically escaped when output. This guarantees valid HTML. Therefore, the value @racket["<b>Unfinished tag"] is rendered as @tt{<b>Unfinished tag} not @tt{<b>Unfinished tag}. Similarly, @racket["<i>Finished tag</i>"] is rendered as @tt{<i>Finished tag</i>} not @tt{<i>Finished tag</i>}.
|
The HTML @tt{hello} is represented as @racket["hello"]. Strings are
|
||||||
|
automatically escaped when output. This guarantees valid HTML.
|
||||||
|
Therefore, the value @racket["<b>Unfinished tag"] is rendered as
|
||||||
|
@tt{<b>Unfinished tag} not @tt{<b>Unfinished tag}. Similarly,
|
||||||
|
@racket["<i>Finished tag</i>"] is rendered as
|
||||||
|
@tt{<i>Finished tag</i>} not @tt{<i>Finished tag</i>}.
|
||||||
|
|
||||||
@tt{<p>This is an example</p>} is
|
@tt{<p>This is an example</p>} is
|
||||||
|
|
||||||
|
|
|
@ -212,6 +212,7 @@ functions of interest for the servlet developer.
|
||||||
returns the instance id, continuation id, and nonce.
|
returns the instance id, continuation id, and nonce.
|
||||||
}
|
}
|
||||||
|
|
||||||
@defthing[servlet-prompt continuation-prompt-tag?]{The tag used for Web interaction continuation capture.}
|
@defthing[servlet-prompt continuation-prompt-tag?]{
|
||||||
|
The tag used for Web interaction continuation capture.}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,8 @@ Represents a location in an input stream.}
|
||||||
@defstruct[source ([start location/c]
|
@defstruct[source ([start location/c]
|
||||||
[stop location/c])]{
|
[stop location/c])]{
|
||||||
|
|
||||||
Represents a source location. Other structure types extend @racket[source].
|
Represents a source location. Other structure types extend
|
||||||
|
@racket[source].
|
||||||
|
|
||||||
When XML is generated from an input stream by @racket[read-xml],
|
When XML is generated from an input stream by @racket[read-xml],
|
||||||
locations are represented by @racket[location] instances. When XML
|
locations are represented by @racket[location] instances. When XML
|
||||||
|
@ -174,7 +175,8 @@ and a @racket[_misc] is an instance of the @racket[comment] or
|
||||||
@racket[p-i] structure types.}
|
@racket[p-i] structure types.}
|
||||||
|
|
||||||
@defthing[xexpr/c contract?]{
|
@defthing[xexpr/c contract?]{
|
||||||
A contract that is like @racket[xexpr?] except produces a better error message when the value is not an @tech{X-expression}.
|
A contract that is like @racket[xexpr?] except produces a better error
|
||||||
|
message when the value is not an @tech{X-expression}.
|
||||||
}
|
}
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue
Block a user