From d54e587fe69ae54a3ef83c5a7994ef2e44b2139f Mon Sep 17 00:00:00 2001 From: Allan Saddi Date: Sun, 18 Jun 2006 16:04:04 +0000 Subject: Stop ignoring EPIPE exceptions. --- ChangeLog | 11 +++++++++++ flup/server/ajp_base.py | 26 ++++++++++++++------------ flup/server/fcgi_base.py | 26 ++++++++++++++------------ flup/server/scgi_base.py | 36 ++++++++++++++++-------------------- 4 files changed, 55 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd76797..0e74e0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2006-06-18 Allan Saddi + + * Stop ignoring EPIPE exceptions, as this is probably the + wrong thing to do. (Application is unaware of disconnected + clients and the CPU spins when sending large files to a + disconnected client.) Thanks to Ivan Sagalaev for bringing + this to my attention. + + NB: Existing applications that use the flup servers may begin + seeing socket.error exceptions... + 2006-05-18 Allan Saddi * Added umask keyword parameter to fcgi and fcgi_fork, diff --git a/flup/server/ajp_base.py b/flup/server/ajp_base.py index 6ffc2e6..de5ba4e 100644 --- a/flup/server/ajp_base.py +++ b/flup/server/ajp_base.py @@ -297,9 +297,7 @@ class Packet(object): try: sent = sock.send(data) except socket.error, e: - if e[0] == errno.EPIPE: - return # Don't bother raising an exception. Just ignore. - elif e[0] == errno.EAGAIN: + if e[0] == errno.EAGAIN: select.select([], [sock], []) continue else: @@ -897,16 +895,20 @@ class BaseAJPServer(object): if not self.multithreaded: self._appLock.acquire() try: - result = self.application(environ, start_response) try: - for data in result: - if data: - write(data) - if not headers_sent: - write('') # in case body was empty - finally: - if hasattr(result, 'close'): - result.close() + result = self.application(environ, start_response) + try: + for data in result: + if data: + write(data) + if not headers_sent: + write('') # in case body was empty + finally: + if hasattr(result, 'close'): + result.close() + except socket.error, e: + if e[0] != errno.EPIPE: + raise # Don't let EPIPE propagate beyond server finally: if not self.multithreaded: self._appLock.release() diff --git a/flup/server/fcgi_base.py b/flup/server/fcgi_base.py index bce5155..56fac6b 100644 --- a/flup/server/fcgi_base.py +++ b/flup/server/fcgi_base.py @@ -506,9 +506,7 @@ class Record(object): try: sent = sock.send(data) except socket.error, e: - if e[0] == errno.EPIPE: - return # Don't bother raising an exception. Just ignore. - elif e[0] == errno.EAGAIN: + if e[0] == errno.EAGAIN: select.select([], [sock], []) continue else: @@ -1109,16 +1107,20 @@ class BaseFCGIServer(object): if not self.multithreaded: self._appLock.acquire() try: - result = self.application(environ, start_response) try: - for data in result: - if data: - write(data) - if not headers_sent: - write('') # in case body was empty - finally: - if hasattr(result, 'close'): - result.close() + result = self.application(environ, start_response) + try: + for data in result: + if data: + write(data) + if not headers_sent: + write('') # in case body was empty + finally: + if hasattr(result, 'close'): + result.close() + except socket.error, e: + if e[0] != errno.EPIPE: + raise # Don't let EPIPE propagate beyond server finally: if not self.multithreaded: self._appLock.release() diff --git a/flup/server/scgi_base.py b/flup/server/scgi_base.py index dbc8e60..b57b401 100644 --- a/flup/server/scgi_base.py +++ b/flup/server/scgi_base.py @@ -387,18 +387,10 @@ class BaseSCGIServer(object): for header in responseHeaders: s += '%s: %s\r\n' % header s += '\r\n' - try: - request.stdout.write(s) - except socket.error, e: - if e[0] != errno.EPIPE: - raise + request.stdout.write(s) - try: - request.stdout.write(data) - request.stdout.flush() - except socket.error, e: - if e[0] != errno.EPIPE: - raise + request.stdout.write(data) + request.stdout.flush() def start_response(status, response_headers, exc_info=None): if exc_info: @@ -427,16 +419,20 @@ class BaseSCGIServer(object): if not self.multithreaded: self._appLock.acquire() try: - result = self.application(environ, start_response) try: - for data in result: - if data: - write(data) - if not headers_sent: - write('') # in case body was empty - finally: - if hasattr(result, 'close'): - result.close() + result = self.application(environ, start_response) + try: + for data in result: + if data: + write(data) + if not headers_sent: + write('') # in case body was empty + finally: + if hasattr(result, 'close'): + result.close() + except socket.error, e: + if e[0] != errno.EPIPE: + raise # Don't let EPIPE propagate beyond server finally: if not self.multithreaded: self._appLock.release() -- cgit v1.2.1