Set timeout for client socket (slow client DoS).

This commit is contained in:
Konstantin Kapustin 2012-09-07 17:08:28 +04:00 committed by benoitc
parent 75933bae81
commit aa22115cfc
3 changed files with 13 additions and 0 deletions

View File

@ -28,6 +28,7 @@ class AsyncWorker(base.Worker):
def handle(self, client, addr): def handle(self, client, addr):
req = None req = None
try: try:
client.settimeout(self.cfg.timeout)
parser = http.RequestParser(self.cfg, client) parser = http.RequestParser(self.cfg, client)
try: try:
if not self.cfg.keepalive: if not self.cfg.keepalive:
@ -46,8 +47,12 @@ class AsyncWorker(base.Worker):
self.log.debug("Ignored premature client disconnection. %s", e) self.log.debug("Ignored premature client disconnection. %s", e)
except StopIteration, e: except StopIteration, e:
self.log.debug("Closing connection. %s", e) self.log.debug("Closing connection. %s", e)
except socket.error:
raise # pass to next try-except level
except Exception, e: except Exception, e:
self.handle_error(req, client, addr, e) self.handle_error(req, client, addr, e)
except socket.timeout as e:
self.handle_error(req, client, addr, e)
except socket.error, e: except socket.error, e:
if e[0] not in (errno.EPIPE, errno.ECONNRESET): if e[0] not in (errno.EPIPE, errno.ECONNRESET):
self.log.exception("Socket error processing request.") self.log.exception("Socket error processing request.")

View File

@ -8,6 +8,7 @@ import os
import signal import signal
import sys import sys
import traceback import traceback
import socket
from gunicorn import util from gunicorn import util
@ -155,6 +156,10 @@ class Worker(object):
error=str(exc), error=str(exc),
) )
) )
elif isinstance(exc, socket.timeout):
status_int = 408
reason = "Request Timeout"
mesg = "<p>The server timed out handling for the request</p>"
else: else:
self.log.exception("Error handling request") self.log.exception("Error handling request")

View File

@ -67,6 +67,7 @@ class SyncWorker(base.Worker):
def handle(self, client, addr): def handle(self, client, addr):
req = None req = None
try: try:
client.settimeout(self.cfg.timeout)
parser = http.RequestParser(self.cfg, client) parser = http.RequestParser(self.cfg, client)
req = parser.next() req = parser.next()
self.handle_request(req, client, addr) self.handle_request(req, client, addr)
@ -74,6 +75,8 @@ class SyncWorker(base.Worker):
self.log.debug("Ignored premature client disconnection. %s", e) self.log.debug("Ignored premature client disconnection. %s", e)
except StopIteration, e: except StopIteration, e:
self.log.debug("Closing connection. %s", e) self.log.debug("Closing connection. %s", e)
except socket.timeout as e:
self.handle_error(req, client, addr, e)
except socket.error, e: except socket.error, e:
if e[0] != errno.EPIPE: if e[0] != errno.EPIPE:
self.log.exception("Error processing request.") self.log.exception("Error processing request.")