mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-29 19:30:36 +02:00
web: Don't hide missing data in the chunked input port.
This port is of limited use if it cannot be used reliably. Rather than behaving as if the input has finished when it ends unexpectedly, instead raise an exception. * module/web/http.scm (make-chunked-input-port): Raise an exception on premature termination. (&chunked-input-ended-prematurely): New exception type. (chunked-input-ended-prematurely-error?): New procedure. * test-suite/tests/web-http.test (pass-if-named-exception): Rename to pass-if-named-exception. (pass-if-named-exception): New syntax. ("Exception on premature chunk end"): New test for this behaviour. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
parent
9a3353a993
commit
baa1424335
3 changed files with 36 additions and 10 deletions
|
@ -1117,6 +1117,9 @@ Returns a new port, that transparently reads and decodes chunk-encoded
|
|||
data from @var{port}. If no more chunk-encoded data is available, it
|
||||
returns the end-of-file object. When the port is closed, @var{port} will
|
||||
also be closed, unless @var{keep-alive?} is true.
|
||||
|
||||
If the chunked input ends prematurely, a
|
||||
@code{&chunked-input-ended-promaturely} exception will be raised.
|
||||
@end deffn
|
||||
|
||||
@example
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#:use-module (ice-9 q)
|
||||
#:use-module (ice-9 binary-ports)
|
||||
#:use-module (ice-9 textual-ports)
|
||||
#:use-module (ice-9 exceptions)
|
||||
#:use-module (rnrs bytevectors)
|
||||
#:use-module (web uri)
|
||||
#:export (string->header
|
||||
|
@ -67,6 +68,8 @@
|
|||
read-response-line
|
||||
write-response-line
|
||||
|
||||
&chunked-input-error-prematurely
|
||||
chunked-input-ended-prematurely-error?
|
||||
make-chunked-input-port
|
||||
make-chunked-output-port
|
||||
|
||||
|
@ -1945,6 +1948,17 @@ treated specially, and is just returned as a plain string."
|
|||
|
||||
|
||||
;; Chunked Responses
|
||||
(define &chunked-input-ended-prematurely
|
||||
(make-exception-type '&chunked-input-error-prematurely
|
||||
&external-error
|
||||
'()))
|
||||
|
||||
(define make-chunked-input-ended-prematurely-error
|
||||
(record-constructor &chunked-input-ended-prematurely))
|
||||
|
||||
(define chunked-input-ended-prematurely-error?
|
||||
(record-predicate &chunked-input-ended-prematurely))
|
||||
|
||||
(define (read-chunk-header port)
|
||||
"Read a chunk header from PORT and return the size in bytes of the
|
||||
upcoming chunk."
|
||||
|
@ -1997,8 +2011,8 @@ closed it will also close PORT, unless the KEEP-ALIVE? is true."
|
|||
ask-for)))
|
||||
(cond
|
||||
((eof-object? read) ;premature termination
|
||||
(set! finished? #t)
|
||||
num-read)
|
||||
(raise-exception
|
||||
(make-chunked-input-ended-prematurely-error)))
|
||||
(else
|
||||
(let ((left (- remaining read)))
|
||||
(set! remaining left)
|
||||
|
|
|
@ -28,16 +28,19 @@
|
|||
#:use-module (test-suite lib))
|
||||
|
||||
|
||||
(define-syntax pass-if-named-exception
|
||||
(define-syntax pass-if-expected-exception
|
||||
(syntax-rules ()
|
||||
((_ name k pat exp)
|
||||
((_ name exception-predicate? exp)
|
||||
(pass-if name
|
||||
(catch 'k
|
||||
(lambda () exp (error "expected exception" 'k))
|
||||
(lambda (k message args)
|
||||
(if (string-match pat message)
|
||||
#t
|
||||
(error "unexpected exception" message args))))))))
|
||||
(with-exception-handler
|
||||
(lambda (exn)
|
||||
(if (exception-predicate? exn)
|
||||
#t
|
||||
(error "unexpected exception" exn)))
|
||||
(lambda ()
|
||||
exp
|
||||
#f)
|
||||
#:unwind? #t)))))
|
||||
|
||||
(define-syntax pass-if-only-parse
|
||||
(syntax-rules ()
|
||||
|
@ -491,6 +494,12 @@
|
|||
(port (make-chunked-input-port (open-input-string str))))
|
||||
(get-string-all port)))
|
||||
|
||||
(pass-if-expected-exception "Exception on premature chunk end"
|
||||
chunked-input-ended-prematurely-error?
|
||||
(let* ((str "b\r\nFirst chunk\r\nc\r\nSecond chun")
|
||||
(port (make-chunked-input-port (open-input-string str))))
|
||||
(get-string-all port)))
|
||||
|
||||
(pass-if-equal
|
||||
(call-with-output-string
|
||||
(lambda (out-raw)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue