diff --git a/scheme/lib/url.scm b/scheme/lib/url.scm index 6a26987..b0385d7 100644 --- a/scheme/lib/url.scm +++ b/scheme/lib/url.scm @@ -43,6 +43,12 @@ ;;; Request-URI = ( http_URL | abs_path ["?" query] ) ["#" fragment] +;;; Note: we don't have to support Request-URIS of the form "*" or +;;; authority, because these are not used with the any of the methods +;;; HEAD, GET and POST, which are the only methods we implement so +;;; far. + + ;;; Here we depart from the RFCs: ;;; RFC 2616 and 1945 disallow a #fragment-suffix of the Request-URI. ;;; For compatibility with buggy clients we _do_ allow for it. @@ -159,7 +165,8 @@ ;;; If there's no abs_path given, or abs_path is "/", path is the empty list; ;;; otherwise it is a list containing the path's segments. ;;; -;;; don't decode yet! + +;;; Caution: parse-url doesn't unescape anything yet! (define (parse-url request-uri) (cond @@ -214,36 +221,33 @@ ;;; ;;; The PATH slot is the Request_URI's path split at slashes ;;; (e.g., "/foo///bar//baz/" => ("foo" "bar" "baz")) -;;; and decoded. +;;; and unescaped. ;;; -;;; The QUERY slot is a decoded non-empty-string or #f. +;;; The QUERY slot is an non-empty-string, still in its escaped +;;; representation, or #f. + +;;; Caution: the path slot of a http-url record has already been +;;; UNESCAPED; don't unescape it a second time! +;;; The query slot is still in its escaped representation. (define-record-type http-url :http-url (make-http-url host port path query) http-url? (host http-url-host) (port http-url-port) - (path http-url-path) + (path http-url-path) (query http-url-query)) -;;; decode various parts of the Request_URI as returned by PARSE-URL; -;;; returns a HTTP-URL record. - -(define (parsed-uri->http-url host port path query) - - (let ((portnumber (and port (string->number port))) - (decoded-path (map unescape path)) - (decoded-query (and query (unescape query)))) - - (make-http-url host portnumber decoded-path decoded-query))) - ;;; parse a HTTP 1.1. Request_URI into a http-url record (define (url-string->http-url uri-string) - (call-with-values - (lambda () (parse-url uri-string)) - parsed-uri->http-url)) + (receive (host port path query) + (parse-url uri-string) + (let ((portnumber (and port (string->number port))) + (unescaped-path (map unescape path))) + (make-http-url host portnumber unescaped-path query)))) + ;;; Unparse a http-url record into its corresponding Request_URI @@ -271,7 +275,7 @@ (query (http-url-query http-url)) (query-string (if query - (string-append "?" (escape-query query)) + (string-append "?" query) ""))) (string-append scheme-and-host-string port-string path-string query-string))) @@ -309,6 +313,10 @@ (define (escape-query query) (escape query query-reserved-and-excluded)) +;;; encode something we don't know: escape all but the unreserved characters. +(define (escape-not-unreserved-chars something) + (escape something (rx (~ ,unreserved)))) + ;; Appendix A of RFC 2396 ;; ;A. Collected BNF for URI