[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 03/06: web: Don't hide missing data in the chunked input
From: |
Ludovic Courtès |
Subject: |
[Guile-commits] 03/06: web: Don't hide missing data in the chunked input port. |
Date: |
Mon, 4 Jul 2022 05:52:40 -0400 (EDT) |
civodul pushed a commit to branch main
in repository guile.
commit baa14243355b8a4a7f5228d347ad3ff7057e7312
Author: Christopher Baines <mail@cbaines.net>
AuthorDate: Thu Jun 30 19:15:54 2022 +0100
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>
---
doc/ref/web.texi | 3 +++
module/web/http.scm | 18 ++++++++++++++++--
test-suite/tests/web-http.test | 25 +++++++++++++++++--------
3 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/doc/ref/web.texi b/doc/ref/web.texi
index 93cd0214f..b04d328b7 100644
--- a/doc/ref/web.texi
+++ b/doc/ref/web.texi
@@ -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
diff --git a/module/web/http.scm b/module/web/http.scm
index 827adad3e..29736f2eb 100644
--- a/module/web/http.scm
+++ b/module/web/http.scm
@@ -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)
diff --git a/test-suite/tests/web-http.test b/test-suite/tests/web-http.test
index 3c2acf11c..06dd9479c 100644
--- a/test-suite/tests/web-http.test
+++ b/test-suite/tests/web-http.test
@@ -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)
- [Guile-commits] branch main updated (7e048c6c5 -> 8c976c6a1), Ludovic Courtès, 2022/07/04
- [Guile-commits] 02/06: web: Handle ending CRLF (\r\n) for chunked input and output ports., Ludovic Courtès, 2022/07/04
- [Guile-commits] 04/06: Define IN6ADDR_ANY and IN6ADDR_LOOPBACK., Ludovic Courtès, 2022/07/04
- [Guile-commits] 03/06: web: Don't hide missing data in the chunked input port.,
Ludovic Courtès <=
- [Guile-commits] 05/06: Define IPPROTO_IPV6 and IPV6_V6ONLY., Ludovic Courtès, 2022/07/04
- [Guile-commits] 06/06: Update NEWS., Ludovic Courtès, 2022/07/04
- [Guile-commits] 01/06: web: send capitalized authorization header scheme, Ludovic Courtès, 2022/07/04