We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
"Connection reset by peer" in handle_request isn't handled (or ignored)
We see a lot of these errors with HAProxy 1.5 in front of gunicorn:

```
2014-10-23 17:17:24,366 DEBUG OPTIONS /haproxy_check
2014-10-23 17:17:24,384 DEBUG Ignoring connection reset
2014-10-23 17:17:24,700 DEBUG OPTIONS /haproxy_check
2014-10-23 17:17:24,719 DEBUG Ignoring connection reset
2014-10-23 17:17:24,753 DEBUG OPTIONS /haproxy_check
2014-10-23 17:17:24,770 ERROR Error handling request
Traceback (most recent call last):
  File "/opt/lp-apps/webshell/lib/python2.7/site-packages/gunicorn/workers/async.py", line 108, in handle_request
    resp.write(item)
  File "/opt/lp-apps/webshell/lib/python2.7/site-packages/gunicorn/http/wsgi.py", line 344, in write
    util.write(self.sock, arg, self.chunked)
  File "/opt/lp-apps/webshell/lib/python2.7/site-packages/gunicorn/util.py", line 300, in write
    return write_chunk(sock, data)
  File "/opt/lp-apps/webshell/lib/python2.7/site-packages/gunicorn/util.py", line 295, in write_chunk
    sock.sendall(chunk)
  File "/opt/lp-apps/webshell/lib/python2.7/site-packages/gevent/socket.py", line 458, in sendall
    data_sent += self.send(_get_memory(data, data_sent), flags)
  File "/opt/lp-apps/webshell/lib/python2.7/site-packages/gevent/socket.py", line 435, in send
    return sock.send(data, flags)
error: [Errno 104] Connection reset by peer
2014-10-23 17:17:24,770 DEBUG Closing connection.
```

It seems that in the async worker, the error is sometimes caught and ignored in `handle`, but it also sometimes happens in `handle_request`. It should probably be ignored there as well?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gunicorn/workers/async.py`
Content:
```
1 # -*- coding: utf-8 -
2 #
3 # This file is part of gunicorn released under the MIT license.
4 # See the NOTICE for more information.
5 
6 from datetime import datetime
7 import errno
8 import socket
9 import ssl
10 import sys
11 
12 import gunicorn.http as http
13 import gunicorn.http.wsgi as wsgi
14 import gunicorn.util as util
15 import gunicorn.workers.base as base
16 from gunicorn import six
17 
18 ALREADY_HANDLED = object()
19 
20 
21 class AsyncWorker(base.Worker):
22 
23     def __init__(self, *args, **kwargs):
24         super(AsyncWorker, self).__init__(*args, **kwargs)
25         self.worker_connections = self.cfg.worker_connections
26 
27     def timeout_ctx(self):
28         raise NotImplementedError()
29 
30     def handle(self, listener, client, addr):
31         req = None
32         try:
33             parser = http.RequestParser(self.cfg, client)
34             try:
35                 listener_name = listener.getsockname()
36                 if not self.cfg.keepalive:
37                     req = six.next(parser)
38                     self.handle_request(listener_name, req, client, addr)
39                 else:
40                     # keepalive loop
41                     proxy_protocol_info = {}
42                     while True:
43                         req = None
44                         with self.timeout_ctx():
45                             req = six.next(parser)
46                         if not req:
47                             break
48                         if req.proxy_protocol_info:
49                             proxy_protocol_info = req.proxy_protocol_info
50                         else:
51                             req.proxy_protocol_info = proxy_protocol_info
52                         self.handle_request(listener_name, req, client, addr)
53             except http.errors.NoMoreData as e:
54                 self.log.debug("Ignored premature client disconnection. %s", e)
55             except StopIteration as e:
56                 self.log.debug("Closing connection. %s", e)
57             except ssl.SSLError:
58                 exc_info = sys.exc_info()
59                 # pass to next try-except level
60                 six.reraise(exc_info[0], exc_info[1], exc_info[2])
61             except socket.error:
62                 exc_info = sys.exc_info()
63                 # pass to next try-except level
64                 six.reraise(exc_info[0], exc_info[1], exc_info[2])
65             except Exception as e:
66                 self.handle_error(req, client, addr, e)
67         except ssl.SSLError as e:
68             if e.args[0] == ssl.SSL_ERROR_EOF:
69                 self.log.debug("ssl connection closed")
70                 client.close()
71             else:
72                 self.log.debug("Error processing SSL request.")
73                 self.handle_error(req, client, addr, e)
74         except socket.error as e:
75             if e.args[0] not in (errno.EPIPE, errno.ECONNRESET):
76                 self.log.exception("Socket error processing request.")
77             else:
78                 if e.args[0] == errno.ECONNRESET:
79                     self.log.debug("Ignoring connection reset")
80                 else:
81                     self.log.debug("Ignoring EPIPE")
82         except Exception as e:
83             self.handle_error(req, client, addr, e)
84         finally:
85             util.close(client)
86 
87     def handle_request(self, listener_name, req, sock, addr):
88         request_start = datetime.now()
89         environ = {}
90         resp = None
91         try:
92             self.cfg.pre_request(self, req)
93             resp, environ = wsgi.create(req, sock, addr,
94                     listener_name, self.cfg)
95             environ["wsgi.multithread"] = True
96             self.nr += 1
97             if self.alive and self.nr >= self.max_requests:
98                 self.log.info("Autorestarting worker after current request.")
99                 resp.force_close()
100                 self.alive = False
101 
102             if not self.cfg.keepalive:
103                 resp.force_close()
104 
105             respiter = self.wsgi(environ, resp.start_response)
106             if respiter == ALREADY_HANDLED:
107                 return False
108             try:
109                 if isinstance(respiter, environ['wsgi.file_wrapper']):
110                     resp.write_file(respiter)
111                 else:
112                     for item in respiter:
113                         resp.write(item)
114                 resp.close()
115                 request_time = datetime.now() - request_start
116                 self.log.access(resp, req, environ, request_time)
117             finally:
118                 if hasattr(respiter, "close"):
119                     respiter.close()
120             if resp.should_close():
121                 raise StopIteration()
122         except StopIteration:
123             raise
124         except Exception:
125             if resp and resp.headers_sent:
126                 # If the requests have already been sent, we should close the
127                 # connection to indicate the error.
128                 self.log.exception("Error handling request")
129                 try:
130                     sock.shutdown(socket.SHUT_RDWR)
131                     sock.close()
132                 except socket.error:
133                     pass
134                 raise StopIteration()
135             raise
136         finally:
137             try:
138                 self.cfg.post_request(self, req, environ, resp)
139             except Exception:
140                 self.log.exception("Exception in post_request hook")
141         return True
142
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/gunicorn/workers/async.py b/gunicorn/workers/async.py
--- a/gunicorn/workers/async.py
+++ b/gunicorn/workers/async.py
@@ -118,6 +118,10 @@
                 raise StopIteration()
         except StopIteration:
             raise
+        except socket.error:
+            # If the original exception was a socket.error we delegate
+            # handling it to the caller (where handle() might ignore it 
+            six.reraise(*sys.exc_info())
         except Exception:
             if resp and resp.headers_sent:
                 # If the requests have already been sent, we should close the

{"golden_diff": "diff --git a/gunicorn/workers/async.py b/gunicorn/workers/async.py\n--- a/gunicorn/workers/async.py\n+++ b/gunicorn/workers/async.py\n@@ -118,6 +118,10 @@\n                 raise StopIteration()\n         except StopIteration:\n             raise\n+        except socket.error:\n+            # If the original exception was a socket.error we delegate\n+            # handling it to the caller (where handle() might ignore it \n+            six.reraise(*sys.exc_info())\n         except Exception:\n             if resp and resp.headers_sent:\n                 # If the requests have already been sent, we should close the\n", "issue": "\"Connection reset by peer\" in handle_request isn't handled (or ignored)\nWe see a lot of these errors with HAProxy 1.5 in front of gunicorn:\n\n```\n2014-10-23 17:17:24,366 DEBUG OPTIONS /haproxy_check\n2014-10-23 17:17:24,384 DEBUG Ignoring connection reset\n2014-10-23 17:17:24,700 DEBUG OPTIONS /haproxy_check\n2014-10-23 17:17:24,719 DEBUG Ignoring connection reset\n2014-10-23 17:17:24,753 DEBUG OPTIONS /haproxy_check\n2014-10-23 17:17:24,770 ERROR Error handling request\nTraceback (most recent call last):\n  File \"/opt/lp-apps/webshell/lib/python2.7/site-packages/gunicorn/workers/async.py\", line 108, in handle_request\n    resp.write(item)\n  File \"/opt/lp-apps/webshell/lib/python2.7/site-packages/gunicorn/http/wsgi.py\", line 344, in write\n    util.write(self.sock, arg, self.chunked)\n  File \"/opt/lp-apps/webshell/lib/python2.7/site-packages/gunicorn/util.py\", line 300, in write\n    return write_chunk(sock, data)\n  File \"/opt/lp-apps/webshell/lib/python2.7/site-packages/gunicorn/util.py\", line 295, in write_chunk\n    sock.sendall(chunk)\n  File \"/opt/lp-apps/webshell/lib/python2.7/site-packages/gevent/socket.py\", line 458, in sendall\n    data_sent += self.send(_get_memory(data, data_sent), flags)\n  File \"/opt/lp-apps/webshell/lib/python2.7/site-packages/gevent/socket.py\", line 435, in send\n    return sock.send(data, flags)\nerror: [Errno 104] Connection reset by peer\n2014-10-23 17:17:24,770 DEBUG Closing connection.\n```\n\nIt seems that in the async worker, the error is sometimes caught and ignored in `handle`, but it also sometimes happens in `handle_request`. It should probably be ignored there as well?\n\n", "before_files": [{"content": "# -*- coding: utf-8 -\n#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nfrom datetime import datetime\nimport errno\nimport socket\nimport ssl\nimport sys\n\nimport gunicorn.http as http\nimport gunicorn.http.wsgi as wsgi\nimport gunicorn.util as util\nimport gunicorn.workers.base as base\nfrom gunicorn import six\n\nALREADY_HANDLED = object()\n\n\nclass AsyncWorker(base.Worker):\n\n    def __init__(self, *args, **kwargs):\n        super(AsyncWorker, self).__init__(*args, **kwargs)\n        self.worker_connections = self.cfg.worker_connections\n\n    def timeout_ctx(self):\n        raise NotImplementedError()\n\n    def handle(self, listener, client, addr):\n        req = None\n        try:\n            parser = http.RequestParser(self.cfg, client)\n            try:\n                listener_name = listener.getsockname()\n                if not self.cfg.keepalive:\n                    req = six.next(parser)\n                    self.handle_request(listener_name, req, client, addr)\n                else:\n                    # keepalive loop\n                    proxy_protocol_info = {}\n                    while True:\n                        req = None\n                        with self.timeout_ctx():\n                            req = six.next(parser)\n                        if not req:\n                            break\n                        if req.proxy_protocol_info:\n                            proxy_protocol_info = req.proxy_protocol_info\n                        else:\n                            req.proxy_protocol_info = proxy_protocol_info\n                        self.handle_request(listener_name, req, client, addr)\n            except http.errors.NoMoreData as e:\n                self.log.debug(\"Ignored premature client disconnection. %s\", e)\n            except StopIteration as e:\n                self.log.debug(\"Closing connection. %s\", e)\n            except ssl.SSLError:\n                exc_info = sys.exc_info()\n                # pass to next try-except level\n                six.reraise(exc_info[0], exc_info[1], exc_info[2])\n            except socket.error:\n                exc_info = sys.exc_info()\n                # pass to next try-except level\n                six.reraise(exc_info[0], exc_info[1], exc_info[2])\n            except Exception as e:\n                self.handle_error(req, client, addr, e)\n        except ssl.SSLError as e:\n            if e.args[0] == ssl.SSL_ERROR_EOF:\n                self.log.debug(\"ssl connection closed\")\n                client.close()\n            else:\n                self.log.debug(\"Error processing SSL request.\")\n                self.handle_error(req, client, addr, e)\n        except socket.error as e:\n            if e.args[0] not in (errno.EPIPE, errno.ECONNRESET):\n                self.log.exception(\"Socket error processing request.\")\n            else:\n                if e.args[0] == errno.ECONNRESET:\n                    self.log.debug(\"Ignoring connection reset\")\n                else:\n                    self.log.debug(\"Ignoring EPIPE\")\n        except Exception as e:\n            self.handle_error(req, client, addr, e)\n        finally:\n            util.close(client)\n\n    def handle_request(self, listener_name, req, sock, addr):\n        request_start = datetime.now()\n        environ = {}\n        resp = None\n        try:\n            self.cfg.pre_request(self, req)\n            resp, environ = wsgi.create(req, sock, addr,\n                    listener_name, self.cfg)\n            environ[\"wsgi.multithread\"] = True\n            self.nr += 1\n            if self.alive and self.nr >= self.max_requests:\n                self.log.info(\"Autorestarting worker after current request.\")\n                resp.force_close()\n                self.alive = False\n\n            if not self.cfg.keepalive:\n                resp.force_close()\n\n            respiter = self.wsgi(environ, resp.start_response)\n            if respiter == ALREADY_HANDLED:\n                return False\n            try:\n                if isinstance(respiter, environ['wsgi.file_wrapper']):\n                    resp.write_file(respiter)\n                else:\n                    for item in respiter:\n                        resp.write(item)\n                resp.close()\n                request_time = datetime.now() - request_start\n                self.log.access(resp, req, environ, request_time)\n            finally:\n                if hasattr(respiter, \"close\"):\n                    respiter.close()\n            if resp.should_close():\n                raise StopIteration()\n        except StopIteration:\n            raise\n        except Exception:\n            if resp and resp.headers_sent:\n                # If the requests have already been sent, we should close the\n                # connection to indicate the error.\n                self.log.exception(\"Error handling request\")\n                try:\n                    sock.shutdown(socket.SHUT_RDWR)\n                    sock.close()\n                except socket.error:\n                    pass\n                raise StopIteration()\n            raise\n        finally:\n            try:\n                self.cfg.post_request(self, req, environ, resp)\n            except Exception:\n                self.log.exception(\"Exception in post_request hook\")\n        return True\n", "path": "gunicorn/workers/async.py"}], "after_files": [{"content": "# -*- coding: utf-8 -\n#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nfrom datetime import datetime\nimport errno\nimport socket\nimport ssl\nimport sys\n\nimport gunicorn.http as http\nimport gunicorn.http.wsgi as wsgi\nimport gunicorn.util as util\nimport gunicorn.workers.base as base\nfrom gunicorn import six\n\nALREADY_HANDLED = object()\n\n\nclass AsyncWorker(base.Worker):\n\n    def __init__(self, *args, **kwargs):\n        super(AsyncWorker, self).__init__(*args, **kwargs)\n        self.worker_connections = self.cfg.worker_connections\n\n    def timeout_ctx(self):\n        raise NotImplementedError()\n\n    def handle(self, listener, client, addr):\n        req = None\n        try:\n            parser = http.RequestParser(self.cfg, client)\n            try:\n                listener_name = listener.getsockname()\n                if not self.cfg.keepalive:\n                    req = six.next(parser)\n                    self.handle_request(listener_name, req, client, addr)\n                else:\n                    # keepalive loop\n                    proxy_protocol_info = req.proxy_protocol_info\n                    while True:\n                        req = None\n                        with self.timeout_ctx():\n                            req = six.next(parser)\n                        if not req:\n                            break\n                        req.proxy_protocol_info = proxy_protocol_info\n                        self.handle_request(listener_name, req, client, addr)\n            except http.errors.NoMoreData as e:\n                self.log.debug(\"Ignored premature client disconnection. %s\", e)\n            except StopIteration as e:\n                self.log.debug(\"Closing connection. %s\", e)\n            except ssl.SSLError:\n                exc_info = sys.exc_info()\n                # pass to next try-except level\n                six.reraise(exc_info[0], exc_info[1], exc_info[2])\n            except socket.error:\n                exc_info = sys.exc_info()\n                # pass to next try-except level\n                six.reraise(exc_info[0], exc_info[1], exc_info[2])\n            except Exception as e:\n                self.handle_error(req, client, addr, e)\n        except ssl.SSLError as e:\n            if e.args[0] == ssl.SSL_ERROR_EOF:\n                self.log.debug(\"ssl connection closed\")\n                client.close()\n            else:\n                self.log.debug(\"Error processing SSL request.\")\n                self.handle_error(req, client, addr, e)\n        except socket.error as e:\n            if e.args[0] not in (errno.EPIPE, errno.ECONNRESET):\n                self.log.exception(\"Socket error processing request.\")\n            else:\n                if e.args[0] == errno.ECONNRESET:\n                    self.log.debug(\"Ignoring connection reset\")\n                else:\n                    self.log.debug(\"Ignoring EPIPE\")\n        except Exception as e:\n            self.handle_error(req, client, addr, e)\n        finally:\n            util.close(client)\n\n    def handle_request(self, listener_name, req, sock, addr):\n        request_start = datetime.now()\n        environ = {}\n        resp = None\n        try:\n            self.cfg.pre_request(self, req)\n            resp, environ = wsgi.create(req, sock, addr,\n                    listener_name, self.cfg)\n            environ[\"wsgi.multithread\"] = True\n            self.nr += 1\n            if self.alive and self.nr >= self.max_requests:\n                self.log.info(\"Autorestarting worker after current request.\")\n                resp.force_close()\n                self.alive = False\n\n            if not self.cfg.keepalive:\n                resp.force_close()\n\n            respiter = self.wsgi(environ, resp.start_response)\n            if respiter == ALREADY_HANDLED:\n                return False\n            try:\n                if isinstance(respiter, environ['wsgi.file_wrapper']):\n                    resp.write_file(respiter)\n                else:\n                    for item in respiter:\n                        resp.write(item)\n                resp.close()\n                request_time = datetime.now() - request_start\n                self.log.access(resp, req, environ, request_time)\n            finally:\n                if hasattr(respiter, \"close\"):\n                    respiter.close()\n            if resp.should_close():\n                raise StopIteration()\n        except StopIteration:\n            raise\n        except socket.error:\n            # If the original exception was a socket.error we delegate\n            # handling it to the caller (where handle() might ignore it \n            six.reraise(*sys.exc_info())\n        except Exception:\n            if resp and resp.headers_sent:\n                # If the requests have already been sent, we should close the\n                # connection to indicate the error.\n                self.log.exception(\"Error handling request\")\n                try:\n                    sock.shutdown(socket.SHUT_RDWR)\n                    sock.close()\n                except socket.error:\n                    pass\n                raise StopIteration()\n            raise\n        finally:\n            try:\n                self.cfg.post_request(self, req, environ, resp)\n            except Exception:\n                self.log.exception(\"Exception in post_request hook\")\n        return True\n", "path": "gunicorn/workers/async.py"}]}