[racket-dev] [plt] Push #23903: master branch updated

From: Jay McCarthy (jay at racket-lang.org)
Date: Wed Nov 23 13:02:31 EST 2011

Could you please comment on 7f9818b?

It changes URLs to be able to represent "there, but empty" query
components, but this changes the invariant that URL query components were
always lists, which I think is better than putting in extraneous ?s

Jay

On Wed, Nov 23, 2011 at 11:00 AM, <jay at racket-lang.org> wrote:

> jay has updated `master' from 6a99c93ebb to 9d8d36e568.
>  http://git.racket-lang.org/plt/6a99c93ebb..9d8d36e568
>
> =====[ 6 Commits ]======================================================
>
> Directory summary:
>  14.7% collects/net/
>  52.1% collects/tests/net/
>   5.7% collects/tests/plai/
>  15.4% collects/tests/web-server/pr/
>   6.8% collects/web-server/scribblings/
>   4.7% collects/web-server/
>
> ~~~~~~~~~~
>
> d64d620 Jay McCarthy <jay at racket-lang.org> 2011-11-23 09:44
> :
> | Fixing PR10485
> :
>  A collects/tests/plai/datatype-coverage.rkt
>
> ~~~~~~~~~~
>
> 7f9818b Jay McCarthy <jay at racket-lang.org> 2011-11-23 10:35
> :
> | This fixes 10497 and potentially breaks programs that assume the query
> of a URL is always a list. I have fixed uses in the Web Server, which I
> expect is the major thing affected, but much more could be. Therefore I am
> skeptical this is a good idea just for the representation of ?. So, I'd
> like other people to review the change and let me know if they think I
> should revert it.
> :
>  M collects/net/url.rkt                                         |   14 +-
>  M collects/net/url-structs.rkt                                 |    2 +-
>  M collects/tests/net/url.rkt                                   |   81
> ++++---
>  M collects/unstable/net/url.rkt                                |    2 +-
>  M collects/web-server/dispatch/syntax.rkt                      |    2 +-
>  M collects/web-server/http/request.rkt                         |    2 +-
>  M .../default-web-root/htdocs/lang-servlets/add01.rkt          |    4 +-
>
> ~~~~~~~~~~
>
> ccd5061 Jay McCarthy <jay at racket-lang.org> 2011-11-23 10:36
> :
> | Forgot to include doc change
> :
>  M collects/net/scribblings/url.scrbl |    2 +-
>
> ~~~~~~~~~~
>
> ce6eab6 Jay McCarthy <jay at racket-lang.org> 2011-11-23 10:50
> :
> | Showing that 10546 is fixed
> :
>  A collects/tests/web-server/pr/10546.rkt
>
> ~~~~~~~~~~
>
> 5bd12bb Jay McCarthy <jay at racket-lang.org> 2011-11-23 10:55
> :
> | Clarifying syntax in docs
> :
>  M collects/web-server/scribblings/templates.scrbl |    5 +++--
>
> ~~~~~~~~~~
>
> 9d8d36e Jay McCarthy <jay at racket-lang.org> 2011-11-23 10:58
> :
> | Demonstrating that 10772 is fixed
> :
>  M collects/tests/plai/datatype.rkt |    2 ++
>
> =====[ Overall Diff ]===================================================
>
> collects/net/scribblings/url.scrbl
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/collects/net/scribblings/url.scrbl
> +++ NEW/collects/net/scribblings/url.scrbl
> @@ -38,7 +38,7 @@ re-exported by @racketmodname[net/url].}
>                 [port (or/c false/c exact-nonnegative-integer?)]
>                 [path-absolute? boolean?]
>                 [path (listof path/param?)]
> -                [query (listof (cons/c symbol? (or/c false/c string?)))]
> +                [query (or/c false/c (listof (cons/c symbol? (or/c
> false/c string?))))]
>                 [fragment (or/c false/c string?)])]{
>
>  The basic structure for all URLs, which is explained in RFC 3986
>
> collects/net/url-structs.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/collects/net/url-structs.rkt
> +++ NEW/collects/net/url-structs.rkt
> @@ -13,7 +13,7 @@
>               [port (or/c false/c number?)]
>               [path-absolute? boolean?]
>               [path (listof path/param?)]
> -              [query (listof (cons/c symbol? (or/c string? false/c)))]
> +              [query (or/c false/c (listof (cons/c symbol? (or/c string?
> false/c))))]
>               [fragment (or/c false/c string?)]))
>  (struct path/param ([path (or/c string? (symbols 'up 'same))]
>                      [param (listof string?)])))
>
> collects/net/url.rkt
> ~~~~~~~~~~~~~~~~~~~~
> --- OLD/collects/net/url.rkt
> +++ NEW/collects/net/url.rkt
> @@ -76,7 +76,11 @@
>             ""))
>         (combine-path-strings (url-path-absolute? url) path)
>         ;; (if query (sa "?" (uri-encode query)) "")
> -        (if (null? query) "" (sa "?" (alist->form-urlencoded query)))
> +        (if query
> +            (if (null? query)
> +                "?"
> +                (sa "?" (alist->form-urlencoded query)))
> +            "")
>         (if fragment (sa "#" (uri-encode fragment)) ""))))
>
>  ;; url->default-port : url -> num
> @@ -259,7 +263,7 @@
>  ;; transliteration of code in rfc 3986, section 5.2.2
>  (define (combine-url/relative Base string)
>   (let ([R (string->url string)]
> -        [T (make-url #f #f #f #f #f '() '() #f)])
> +        [T (make-url #f #f #f #f #f '() #f #f)])
>     (if (url-scheme R)
>       (begin
>         (set-url-scheme! T (url-scheme R))
> @@ -283,7 +287,7 @@
>               (begin
>                 (set-url-path-absolute?! T (url-path-absolute? Base))
>                 (set-url-path! T (url-path Base))
> -                (if (not (null? (url-query R)))
> +                (if (url-query R)
>                   (set-url-query! T (url-query R))
>                   (set-url-query! T (url-query Base))))
>               (begin
> @@ -485,7 +489,7 @@
>               [path     (if win-file?
>                           (separate-windows-path-strings path)
>                           (separate-path-strings path))]
> -              [query    (if query (form-urlencoded->alist query) '())]
> +              [query    (if query (form-urlencoded->alist query) #f)]
>               [fragment (uri-decode/maybe fragment)])
>          (make-url scheme user host port abs? path query fragment))))
>    (cdr (or (regexp-match url-rx str)
> @@ -574,7 +578,7 @@
>                   (if (eq? base 'relative)
>                     accum
>                     (loop base accum)))])))])
> -    (make-url "file" #f "" #f (absolute-path? path) url-path '() #f)))
> +    (make-url "file" #f "" #f (absolute-path? path) url-path #f #f)))
>
>  (define (url->path url [kind (system-path-convention-type)])
>   (file://->path url kind))
>
> collects/tests/net/url.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/collects/tests/net/url.rkt
> +++ NEW/collects/tests/net/url.rkt
> @@ -1,6 +1,6 @@
>  #lang scheme
>  (require net/url tests/eli-tester
> -         (only-in net/uri-codec current-alist-separator-mode))
> +         (only-in net/uri-codec current-alist-separator-mode uri-encode))
>
>  (define (url->vec url)
>   (vector
> @@ -50,29 +50,29 @@
>      (current-proxy-servers))
>    => '(("http" "proxy.com" 3128)))
>
> -  (test-s->u #(#f #f #f #f #t (#("")) () #f)
> +  (test-s->u #(#f #f #f #f #t (#("")) #f #f)
>              "/")
> -  (test-s->u #(#f #f #f #f #f () () #f)
> +  (test-s->u #(#f #f #f #f #f () #f #f)
>              "")
>
> -  (test-s->u #("http" #f #f #f #t (#("")) () #f)
> +  (test-s->u #("http" #f #f #f #t (#("")) #f #f)
>              "http:/")
>
> -  (test-s->u #("http" #f "" #f #t (#("")) () #f)
> +  (test-s->u #("http" #f "" #f #t (#("")) #f #f)
>              "http:///")
>
> -  (test-s->u #("http" #f "www.drscheme.org" #f #f () () #f)
> +  (test-s->u #("http" #f "www.drscheme.org" #f #f () #f #f)
>              "http://www.drscheme.org")
> -  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("")) () #f)
> +  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("")) #f #f)
>              "http://www.drscheme.org/")
>
> -  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a") #("b") #("c"))
> () #f)
> +  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a") #("b") #("c"))
> #f #f)
>              "http://www.drscheme.org/a/b/c")
> -  (test-s->u #("http" "robby" "www.drscheme.org" #f #t (#("a") #("b")
> #("c")) () #f)
> +  (test-s->u #("http" "robby" "www.drscheme.org" #f #t (#("a") #("b")
> #("c")) #f #f)
>              "http:[email protected]/a/b/c")
> -  (test-s->u #("http" #f "www.drscheme.org" 8080 #t (#("a") #("b")
> #("c")) () #f)
> +  (test-s->u #("http" #f "www.drscheme.org" 8080 #t (#("a") #("b")
> #("c")) #f #f)
>              "http://www.drscheme.org:8080/a/b/c")
> -  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a") #("b") #("c"))
> () "joe")
> +  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a") #("b") #("c"))
> #f "joe")
>              "http://www.drscheme.org/a/b/c#joe")
>   (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a") #("b") #("c"))
> ((tim . "")) #f)
>              "http://www.drscheme.org/a/b/c?tim=")
> @@ -90,53 +90,53 @@
>   (parameterize ([current-alist-separator-mode 'amp])
>     (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a") #("b")
> #("c")) ((tam . "tom") (pam . "pom")) "joe")
>                "http://www.drscheme.org/a/b/c?tam=tom&pam=pom#joe"))
> -  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a") #("b") #("c"
> "b")) () #f)
> +  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a") #("b") #("c"
> "b")) #f #f)
>              "http://www.drscheme.org/a/b/c;b")
> -  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a" "x") #("b")
> #("c" "b")) () #f)
> +  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a" "x") #("b")
> #("c" "b")) #f #f)
>              "http://www.drscheme.org/a;x/b/c;b")
>
>   ;; test unquoting for %
>   (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a") #("b") #("c"))
> ((ti#m . "")) "jo e")
>              "http://www.drscheme.org/a/b/c?ti%23m=#jo%20e")
> -  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a " " a") #(" b ")
> #(" c ")) () #f)
> +  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a " " a") #(" b ")
> #(" c ")) #f #f)
>              "http://www.drscheme.org/a%20;%20a/%20b%20/%20c%20")
> -  (test-s->u #("http" "robb y" "www.drscheme.org" #f #t (#("")) () #f)
> +  (test-s->u #("http" "robb y" "www.drscheme.org" #f #t (#("")) #f #f)
>              "http:[email protected]/")
> -  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("%a") #("b/")
> #("c")) () #f)
> +  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("%a") #("b/")
> #("c")) #f #f)
>              "http://www.drscheme.org/%25a/b%2F/c")
> -  (test-s->u #("http" "robby:password" "www.drscheme.org" #f #t (#(""))
> () #f)
> +  (test-s->u #("http" "robby:password" "www.drscheme.org" #f #t (#(""))
> #f #f)
>              "http://robby:[email protected]/")
>   (test "robby:password" (lambda (x) (url-user (string->url x))) "
> http:[email protected]/")
>
>   ;; test the characters that need to be encoded in paths vs those that do
> not need to
>   ;; be encoded in paths
> -  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a:@!$&'()*+,=z")
> #("/?#[];") #("")) () #f)
> +  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("a:@!$&'()*+,=z")
> #("/?#[];") #("")) #f #f)
>              "http://www.drscheme.org/a:@!$&'()*+,=z/%2F%3F%23%5B%5D%3B/")
>
> -  (test-s->u #("http" #f "www.drscheme.org" #f #t (#(".") #("..")
> #(same) #(up) #("...") #("abc.def")) () #f)
> +  (test-s->u #("http" #f "www.drscheme.org" #f #t (#(".") #("..")
> #(same) #(up) #("...") #("abc.def")) #f #f)
>              "http://www.drscheme.org/%2e/%2e%2e/./../.../abc.def")
> -  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("." "") #(".." "")
> #(same "") #(up "") #("..." "") #("abc.def" "")) () #f)
> +  (test-s->u #("http" #f "www.drscheme.org" #f #t (#("." "") #(".." "")
> #(same "") #(up "") #("..." "") #("abc.def" "")) #f #f)
>              "http://www.drscheme.org/%2e;/%2e%2e;/.;/..;/...;/abc.def;")
>
>   ;; test other scheme identifiers
> -  (test-s->u #("blah" #f "www.foo.com" #f #t (#("")) () #f)
> +  (test-s->u #("blah" #f "www.foo.com" #f #t (#("")) #f #f)
>              "blah://www.foo.com/")
> -  (test-s->u #("blah99" #f "www.foo.com" #f #t (#("")) () #f)
> +  (test-s->u #("blah99" #f "www.foo.com" #f #t (#("")) #f #f)
>              "blah99://www.foo.com/")
> -  (test-s->u #("blah+" #f "www.foo.com" #f #t (#("")) () #f)
> +  (test-s->u #("blah+" #f "www.foo.com" #f #t (#("")) #f #f)
>              "blah+://www.foo.com/")
> -  (test-s->u #("a+b-c456.d" #f "www.foo.com" #f #t (#("")) () #f)
> +  (test-s->u #("a+b-c456.d" #f "www.foo.com" #f #t (#("")) #f #f)
>              "a+b-c456.d://www.foo.com/")
>
>   ;; a colon and other junk (`sub-delims') can appear in usernames
> -  (test #("http" "x:!$&'()*+,;=y" "www.drscheme.org" #f #t (#("a")) ()
> #f)
> +  (test #("http" "x:!$&'()*+,;=y" "www.drscheme.org" #f #t (#("a")) #f
> #f)
>         string->url/vec
>         "http://x:!$&'()*+,;=y at www.drscheme.org/a")
>   ;; a colon and atsign can appear in absolute paths
> -  (test-s->u #(#f #f #f #f #t (#("x:@y") #("z")) () #f)
> +  (test-s->u #(#f #f #f #f #t (#("x:@y") #("z")) #f #f)
>              "/x:@y/z")
>   ;; and in relative paths as long as it's not in the first element
> -  (test-s->u #(#f #f #f #f #f (#("x") #("y:@z")) () #f)
> +  (test-s->u #(#f #f #f #f #f (#("x") #("y:@z")) #f #f)
>              "x/y:@z")
>
>   ;; test bad schemes
> @@ -148,38 +148,38 @@
>    (string->url "a b://www.foo.com/") =error> url-exception?)
>
>   ;; test file: urls
> -  (test-s->u #("file" #f "" #f #t (#("abc") #("def.html")) () #f)
> +  (test-s->u #("file" #f "" #f #t (#("abc") #("def.html")) #f #f)
>              "file:///abc/def.html")
>   (test (url->string (string->url "file:///abc/def.html"))
>         => "file:///abc/def.html")
>   (parameterize ([file-url-path-convention-type 'unix])
>     (test (url->string (string->url "file://a/b"))
>           => "file://a/b")
> -    (test-s->u #("file" #f "localhost" #f #t (#("abc") #("def.html")) ()
> #f)
> +    (test-s->u #("file" #f "localhost" #f #t (#("abc") #("def.html")) #f
> #f)
>                "file://localhost/abc/def.html"))
>
>   ;; test files: urls with colons, and the different parsing on Windows
> -  (test-s->u #("file" #f "localhost" 123 #t (#("abc") #("def.html")) ()
> #f)
> +  (test-s->u #("file" #f "localhost" 123 #t (#("abc") #("def.html")) #f
> #f)
>              "file://localhost:123/abc/def.html")
>   (parameterize ([file-url-path-convention-type 'unix])
>     ;; different parse for file://foo:/...
>     (test (string->url/vec "file://foo:/abc/def.html")
> -          => #("file" #f "foo" #f #t (#("abc") #("def.html")) () #f)))
> +          => #("file" #f "foo" #f #t (#("abc") #("def.html")) #f #f)))
>   (parameterize ([file-url-path-convention-type 'windows])
>     (test (string->url/vec "file://foo:/abc/def.html")
> -          => #("file" #f "" #f #t (#("foo:") #("abc") #("def.html")) ()
> #f)
> +          => #("file" #f "" #f #t (#("foo:") #("abc") #("def.html")) #f
> #f)
>           (string->url/vec "file://c:/abc/def.html")
> -          => #("file" #f "" #f #t (#("c:") #("abc") #("def.html")) () #f)
> +          => #("file" #f "" #f #t (#("c:") #("abc") #("def.html")) #f #f)
>           (string->url/vec "file:\\\\d\\c\\abc\\def.html")
> -          => #("file" #f "" #f #t (#("") #("d") #("c") #("abc")
> #("def.html")) () #f)))
> +          => #("file" #f "" #f #t (#("") #("d") #("c") #("abc")
> #("def.html")) #f #f)))
>
>   (parameterize ([file-url-path-convention-type 'unix])
>     ;; but no effect on http://foo:/...
>     (test (string->url/vec "http://foo:/abc/def.html")
> -          => #("http" #f "foo" #f #t (#("abc") #("def.html")) () #f)))
> +          => #("http" #f "foo" #f #t (#("abc") #("def.html")) #f #f)))
>   (parameterize ([file-url-path-convention-type 'windows])
>     (test (string->url/vec "http://foo:/abc/def.html")
> -          => #("http" #f "foo" #f #t (#("abc") #("def.html")) () #f)))
> +          => #("http" #f "foo" #f #t (#("abc") #("def.html")) #f #f)))
>
>   (test (url->string (path->url (bytes->path #"c:\\a\\b" 'windows)))
>         => "file:///c:/a/b"
> @@ -228,7 +228,7 @@
>          "HTTP:[email protected]:80/INDEX.HTML;XXX?T=P#YYY")
>         => #("http" "ROBBY" "www.drscheme.org" 80 #t (#("INDEX.HTML"
> "XXX")) ((T . "P")) "YYY"))
>
> -  (test-s->u #("mailto" #f #f #f #f (#("robby at racket-lang.org")) () #f)
> +  (test-s->u #("mailto" #f #f #f #f (#("robby at racket-lang.org")) #f #f)
>              "mailto:robby at racket-lang.org")
>
>   (test (string->url/vec "http://www.drscheme.org?bar=馨慧")
> @@ -238,7 +238,7 @@
>         => #("http" #f "www.drscheme.org" #f #f () ((bár . "é")) #f))
>
>   (test-c-u/r "http://www.drscheme.org"
> -              (make-url #f #f #f #f #f '() '() #f)
> +              (make-url #f #f #f #f #f '() #f #f)
>               "http://www.drscheme.org")
>
>   (test-c-u/r "http://www.drscheme.org"
> @@ -351,6 +351,11 @@
>
>      ))
>
> +  ;; PR 10497
> +  (test
> +   (url->string (url #f #f #f #f #f empty empty #f)) => "?"
> +   (url->string (url #f #f #f #f #f empty #f #f)) => "")
> +
>   )
>
>  (provide tests)
>
> collects/tests/plai/datatype-coverage.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- /dev/null
> +++ NEW/collects/tests/plai/datatype-coverage.rkt
> @@ -0,0 +1,11 @@
> +#lang plai
> +;; RE: PR10485
> +(define-type toy
> +  [airplane (lift number?) (name string?)])
> +
> +(type-case toy (airplane 3412 "the bat!")
> +  [airplane (lift name) (+ lift 13)])
> +
> +;; The body of this function should be the only red in the file
> +(define (f x)
> +  (+ 1 1))
> \ No newline at end of file
>
> collects/tests/plai/datatype.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/collects/tests/plai/datatype.rkt
> +++ NEW/collects/tests/plai/datatype.rkt
> @@ -57,4 +57,6 @@
>  (type-case "foo" "bar") =error> "this must be a type defined with
> define-type"
>
>  (type-case + "bar") =error> "this must be a type defined with define-type"
> +
> + (type-case #f [x () 1]) =error> "this must be a type defined with
> define-type"
>  )
>
> collects/tests/web-server/pr/10546.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- /dev/null
> +++ NEW/collects/tests/web-server/pr/10546.rkt
> @@ -0,0 +1,55 @@
> +#lang racket
> +
> +(define here (current-directory))
> +(define txt (build-path here "some.txt"))
> +
> +(with-output-to-file txt
> +  #:exists 'replace
> +  (lambda ()
> +    (display #<<END
> +Here is some text that looks at @this
> +END
> +  )))
> +
> +(with-output-to-file "relative.rkt"
> +  #:exists 'replace
> +  (lambda ()
> +    (display #<<END
> +#lang racket
> +(require web-server/templates)
> +(provide ans)
> +
> +(define this 5)
> +(define ans (include-template "some.txt"))
> +END
> +  )))
> +
> +(with-output-to-file "absolute.rkt"
> +  #:exists 'replace
> +  (lambda ()
> +    (display #<<END
> +#lang racket
> +(require web-server/templates)
> +(provide ans)
> +
> +(define this 5)
> +(define ans (include-template (file "
> +END
> +  )
> +
> + (display (path->string txt))
> +
> +(display #<<END
> +")))
> +END
> +)))
> +
> +(require tests/eli-tester)
> +(define rel (dynamic-require "relative.rkt" 'ans))
> +(define abs (dynamic-require "absolute.rkt" 'ans))
> +(test
> +  rel => abs
> +  rel => "Here is some text that looks at 5")
> +
> +
> +
>
> collects/unstable/net/url.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/collects/unstable/net/url.rkt
> +++ NEW/collects/unstable/net/url.rkt
> @@ -20,7 +20,7 @@
>      (url-port in-url)
>      (url-path-absolute? in-url)
>      new-path
> -     empty
> +     #f
>      (url-fragment in-url))))
>  ;; Eli: if it also removes the query, this it's a bad name, and it's
>  ;;   questionable whether it is general enough.  Why not make it into a
>
> collects/web-server/default-web-root/htdocs/lang-servlets/add01.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/collects/web-server/default-web-root/htdocs/lang-servlets/add01.rkt
> +++ NEW/collects/web-server/default-web-root/htdocs/lang-servlets/add01.rkt
> @@ -8,7 +8,7 @@
>   (let* ([uri (request-uri req)]
>          [qry (url-query uri)])
>     (cond
> -      [(assoc 'second qry)
> +      [(and qry (assoc 'second qry))
>        => (lambda (a-pair)
>             (response/xexpr
>              `(html (head (title "Answer Page"))
> @@ -17,7 +17,7 @@
>                      (p ,(format "The answer is: ~a"
>                                  (+ (string->number (cdr a-pair))
>                                     (string->number (cdr (assoc 'first
> qry))))))))))]
> -      [(assoc 'first qry)
> +      [(and qry (assoc 'first qry))
>        => (lambda (a-pair)
>             (response/xexpr
>              `(html (head (title "Second Page"))
>
> collects/web-server/dispatch/syntax.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/collects/web-server/dispatch/syntax.rkt
> +++ NEW/collects/web-server/dispatch/syntax.rkt
> @@ -16,7 +16,7 @@
>                  (list (make-path/param "" empty))
>                  (map (lambda (s) (make-path/param s empty))
>                       strlist))
> -             empty #f)))
> +             #f #f)))
>
>  (define-syntax (dispatch-case stx)
>   (syntax-case stx (else)
>
> collects/web-server/http/request.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/collects/web-server/http/request.rkt
> +++ NEW/collects/web-server/http/request.rkt
> @@ -177,7 +177,7 @@
>                                    (make-binding:form (string->bytes/utf-8
> (symbol->string k))
>                                                       (string->bytes/utf-8
> v))
>                                    #f)])
> -                            (url-query uri))))
> +                            (or (url-query uri) empty))))
>              #f)]
>     [(bytes-ci=? #"POST" meth)
>      (local
>
> collects/web-server/scribblings/templates.scrbl
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/collects/web-server/scribblings/templates.scrbl
> +++ NEW/collects/web-server/scribblings/templates.scrbl
> @@ -2,6 +2,7 @@
>  @(require "web-server.rkt")
>  @(require (for-label web-server/servlet
>                      web-server/templates
> +                     racket/include
>                      racket/promise
>                      racket/list
>                      xml))
> @@ -358,8 +359,8 @@ the template to be unescaped, then create a
> @racket[cdata] structure:
>
>  @section{API Details}
>
> - at defform[(include-template path)]{
> - Compiles the template at @racket[path] using the @at-reader-ref syntax
> within the enclosing lexical context.
> + at defform[(include-template path-spec)]{
> + Compiles the template at @racket[path-spec] using the @at-reader-ref
> syntax within the enclosing lexical context. The @racket[path-spec] is the
> same format used by @racket[include].
>
>  Example:
>  @racketblock[
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20111123/798a19d9/attachment.html>

Posted on the dev mailing list.