diff --git a/collects/web-server/response.ss b/collects/web-server/response.ss index 66f687b19f..118d958882 100644 --- a/collects/web-server/response.ss +++ b/collects/web-server/response.ss @@ -110,63 +110,68 @@ (define DAYS #("Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat")) - + ;; ************************************************** ;; output-response: connection response -> void (define (ext:output-response conn resp) - (call-with-semaphore (connection-mutex conn) - (lambda () - (output-response conn resp) - (flush-output (connection-o-port conn))))) - + (if (connection-close? conn) + (raise 'output-response "Attempt to output on closed connection.") + (with-handlers ([exn? (lambda (exn) + (kill-connection! conn) + (raise exn))]) + (call-with-semaphore (connection-mutex conn) + (lambda () + (output-response conn resp) + (flush-output (connection-o-port conn))))))) + (define (output-response conn resp) - (cond - [(response/full? resp) - (output-response/basic - conn resp (response/full->size resp) - (lambda (o-port) - (for-each - (lambda (str) (display str o-port)) - (response/full-body resp))))] - [(response/incremental? resp) - (output-response/incremental conn resp)] - [(and (pair? resp) (bytes? (car resp))) - (output-response/basic - conn - (make-response/basic 200 "Okay" (current-seconds) (car resp) '()) - (apply + (map - (lambda (c) - (if (string? c) - (string-length c) - (bytes-length c))) - (cdr resp))) - (lambda (o-port) - (for-each - (lambda (str) (display str o-port)) - (cdr resp))))] - [else - ;; TODO: make a real exception for this. - (with-handlers - ([exn:invalid-xexpr? - (lambda (exn) - (output-response/method - conn - (xexpr-exn->response exn resp) - 'ignored))] - [exn? (lambda (exn) - (raise exn))]) - (let ([str (and (validate-xexpr resp) (xexpr->string resp))]) - (output-response/basic - conn - (make-response/basic 200 - "Okay" - (current-seconds) - TEXT/HTML-MIME-TYPE - '()) - (add1 (string-length str)) - (lambda (o-port) - (display str o-port) - (newline o-port)))))])) + (cond + [(response/full? resp) + (output-response/basic + conn resp (response/full->size resp) + (lambda (o-port) + (for-each + (lambda (str) (display str o-port)) + (response/full-body resp))))] + [(response/incremental? resp) + (output-response/incremental conn resp)] + [(and (pair? resp) (bytes? (car resp))) + (output-response/basic + conn + (make-response/basic 200 "Okay" (current-seconds) (car resp) '()) + (apply + (map + (lambda (c) + (if (string? c) + (string-length c) + (bytes-length c))) + (cdr resp))) + (lambda (o-port) + (for-each + (lambda (str) (display str o-port)) + (cdr resp))))] + [else + ;; TODO: make a real exception for this. + (with-handlers + ([exn:invalid-xexpr? + (lambda (exn) + (output-response/method + conn + (xexpr-exn->response exn resp) + 'ignored))] + [exn? (lambda (exn) + (raise exn))]) + (let ([str (and (validate-xexpr resp) (xexpr->string resp))]) + (output-response/basic + conn + (make-response/basic 200 + "Okay" + (current-seconds) + TEXT/HTML-MIME-TYPE + '()) + (add1 (string-length str)) + (lambda (o-port) + (display str o-port) + (newline o-port)))))])) ;; response/full->size: response/full -> number ;; compute the size for a response/full @@ -181,10 +186,15 @@ ;; ************************************************** ;; output-file: connection path symbol bytes -> void (define (ext:output-file conn file-path method mime-type) - (call-with-semaphore (connection-mutex conn) - (lambda () - (output-file conn file-path method mime-type) - (flush-output (connection-o-port conn))))) + (if (connection-close? conn) + (raise 'output-response "Attempt to output on closed connection.") + (with-handlers ([exn? (lambda (exn) + (kill-connection! conn) + (raise exn))]) + (call-with-semaphore (connection-mutex conn) + (lambda () + (output-file conn file-path method mime-type) + (flush-output (connection-o-port conn))))))) (define (output-file conn file-path method mime-type) (output-headers conn 200 "Okay" @@ -202,11 +212,16 @@ ;; output-response/method: connection response/full symbol -> void ;; If it is a head request output headers only, otherwise output as usual (define (ext:output-response/method conn resp meth) - (call-with-semaphore (connection-mutex conn) - (lambda () - (output-response/method conn resp meth) - (flush-output (connection-o-port conn))))) - + (if (connection-close? conn) + (raise 'output-response "Attempt to output on closed connection.") + (with-handlers ([exn? (lambda (exn) + (kill-connection! conn) + (raise exn))]) + (call-with-semaphore (connection-mutex conn) + (lambda () + (output-response/method conn resp meth) + (flush-output (connection-o-port conn))))))) + (define (output-response/method conn resp meth) (cond [(eqv? meth 'head)