From 41764d60dba80126b3c97f883d0225510b55f3fa Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Tue, 28 Aug 2018 18:39:34 -0400 Subject: [PATCH 1/2] web: Add support for HTTP header continuation lines. * module/web/http.scm (spaces-and-tabs, space-or-tab?): New variables. (read-header-line): After reading a header, if a space or tab follows, then read the continuation lines and append them all together. --- module/web/http.scm | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/module/web/http.scm b/module/web/http.scm index de61c9495..15f173173 100644 --- a/module/web/http.scm +++ b/module/web/http.scm @@ -1,6 +1,6 @@ ;;; HTTP messages -;; Copyright (C) 2010-2017 Free Software Foundation, Inc. +;; Copyright (C) 2010-2018 Free Software Foundation, Inc. ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public @@ -152,18 +152,35 @@ The default writer will call ‘put-string’." (lambda (val port) (put-string port val))))) +(define spaces-and-tabs + (char-set #\space #\tab)) + +(define (space-or-tab? c) + (case c + ((#\space #\tab) #t) + (else #f))) + (define (read-header-line port) - "Read an HTTP header line and return it without its final CRLF or LF. -Raise a 'bad-header' exception if the line does not end in CRLF or LF, -or if EOF is reached." + "Read an HTTP header line, including any continuation lines, and +return the combined string without its final CRLF or LF. Raise a +'bad-header' exception if the line does not end in CRLF or LF, or if EOF +is reached." (match (%read-line port) (((? string? line) . #\newline) ;; '%read-line' does not consider #\return a delimiter; so if it's ;; there, remove it. We are more tolerant than the RFC in that we ;; tolerate LF-only endings. - (if (string-suffix? "\r" line) - (string-drop-right line 1) - line)) + (let ((line (if (string-suffix? "\r" line) + (string-drop-right line 1) + line))) + ;; If the next character is a space or tab, then there's at least + ;; one continuation line. Read the continuation lines by calling + ;; 'read-header-line' recursively, and append them to this header + ;; line, folding the leading spaces and tabs to a single space. + (if (space-or-tab? (lookahead-char port)) + (string-append line " " (string-trim (read-header-line port) + spaces-and-tabs)) + line))) ((line . _) ;EOF or missing delimiter (bad-header 'read-header-line line)))) -- 2.18.0