135 lines
5.9 KiB
Racket
135 lines
5.9 KiB
Racket
#lang racket
|
|
(require net/url
|
|
mzlib/thread
|
|
openssl
|
|
tests/eli-tester)
|
|
|
|
(define (run-tests scheme wrap-ports skip-actual-redirect?)
|
|
(define ((make-tester url->port) response . responses)
|
|
(define first-port-no 9001)
|
|
(define server-cust
|
|
(make-custodian))
|
|
(parameterize ([current-custodian server-cust])
|
|
(for ([response (in-list (cons response responses))]
|
|
[port-no (in-naturals first-port-no)])
|
|
(thread
|
|
(λ ()
|
|
(run-server port-no
|
|
(lambda (ip op)
|
|
(let-values ([(ip op) (wrap-ports ip op)])
|
|
(regexp-match #rx"(\r\n|^)\r\n" ip)
|
|
(display response op)
|
|
(close-output-port op)
|
|
(close-input-port ip)))
|
|
+inf.0)))))
|
|
(sleep 1)
|
|
(dynamic-wind
|
|
void
|
|
(λ ()
|
|
(call-with-values
|
|
(λ ()
|
|
(url->port
|
|
(url scheme #f "localhost" first-port-no
|
|
#t empty empty #f)))
|
|
(λ vals (apply values (cons (port->string (car vals)) (cdr vals))))))
|
|
(λ ()
|
|
(custodian-shutdown-all server-cust))))
|
|
|
|
(define get-pure
|
|
(make-tester get-pure-port))
|
|
(define get-impure
|
|
(make-tester get-impure-port))
|
|
(define get-pure/redirect
|
|
(make-tester (λ (x) (get-pure-port x #:redirections 1))))
|
|
(define get-pure/headers
|
|
(make-tester get-pure-port/headers))
|
|
(define get-pure/headers/redirect
|
|
(make-tester (λ (x) (get-pure-port/headers x #:redirections 1))))
|
|
|
|
(test
|
|
(get-pure
|
|
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n24\r\nThis is the data in the first chunk \r\n1A\r\nand this is the second one\r\n0\r\n")
|
|
=>
|
|
"This is the data in the first chunk and this is the second one"
|
|
|
|
(get-pure
|
|
"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\nThis is the data in the first chunk and this is the second one")
|
|
=>
|
|
"This is the data in the first chunk and this is the second one"
|
|
|
|
(get-pure
|
|
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n20\r\nThis is the data in the first ch\r\n21\r\nand this is the second oneXXXXXXX\r\n0\r\n")
|
|
=>
|
|
"This is the data in the first chand this is the second oneXXXXXXX"
|
|
|
|
(get-pure/redirect
|
|
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n24\r\nThis is the data in the first chunk \r\n1A\r\nand this is the second one\r\n0\r\n")
|
|
=>
|
|
"This is the data in the first chunk and this is the second one"
|
|
|
|
(get-pure/redirect
|
|
"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\nThis is the data in the first chunk and this is the second one")
|
|
=>
|
|
"This is the data in the first chunk and this is the second one"
|
|
|
|
(get-pure/redirect
|
|
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n20\r\nThis is the data in the first ch\r\n21\r\nand this is the second oneXXXXXXX\r\n0\r\n")
|
|
=>
|
|
"This is the data in the first chand this is the second oneXXXXXXX"
|
|
|
|
(get-impure
|
|
"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\nThis is the data in the first chunk and this is the second one\r\n")
|
|
=>
|
|
"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\nThis is the data in the first chunk and this is the second one\r\n"
|
|
|
|
(get-pure/headers
|
|
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n24\r\nThis is the data in the first chunk \r\n1A\r\nand this is the second one\r\n0\r\n")
|
|
=>
|
|
(values "This is the data in the first chunk and this is the second one"
|
|
"Content-Type: text/plain\r\nTransfer-Encoding: chunked\r\n")
|
|
|
|
(get-pure/headers
|
|
"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\nThis is the data in the first chunk and this is the second one")
|
|
=>
|
|
(values "This is the data in the first chunk and this is the second one"
|
|
"Content-Type: text/plain\r\n")
|
|
|
|
(get-pure/headers
|
|
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n20\r\nThis is the data in the first ch\r\n21\r\nand this is the second oneXXXXXXX\r\n0\r\n")
|
|
=>
|
|
(values "This is the data in the first chand this is the second oneXXXXXXX"
|
|
"Content-Type: text/plain\r\nTransfer-Encoding: chunked\r\n")
|
|
|
|
(get-pure/headers
|
|
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\nAnother-Header: ta-daa\r\n\r\n20\r\nThis is the data in the first ch\r\n21\r\nand this is the second oneXXXXXXX\r\n0\r\n")
|
|
=>
|
|
(values "This is the data in the first chand this is the second oneXXXXXXX"
|
|
"Content-Type: text/plain\r\nTransfer-Encoding: chunked\r\nAnother-Header: ta-daa\r\n")
|
|
)
|
|
|
|
(unless skip-actual-redirect?
|
|
(test
|
|
(get-pure/redirect
|
|
"HTTP/1.1 301 Moved Permanently\r\nLocation: http://localhost:9002/whatever\r\n\r\nstuff"
|
|
(string-append
|
|
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n"
|
|
"24\r\nThis is the data in the first chunk \r\n1A\r\nand this is the second one\r\n0\r\n"))
|
|
|
|
(get-pure/headers/redirect
|
|
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\nAnother-Header: ta-daa\r\n\r\n20\r\nThis is the data in the first ch\r\n21\r\nand this is the second oneXXXXXXX\r\n0\r\n")
|
|
=>
|
|
(values "This is the data in the first chand this is the second oneXXXXXXX"
|
|
"Content-Type: text/plain\r\nTransfer-Encoding: chunked\r\nAnother-Header: ta-daa\r\n"))))
|
|
|
|
(provide tests)
|
|
(module+ main (tests))
|
|
(define (tests)
|
|
(test
|
|
(run-tests "http" values #f)
|
|
(run-tests "https" (let ([ctx (ssl-make-server-context)])
|
|
(ssl-load-certificate-chain! ctx (collection-file-path "test.pem" "openssl"))
|
|
(ssl-load-private-key! ctx (collection-file-path "test.pem" "openssl"))
|
|
(lambda (in out)
|
|
(ports->ssl-ports in out #:mode 'accept #:context ctx)))
|
|
#t)))
|