From 4b84fc7b48e1a9ecca4832cf6445f2ca246ec4ef Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Mon, 29 Apr 2013 13:20:24 -0600 Subject: [PATCH] Ignoring some bad network errors re Robby --- .../private/dispatch-server-unit.rkt | 82 ++++++++++--------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/collects/web-server/private/dispatch-server-unit.rkt b/collects/web-server/private/dispatch-server-unit.rkt index aae838b0fa..d07d180815 100644 --- a/collects/web-server/private/dispatch-server-unit.rkt +++ b/collects/web-server/private/dispatch-server-unit.rkt @@ -73,40 +73,48 @@ (define conn (new-connection config:initial-connection-timeout ip op (current-custodian) #f)) - ;; HTTP/1.1 allows any number of requests to come from this input - ;; port. However, there is no explicit cancellation of a - ;; connection---the browser will just close the port. This leaves - ;; the Web server in the unfortunate state of config:read-request - ;; trying to read an HTTP and failing---with an ugly error - ;; message. This call to peek here will block until at least one - ;; character is available and then transfer to read-request. At - ;; that point, an error message would be reasonable because the - ;; request would be badly formatted or ended early. However, if - ;; the connection is closed, then peek will get the EOF and the - ;; connection will be closed. This shouldn't change any other - ;; behavior: read-request is already blocking, peeking doesn't - ;; consume a byte, etc. - (define the-evt - (choice-evt - (handle-evt - (port-closed-evt ip) - (λ (res) - (kill-connection! conn))) - (handle-evt - (peek-bytes-evt 1 0 #f ip) - (λ (res) - (cond - [(eof-object? res) - (kill-connection! conn)] - [else - (define-values - (req close?) - (config:read-request conn config:port port-addresses)) - (set-connection-close?! conn close?) - (config:dispatch conn req) - (if (connection-close? conn) - (kill-connection! conn) - (connection-loop))]))))) - (define (connection-loop) - (sync the-evt)) - (connection-loop)) + (with-handlers + ([(λ (x) + ;; This error is "Connection reset by peer" and doesn't + ;; really indicate a problem with the server. + (and (exn:fail:network:errno? x) + (= 54 (exn:fail:network:errno-errno x)))) + (λ (x) + (kill-connection! conn))]) + ;; HTTP/1.1 allows any number of requests to come from this input + ;; port. However, there is no explicit cancellation of a + ;; connection---the browser will just close the port. This leaves + ;; the Web server in the unfortunate state of config:read-request + ;; trying to read an HTTP and failing---with an ugly error + ;; message. This call to peek here will block until at least one + ;; character is available and then transfer to read-request. At + ;; that point, an error message would be reasonable because the + ;; request would be badly formatted or ended early. However, if + ;; the connection is closed, then peek will get the EOF and the + ;; connection will be closed. This shouldn't change any other + ;; behavior: read-request is already blocking, peeking doesn't + ;; consume a byte, etc. + (define the-evt + (choice-evt + (handle-evt + (port-closed-evt ip) + (λ (res) + (kill-connection! conn))) + (handle-evt + (peek-bytes-evt 1 0 #f ip) + (λ (res) + (cond + [(eof-object? res) + (kill-connection! conn)] + [else + (define-values + (req close?) + (config:read-request conn config:port port-addresses)) + (set-connection-close?! conn close?) + (config:dispatch conn req) + (if (connection-close? conn) + (kill-connection! conn) + (connection-loop))]))))) + (define (connection-loop) + (sync the-evt)) + (connection-loop)))