diff --git a/collects/web-server/dispatchers/dispatch-files.ss b/collects/web-server/dispatchers/dispatch-files.ss index 97232a6c3d..3153873f0b 100644 --- a/collects/web-server/dispatchers/dispatch-files.ss +++ b/collects/web-server/dispatchers/dispatch-files.ss @@ -7,13 +7,11 @@ (lib "plt-match.ss") (lib "contract.ss") (lib "uri-codec.ss" "net")) - (require (lib "pretty.ss")) (require "dispatch.ss" "../private/configuration.ss" "../private/util.ss" "../private/mime-types.ss" - "../private/request.ss" - "../private/servlet-helpers.ss" + "../request-structs.ss" "../private/response.ss" "../response-structs.ss") (provide/contract diff --git a/collects/web-server/dispatchers/dispatch-log.ss b/collects/web-server/dispatchers/dispatch-log.ss index d17a3e19ac..efff53ce68 100644 --- a/collects/web-server/dispatchers/dispatch-log.ss +++ b/collects/web-server/dispatchers/dispatch-log.ss @@ -6,8 +6,7 @@ (lib "plt-match.ss") (lib "contract.ss")) (require "dispatch.ss" - "../request-structs.ss" - "../private/servlet-helpers.ss") + "../request-structs.ss") (provide/contract [interface-version dispatcher-interface-version?]) (provide ; XXX contract kw diff --git a/collects/web-server/dispatchers/dispatch-passwords.ss b/collects/web-server/dispatchers/dispatch-passwords.ss index 1ed1a1c043..fe37d4225f 100644 --- a/collects/web-server/dispatchers/dispatch-passwords.ss +++ b/collects/web-server/dispatchers/dispatch-passwords.ss @@ -4,7 +4,8 @@ (require "dispatch.ss" "../private/util.ss" "../private/configuration.ss" - "../private/servlet-helpers.ss" + "../request-structs.ss" + "../private/basic-auth.ss" "../private/connection-manager.ss" "../private/response.ss") (provide/contract diff --git a/collects/web-server/private/basic-auth.ss b/collects/web-server/private/basic-auth.ss new file mode 100644 index 0000000000..d2b9047569 --- /dev/null +++ b/collects/web-server/private/basic-auth.ss @@ -0,0 +1,35 @@ +(module basic-auth mzscheme + (require (lib "contract.ss") + (lib "plt-match.ss") + (lib "base64.ss" "net")) + (require "../request-structs.ss") + + ; Authentication + ; extract-user-pass : (listof (cons sym bytes)) -> (or/c #f (cons str str)) + ;; Notes (GregP) + ;; 1. This is Basic Authentication (RFC 1945 SECTION 11.1) + ;; e.g. an authorization header will look like this: + ;; Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== + ;; 2. Headers should be read as bytes and then translated to unicode as appropriate. + ;; 3. The Authorization header should have bytes (i.e. (cdr pass-pair) is bytes + (define (extract-user-pass headers) + (match (headers-assq* #"Authorization" headers) + [#f #f] + [(struct header (_ basic-credentials)) + (cond + [(and (basic? basic-credentials) + (regexp-match #rx"([^:]*):(.*)" + (base64-decode (subbytes basic-credentials 6 (bytes-length basic-credentials))))) + => (lambda (user-pass) + (cons (cadr user-pass) (caddr user-pass)))] + [else #f])])) + + ;; basic?: bytes -> (or/c (listof bytes) #f) + ;; does the second part of the authorization header start with #"Basic " + (define basic? + (let ([rx (byte-regexp #"^Basic .*")]) + (lambda (a) (regexp-match rx a)))) + + (provide/contract + ; XXX contract maybe + [extract-user-pass ((listof header?) . -> . (or/c false/c (cons/c bytes? bytes?)))])) \ No newline at end of file diff --git a/collects/web-server/private/servlet-helpers.ss b/collects/web-server/private/servlet-helpers.ss index ab6110b032..73bdd627d1 100644 --- a/collects/web-server/private/servlet-helpers.ss +++ b/collects/web-server/private/servlet-helpers.ss @@ -2,13 +2,14 @@ (require (lib "contract.ss") (lib "kw.ss") (lib "plt-match.ss") - (lib "base64.ss" "net") (lib "uri-codec.ss" "net")) (require "util.ss" "bindings.ss" + "basic-auth.ss" "../request-structs.ss" "../response-structs.ss") (provide (all-from "bindings.ss") + (all-from "basic-auth.ss") (all-from "../response-structs.ss") (all-from "../request-structs.ss")) @@ -58,43 +59,11 @@ (pre ,(exn->string exn)))))))]) (thunk))) - ; Authentication - (define AUTHENTICATION-REGEXP (regexp "([^:]*):(.*)")) - (define (match-authentication x) (regexp-match AUTHENTICATION-REGEXP x)) - ;:(define match-authentication (type: (str -> (or/c false (list str str str))))) - - ; extract-user-pass : (listof (cons sym bytes)) -> (or/c #f (cons str str)) - ;; Notes (GregP) - ;; 1. This is Basic Authentication (RFC 1945 SECTION 11.1) - ;; e.g. an authorization header will look like this: - ;; Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== - ;; 2. Headers should be read as bytes and then translated to unicode as appropriate. - ;; 3. The Authorization header should have bytes (i.e. (cdr pass-pair) is bytes - (define (extract-user-pass headers) - (match (headers-assq* #"Authorization" headers) - [#f #f] - [(struct header (_ basic-credentials)) - (cond - [(and (basic? basic-credentials) - (match-authentication - (base64-decode (subbytes basic-credentials 6 (bytes-length basic-credentials))))) - => (lambda (user-pass) - (cons (cadr user-pass) (caddr user-pass)))] - [else #f])])) - - ;; basic?: bytes -> (or/c (listof bytes) #f) - ;; does the second part of the authorization header start with #"Basic " - (define basic? - (let ([rx (byte-regexp #"^Basic .*")]) - (lambda (a) (regexp-match rx a)))) - (provide ; all-from with-errors-to-browser redirect-to (rename uri-decode translate-escapes)) (provide/contract - ; XXX contract maybe - [extract-user-pass ((listof header?) . -> . (or/c false/c (cons/c bytes? bytes?)))] [permanently redirection-status?] [temporarily redirection-status?] [see-other redirection-status?] diff --git a/collects/web-server/servlet.ss b/collects/web-server/servlet.ss index 7532c5d202..5ea6750fc7 100644 --- a/collects/web-server/servlet.ss +++ b/collects/web-server/servlet.ss @@ -8,6 +8,11 @@ "private/servlet-helpers.ss" "private/web-cells.ss" "servlet-structs.ss") + (require "private/servlet-url.ss") + (provide (all-from "private/web-cells.ss") + (all-from "private/servlet-helpers.ss") + (all-from "private/servlet-url.ss") + (all-from "servlet-structs.ss")) ;; ************************************************************ ;; HELPERS @@ -39,13 +44,7 @@ [send/forward ((response-generator?) (expiration-handler?) . opt-> . request?)] [send/suspend/dispatch ((embed/url? . -> . servlet-response?) . -> . any/c)] [send/suspend/callback (xexpr/callback? . -> . any/c)]) - - (require "private/servlet-url.ss") - (provide (all-from "private/web-cells.ss") - (all-from "private/servlet-helpers.ss") - (all-from "private/servlet-url.ss") - (all-from "servlet-structs.ss")) - + ;; ************************************************************ ;; EXPORTS @@ -141,4 +140,4 @@ ; redirect/get : -> request (define redirect/get (make-redirect/get send/suspend)) - (define redirect/get/forget (make-redirect/get send/forward))) + (define redirect/get/forget (make-redirect/get send/forward))) \ No newline at end of file