Fix some issues handling head requests
Rather than raising an exception when there's a body provided, use the body as normal to inform the headers, as this is useful, and just don't write the body to the client.
This commit is contained in:
parent
338d08081e
commit
4642f7c7d2
2 changed files with 127 additions and 59 deletions
|
|
@ -228,8 +228,6 @@ on the procedure being called at any particular time."
|
|||
(adapt-response-version response
|
||||
(request-version request))
|
||||
body))
|
||||
((not body)
|
||||
(values response #vu8()))
|
||||
((string? body)
|
||||
(let* ((type (response-content-type response
|
||||
'(text/plain)))
|
||||
|
|
@ -243,16 +241,15 @@ on the procedure being called at any particular time."
|
|||
`(,@type (charset . ,charset))))
|
||||
(string->bytevector body charset))))
|
||||
((not (or (bytevector? body)
|
||||
(procedure? body)))
|
||||
(procedure? body)
|
||||
(eq? #f body)))
|
||||
(raise-exception
|
||||
(make-exception-with-irritants
|
||||
(list (make-exception-with-message
|
||||
"unexpected body type")
|
||||
body))))
|
||||
((and (response-must-not-include-body? response)
|
||||
body
|
||||
;; FIXME make this stricter: even an empty body should be prohibited.
|
||||
(not (zero? (bytevector-length body))))
|
||||
body)
|
||||
(raise-exception
|
||||
(make-exception-with-irritants
|
||||
(list (make-exception-with-message
|
||||
|
|
@ -262,25 +259,24 @@ on the procedure being called at any particular time."
|
|||
;; check length; assert type; add other required fields?
|
||||
(values (response-maybe-add-connection-header-value
|
||||
request
|
||||
(if (procedure? body)
|
||||
(if (response-content-length response)
|
||||
response
|
||||
(extend-response response
|
||||
'transfer-encoding
|
||||
'((chunked))))
|
||||
(let ((rlen (response-content-length response))
|
||||
(blen (bytevector-length body)))
|
||||
(cond
|
||||
(rlen (if (= rlen blen)
|
||||
response
|
||||
(error "bad content-length" rlen blen)))
|
||||
(else (extend-response response 'content-length blen))))))
|
||||
(cond
|
||||
((procedure? body)
|
||||
(if (response-content-length response)
|
||||
response
|
||||
(extend-response response
|
||||
'transfer-encoding
|
||||
'((chunked)))))
|
||||
((bytevector? body)
|
||||
(let ((rlen (response-content-length response))
|
||||
(blen (bytevector-length body)))
|
||||
(cond
|
||||
(rlen (if (= rlen blen)
|
||||
response
|
||||
(error "bad content-length" rlen blen)))
|
||||
(else (extend-response response 'content-length blen)))))
|
||||
(else response)))
|
||||
(if (eq? (request-method request) 'HEAD)
|
||||
(raise-exception
|
||||
(make-exception-with-irritants
|
||||
(list (make-exception-with-message
|
||||
"unexpected body type")
|
||||
body)))
|
||||
#f
|
||||
body)))))
|
||||
|
||||
(define (with-stack-and-prompt thunk)
|
||||
|
|
@ -405,41 +401,48 @@ on the procedure being called at any particular time."
|
|||
(let ((response-start-time
|
||||
(get-internal-real-time))
|
||||
(body-written?
|
||||
(if (procedure? body)
|
||||
(let* ((type (response-content-type response
|
||||
'(text/plain)))
|
||||
(declared-charset (assq-ref (cdr type) 'charset))
|
||||
(charset (or declared-charset "ISO-8859-1"))
|
||||
(body-port
|
||||
(if (response-content-length response)
|
||||
client
|
||||
(make-chunked-output-port/knots
|
||||
client
|
||||
#:keep-alive? #t
|
||||
#:buffering
|
||||
(- buffer-size
|
||||
(chunked-output-port-overhead-bytes
|
||||
buffer-size))))))
|
||||
(set-port-encoding! body-port charset)
|
||||
(let ((body-written?
|
||||
(with-exception-handler
|
||||
(lambda (exn)
|
||||
#f)
|
||||
(lambda ()
|
||||
(with-exception-handler
|
||||
(lambda (exn)
|
||||
(print-backtrace-and-exception/knots exn)
|
||||
(raise-exception exn))
|
||||
(lambda ()
|
||||
(body body-port)))
|
||||
#t)
|
||||
#:unwind? #t)))
|
||||
(unless (response-content-length response)
|
||||
(close-port body-port))
|
||||
body-written?))
|
||||
(begin
|
||||
(put-bytevector client body)
|
||||
#t))))
|
||||
(cond
|
||||
((and (procedure? body)
|
||||
(not
|
||||
(eq? (request-method request)
|
||||
'HEAD)))
|
||||
(let* ((type (response-content-type response
|
||||
'(text/plain)))
|
||||
(declared-charset (assq-ref (cdr type) 'charset))
|
||||
(charset (or declared-charset "ISO-8859-1"))
|
||||
(body-port
|
||||
(if (response-content-length response)
|
||||
client
|
||||
(make-chunked-output-port/knots
|
||||
client
|
||||
#:keep-alive? #t
|
||||
#:buffering
|
||||
(- buffer-size
|
||||
(chunked-output-port-overhead-bytes
|
||||
buffer-size))))))
|
||||
(set-port-encoding! body-port charset)
|
||||
(let ((body-written?
|
||||
(with-exception-handler
|
||||
(lambda (exn)
|
||||
#f)
|
||||
(lambda ()
|
||||
(with-exception-handler
|
||||
(lambda (exn)
|
||||
(print-backtrace-and-exception/knots exn)
|
||||
(raise-exception exn))
|
||||
(lambda ()
|
||||
(body body-port)))
|
||||
#t)
|
||||
#:unwind? #t)))
|
||||
(unless (response-content-length response)
|
||||
(close-port body-port))
|
||||
body-written?)))
|
||||
((bytevector? body)
|
||||
(put-bytevector client body)
|
||||
#t)
|
||||
(else
|
||||
;; No body to write
|
||||
#t))))
|
||||
(if body-written?
|
||||
(begin
|
||||
(force-output client)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue