1- # $Id: client.py,v 1.228 2006-11-09 00:36:21 richard Exp $
1+ # $Id: client.py,v 1.229 2006-11-15 06:27:15 a1s Exp $
22
33"""WWW request handler (also used in the stand-alone server).
44"""
@@ -109,6 +109,24 @@ class Client:
109109 # columns, sort, sortdir, filter, group, groupdir, search_text,
110110 # pagesize, startwith
111111
112+ # list of network error codes that shouldn't be reported to tracker admin
113+ # (error descriptions from FreeBSD intro(2))
114+ IGNORE_NET_ERRORS = (
115+ # A write on a pipe, socket or FIFO for which there is
116+ # no process to read the data.
117+ errno .EPIPE ,
118+ # A connection was forcibly closed by a peer.
119+ # This normally results from a loss of the connection
120+ # on the remote socket due to a timeout or a reboot.
121+ errno .ECONNRESET ,
122+ # Software caused connection abort. A connection abort
123+ # was caused internal to your host machine.
124+ errno .ECONNABORTED ,
125+ # A connect or send request failed because the connected party
126+ # did not properly respond after a period of time.
127+ errno .ETIMEDOUT ,
128+ )
129+
112130 def __init__ (self , instance , request , env , form = None , translator = None ):
113131 # re-seed the random number generator
114132 random .seed ()
@@ -819,16 +837,25 @@ def get_action_class(self, action_name):
819837 raise ValueError , 'No such action "%s"' % action_name
820838 return action_klass
821839
840+ def _socket_op (self , call , * args , ** kwargs ):
841+ """Execute socket-related operation, catch common network errors
842+
843+ Parameters:
844+ call: a callable to execute
845+ args, kwargs: call arguments
846+
847+ """
848+ try :
849+ call (* args , ** kwargs )
850+ except socket .error , err :
851+ if err .errno not in self .IGNORE_NET_ERRORS :
852+ raise
853+
822854 def write (self , content ):
823855 if not self .headers_done :
824856 self .header ()
825857 if self .env ['REQUEST_METHOD' ] != 'HEAD' :
826- try :
827- self .request .wfile .write (content )
828- except socket .error , error :
829- # the end-user has gone away
830- if error .errno != errno .EPIPE :
831- raise
858+ self ._socket_op (self .request .wfile .write , content )
832859
833860 def write_html (self , content ):
834861 if not self .headers_done :
@@ -847,12 +874,7 @@ def write_html(self, content):
847874 content = content .encode (self .charset , 'xmlcharrefreplace' )
848875
849876 # and write
850- try :
851- self .request .wfile .write (content )
852- except socket .error , error :
853- # the end-user has gone away
854- if error .errno != errno .EPIPE :
855- raise
877+ self ._socket_op (self .request .wfile .write , content )
856878
857879 def setHeader (self , header , value ):
858880 '''Override a header to be returned to the user's browser.
@@ -881,7 +903,7 @@ def header(self, headers=None, response=None):
881903 cookie += " expires=%s;" % Cookie ._getdate (expire )
882904 headers .append (('Set-Cookie' , cookie ))
883905
884- self .request .start_response ( headers , response )
906+ self ._socket_op ( self . request .start_response , headers , response )
885907
886908 self .headers_done = 1
887909 if self .debug :
0 commit comments