doc and test in support of racket/racket PR 1080

This commit is contained in:
Tim Brown 2015-10-19 15:06:18 +01:00 committed by Matthew Flatt
parent 43742a9205
commit ef8f42f5b0
2 changed files with 181 additions and 32 deletions

View File

@ -469,14 +469,18 @@ particular, it is closed if @racket[handle] raises an exception, or if
the connection process is interruped by an asynchronous break the connection process is interruped by an asynchronous break
exception.} exception.}
@defparam[current-proxy-servers mapping (listof (list/c string? string? (integer-in 0 65535)))]{ @deftogether[(
@defparam[current-proxy-servers mapping (listof (list/c string? string? (integer-in 0 65535)))]
@defthing[proxiable-url-schemes (listof string?) #:value '("http")]
)]{
A parameter that determines a mapping of proxy servers used for The @racket[current-proxy-servers] parameter determines a mapping of proxy servers used for
connections. Each mapping is a list of three elements: connections. Each mapping is a list of three elements:
@itemize[ @itemize[
@item{the URL scheme, such as @racket["http"];} @item{the URL scheme, such as @racket["http"]; @racket[proxiable-url-schemes] lists the URL schemes
that can be proxied. Currently, the only proxiable scheme is @racket["http"].}
@item{the proxy server address; and} @item{the proxy server address; and}
@ -484,16 +488,17 @@ connections. Each mapping is a list of three elements:
] ]
Currently, the only proxiable scheme is @racket["http"]. @racket[current-proxy-servers] can be configured from the environment. If
it has no entry for a particular URL scheme, then the environment
variables @litchar["plt_http_proxy"] and @litchar["http_proxy"] are used. This is done via a promise
that is forced by @racket[proxy-server-for].
The environment variable @litchar["PLT_HTTP_PROXY"] can by used to set The environment variables contain a single URL of the form:
an initial value for @racket[current-proxy-servers]. It contains a @litchar{http://hostname:portno}. If any other components of the URL are provided,
single URL of the form: @litchar{http://hostname:portno}. If any other an error will be logged to the @racket[net/url] logger.
components of the URL are provided, an error will be logged to the
@racket[net/url] logger.
The default mapping (or the mapping if @litchar["PLT_HTTP_PROXY"] is The default mapping is the empty list (i.e., no proxies).
not a valid URL) is the empty list (i.e., no proxies).} }
@defparam[current-no-proxy-servers dest-hosts-list (listof (or/c string? regexp?))]{ @defparam[current-no-proxy-servers dest-hosts-list (listof (or/c string? regexp?))]{
@ -501,43 +506,61 @@ A parameter that determines which servers will be accessed directly
i.e. without resort to @racket[current-proxy-servers]. It is a list of: i.e. without resort to @racket[current-proxy-servers]. It is a list of:
@itemize[ @itemize[
@item{strings that match host names exactly} @item{strings that match host names exactly}
@item{regexps that match host by pattern} @item{regexps that match host by pattern}
] ]
If a proxy server is defined for a URL scheme, then the destination If a proxy server is defined for a URL scheme, then the destination
host name is checked against @[current-no-proxy-servers]. The proxy host name is checked against @racket[current-no-proxy-servers]. The proxy
is used if and only if the host name does not match (by the definition is used if and only if the host name does not match (by the definition
above) any in the list. above) any in the list.
The environment variable @litchar["PLT_NO_PROXY"] can by used to set @racket[current-no-proxy-servers] can be configured from the environment.
an initial value for @racket[current-no-proxy-servers]. It is a The environment variables @litchar["plt_no_proxy"] and @litchar["no_proxy"]
comma-separated list of ``patterns''. A pattern from the environment are used. This is done via a promise that is forced by @racket[proxy-server-for].
variable is one of:
These environment variables are comma-separated list of ``patterns''.
A pattern from an environment variable is one of:
@itemize[ @itemize[
@item{a string beginning with a @litchar{.} . This is converted to a
@item{a string beginning with a @litchar{.} (period). This is converted to a
regexp which performs a suffix match on a destination host name, regexp which performs a suffix match on a destination host name,
e.g. @litchar[.racket-lang.org] will match destinations of e.g. @litchar[".racket-lang.org"] will match destinations of
@litchar[doc.racket-lang.org], @litchar[pkgs.racket-lang.org], but @litchar["doc.racket-lang.org"], @litchar["pkgs.racket-lang.org"], but
neither @litchar[doc.bracket-lang.org] nor neither @litchar["doc.bracket-lang.org"] nor
@litchar[pkgs.racket-lang.org.uk]. @litchar["pkgs.racket-lang.org.uk"].
@margin-note{This is consistent with the @litchar["NO_PROXY"] environment @margin-note{This is consistent with the @litchar["no_proxy"] environment
variable used by other programs, albeit not consistent with the regexps variable used by other software, albeit not consistent with the regexps
stored in @racket[current-no-proxy-servers]} stored in @racket[current-no-proxy-servers]}
} }
@item{any other string -- is kept as a string to be matched exactly}
] @item{any other string -- is converted to a regexp which matches the string exactly}
} ]}
@defproc[(proxy-server-for @defproc[(proxy-server-for
[url-schm string?] [url-schm string?]
[dest-host-name (or/c false/c string?) #f]) [dest-host-name (or/c false/c string?) #f])
(list/c string? string? (integer-in 0 65535))]{ (list/c string? string? (integer-in 0 65535))]{
Returns the proxy server entry for the combination of @racket[url-schm] and @racket[host], or Returns the proxy server entry for the combination of @racket[url-schm]
@racket[#f] if no proxy is to be used. and @racket[host], or @racket[#f] if no proxy is to be used.
}
The process that loads environment variables into @racket[current-proxy-servers]
and @racket[current-no-proxy-servers] is held on a promise that is forced by
@racket[proxy-server-for]. This means that:
@itemize[
@item{calling @racket[proxy-server-for] might change the list of
@racket[current-proxy-servers] and @racket[current-no-proxy-servers]}
@item{to resolve proxy/no-proxy values from the environment, call @racket[(proxy-server-for #f)]}
]}
@defproc[(url-exception? [x any/c]) @defproc[(url-exception? [x any/c])
boolean?]{ boolean?]{

View File

@ -1,13 +1,139 @@
#lang racket #lang racket
(require net/url tests/eli-tester) (require net/url
tests/eli-tester)
(provide tests) (provide tests)
(module+ main (test do (tests))) (module+ main (test do (tests)))
(define (tests) (define (tests)
(define envar-stash (environment-variables-copy (current-environment-variables)))
(define (test-proxy-server-for #:current-proxy-servers [current-proxy-servers-val #f]
#:current-no-proxy-servers [current-no-proxy-servers-val #f]
schema
(host #f)
#:plt-http-proxy (plt-http-proxy #f)
#:http-proxy (http-proxy #f)
#:plt-no-proxy (plt-no-proxy #f)
#:no-proxy (no-proxy #f))
(parameterize ([current-environment-variables envar-stash]
[current-namespace (make-base-namespace)])
(define (put! name val)
(environment-variables-set! envar-stash
(string->bytes/locale name)
(and val (string->bytes/locale val))))
(put! "plt_http_proxy" plt-http-proxy)
(put! "http_proxy" http-proxy)
(put! "plt_no_proxy" plt-no-proxy)
(put! "no_proxy" no-proxy)
(eval '(require net/url))
(eval `(parameterize (,@(if current-proxy-servers-val
`([current-proxy-servers (quote ,current-proxy-servers-val)])
null)
,@(if current-no-proxy-servers-val
`([current-no-proxy-servers (quote ,current-no-proxy-servers-val)])
null))
(proxy-server-for ,schema ,host)))))
(test (test
;; Test the current-proxy-servers parameter can be set ;; Test the current-proxy-servers parameter can be set
(parameterize ([current-proxy-servers '(("http" "proxy.com" 3128))]) (parameterize ([current-proxy-servers '(("http" "proxy.com" 3128))])
(current-proxy-servers)) (current-proxy-servers))
=> '(("http" "proxy.com" 3128)))) => '(("http" "proxy.com" 3128))
;; we have at least http
(member "http" proxiable-url-schemes)
;; by default, there are no proxy servers
(test-proxy-server-for "http") => #f
;; current-no-proxy-servers converts incoming strings to anchored regexps
(parameterize ([current-no-proxy-servers (list "test.racket-lang.org"
#rx".*\\.racket-lang\\.org")])
(current-no-proxy-servers))
=> '(#rx"^test\\.racket-lang\\.org$"
#rx".*\\.racket-lang\\.org")
;; ------------------------------------------------------------------
;; Test Proxy Servers (loading from environment and proxy-server-for)
;; proxy servers set in current-proxy-servers are not overridden by environment
(test-proxy-server-for #:current-proxy-servers '(("http" "proxy.com" 3128))
#:plt-http-proxy "http://proxy.net:1234"
#:http-proxy "http://proxy.net:1234"
"http" "test.racket-lang.org")
=> '("http" "proxy.com" 3128)
;; plt_http_proxy is is prioritised over http_proxy
(test-proxy-server-for #:plt-http-proxy "http://proxy.net:3128"
#:http-proxy "http://proxy.net:3228"
"http" "test.racket-lang.org")
=> '("http" "proxy.net" 3128)
;; otherwise fall back to http_proxy
(test-proxy-server-for #:http-proxy "http://proxy.net:3228"
"http" "test.racket-lang.org")
=> '("http" "proxy.net" 3228)
;; ---------------------------------------------------------------------
;; Test NO Proxy Servers (loading from environment and proxy-server-for)
;; no proxy servers accumulate (they don't override), so test each one
;; being inserted in turn
;; prove that we need a proxy if not otherwise told...
(test-proxy-server-for #:current-proxy-servers '(("http" "proxy.com" 3128))
"http" "test.racket-lang.org")
=> '("http" "proxy.com" 3128)
(test-proxy-server-for #:current-proxy-servers '(("http" "proxy.com" 3128))
#:current-no-proxy-servers '("test.racket-lang.org")
"http" "test.racket-lang.org")
=> #f
(test-proxy-server-for #:current-proxy-servers '(("http" "proxy.com" 3128))
#:plt-no-proxy "test.racket-lang.org"
"http" "test.racket-lang.org")
=> #f
(test-proxy-server-for #:current-proxy-servers '(("http" "proxy.com" 3128))
#:no-proxy "test.racket-lang.org"
"http" "test.racket-lang.org")
=> #f
;; Pattern matching
;; prove that we need a proxy if not otherwise told...
(test-proxy-server-for #:current-proxy-servers '(("http" "proxy.com" 3128))
#:current-no-proxy-servers '(#rx".racket-lang.org")
"http" "test.racket-lang.org")
=> #f
(test-proxy-server-for #:current-proxy-servers '(("http" "proxy.com" 3128))
#:plt-no-proxy ".racket-lang.org"
"http" "test.racket-lang.org")
=> #f
(test-proxy-server-for #:current-proxy-servers '(("http" "proxy.com" 3128))
#:no-proxy ".racket-lang.org"
"http" "test.racket-lang.org")
=> #f
;; Failed matches
(test-proxy-server-for #:current-proxy-servers '(("http" "proxy.com" 3128))
#:plt-no-proxy ".racket-lang.org"
"http" "test.bracket-lang.org")
=> '("http" "proxy.com" 3128)
(test-proxy-server-for #:current-proxy-servers '(("http" "proxy.com" 3128))
#:no-proxy ".racket-lang.org"
"http" "test.bracket-lang.org")
=> '("http" "proxy.com" 3128)
;; Look at this... the no-proxes has a regexp which starts with a '.', a regexp
;; any char... that will match the 'b' in bracket
(test-proxy-server-for #:current-proxy-servers '(("http" "proxy.com" 3128))
#:current-no-proxy-servers '(#rx".racket-lang.org")
"http" "test.bracket-lang.org")
=> #f
))
(module+ test (require (submod ".." main))) ; for raco test & drdr (module+ test (require (submod ".." main))) ; for raco test & drdr