Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

bug21142: handle connection reset and aborted errors in the client

READ-SOCKET-LINE assumes that (READ-CHAR SOCKET NIL NIL) gets an eof
and returns NIL if the connection is severed. Windows can surprise us
with WSAECONNABORTED, and linux with ECONNRESET (and it's actually
documented). Other platforms are expected to vary in when/if these can
be triggered when reading from a socket, but it's safe to treat these
errors as eof for our purposes.

Update defpatch form (acl82: v17, acl90: v4).

<release-note>
bug21142 - handle connection reset and aborted errors in the client

Previously, net.client:do-http-request sometimes signaled connection
reset and connection aborted errors when the :connection argument was
used and the connection was severed (for example, the connection timed
out on the server and was closed). With this fix, connection reset and
aborted errors are treated as an eof: we retry the request with a new
connection which should make keep-alive operation more reliable.
</release-note>

Change-Id: I1ec4d1e6c3b3ea54c9f22bacf63d6080277c31ca
  • Loading branch information...
commit ac98d1b45021059519ef271208de9bcfd1110b9d 1 parent 64e3ce9
Gabor Melis authored dklayer committed
Showing with 22 additions and 7 deletions.
  1. +12 −3 client.cl
  2. +1 −0  main.cl
  3. +9 −4 packages.cl
View
15 client.cl
@@ -377,7 +377,7 @@
nil)
- then ; got eof right away.. likely due to bogus
+ then ; got eof .. likely due to bogus
; saved connection... so try again with
; no saved connection
(ignore-errors (close connection))
@@ -1286,7 +1286,16 @@ or \"foo.com:8000\", not ~s" proxy))
else val)))
-
+(defmacro ignore-connection-reset-and-abort (&body body)
+ (let ((tag (gensym)))
+ `(catch ',tag
+ (handler-bind
+ ((socket-error
+ (lambda (e)
+ (when (member (stream-error-identifier e)
+ '(:connection-reset :connection-aborted))
+ (throw ',tag nil)))))
+ ,@body))))
(defun read-socket-line (socket buffer max)
@@ -1299,7 +1308,7 @@ or \"foo.com:8000\", not ~s" proxy))
;;
(let ((i 0))
(loop
- (let ((ch (read-char socket nil nil)))
+ (let ((ch (ignore-connection-reset-and-abort (read-char socket nil nil))))
(if* (null ch)
then ; eof from socket
(if* (> i 0)
View
1  main.cl
@@ -1617,6 +1617,7 @@ by keyword symbols and not by strings"
;; by peer
(if* (typep c 'stream-error)
then (or (eq (stream-error-identifier c) :connection-reset)
+ (eq (stream-error-identifier c) :connection-aborted)
#+unix (eq (stream-error-code c) 32) ; sigpipe
#+aix (eq (stream-error-code c) 73)
)))
View
13 packages.cl
@@ -1,14 +1,16 @@
#+(version= 9 0)
-(sys:defpatch "aserve" 3
+(sys:defpatch "aserve" 4
"v1: 1.3.16: fix freeing freed buffer;
v2: 1.3.18: introduce allegroserve-error condition object,
fix compression with logical pathnames;
-v3: add timeout for reading request header."
+v3: add timeout for reading request header.
+v4: 1.3.20: handle connection reset and aborted errors
+ properly in the client;"
:type :system
:post-loadable t)
#+(version= 8 2)
-(sys:defpatch "aserve" 16
+(sys:defpatch "aserve" 17
"v1: version 1.2.67, implement keep-alive in allegroserve client;
v2: 1.2.68, obey keep-alive requests for PUT and POST requests;
v3: 1.2.69, make logging though method specialized on wserver class;
@@ -34,7 +36,10 @@ v13: 1.3.13: improve debugging facilities;
v14: 1.3.16: fix freeing freed buffer;
v15: 1.3.18: introduce allegroserve-error condition object,
fix compression with logical pathnames;
-v16: add timeout for reading request header."
+v16: add timeout for reading request header.
+ fix compression with logical pathnames.
+v17: 1.3.20: handle connection reset and aborted errors
+ properly in the client;"
:type :system
:post-loadable t)
Please sign in to comment.
Something went wrong with that request. Please try again.