some fixes

This commit is contained in:
Benoit Chesneau 2010-01-16 03:20:11 +01:00
parent 5324d3cb60
commit 9900371813
5 changed files with 39 additions and 28 deletions

View File

@ -49,7 +49,7 @@ class Arbiter(object):
SIG_QUEUE = []
SIGNALS = map(
lambda x: getattr(signal, "SIG%s" % x),
"CHLD HUP QUIT INT TERM TTIN TTOU USR1 USR2 WINCH".split()
"HUP QUIT INT TERM TTIN TTOU USR1 USR2 WINCH".split()
)
SIG_NAMES = dict(
(getattr(signal, name), name[3:].lower()) for name in dir(signal)
@ -74,6 +74,7 @@ class Arbiter(object):
map(self.set_non_blocking, pair)
map(lambda p: fcntl.fcntl(p, fcntl.F_SETFD, fcntl.FD_CLOEXEC), pair)
map(lambda s: signal.signal(s, self.signal), self.SIGNALS)
signal.signal(signal.SIGCHLD, self.handle_chld)
def set_non_blocking(self, fd):
flags = fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK
@ -125,7 +126,7 @@ class Arbiter(object):
sock.listen(2048)
return sock
def set_sockopts(self, sock):
def set_sockopts(self, sock):
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
if hasattr(socket, "TCP_CORK"):
@ -170,7 +171,7 @@ class Arbiter(object):
log.info("Master is shutting down.")
self.stop()
def handle_chld(self):
def handle_chld(self, sig, frame):
self.wakeup()
def handle_hup(self):

View File

@ -37,6 +37,8 @@ class HttpParser(object):
""" take a string buff. It return
environ or None if parsing isn't done.
"""
if self._headers:
return self._headers
# wee could be smarter here
# by just reading the array, but converting
@ -69,7 +71,7 @@ class HttpParser(object):
except ValueError:
# bad headers
pass
headers = self._headers
headers.update(self._headers)
self._content_len = int(self._headers.get('Content-Length') or 0)
return headers

View File

@ -55,7 +55,7 @@ class HTTPRequest(object):
SERVER_VERSION = "gunicorn/%s" % __version__
def __init__(self, socket, client_address, server_address):
self.socket = socket
self.socket = socket.dup()
self.client_address = client_address
self.server_address = server_address
self.response_status = None
@ -69,12 +69,14 @@ class HTTPRequest(object):
remain = CHUNK_SIZE
buf = create_string_buffer(remain)
remain -= self.socket.recv_into(buf, remain)
while not self.parser.headers(headers, buf):
data = create_string_buffer(remain)
remain -= self.socket.recv_into(data, remain)
buf = create_string_buffer(data.value + buf.value)
if headers.get('Accept', '').lower() == "100-continue":
print headers
if headers.get('Except', '').lower() == "100-continue":
self.socket.send("100 Continue\n")
if "?" in self.parser.path:

View File

@ -24,35 +24,41 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
import time
from gunicorn.util import http_date
class HTTPResponse(object):
def __init__(self, req, data):
self.req = req
self.data = data
self.headers = self.req.response_headers or {}
def __init__(self, sock, response, req):
self.sock = sock
self.data = response
self.headers = req.response_headers or {}
self.status = req.response_status
self.SERVER_VERSION = req.SERVER_VERSION
def send(self):
# send headers
resp_head = []
resp_head.append("%s %ss\r\n" % (self.req.parser.version, self.req.response_status))
resp_head.append("HTTP/1.1 %s\r\n" % (self.status))
resp_head.append("Server: %s\r\n" % self.req.SERVER_VERSION)
resp_head.append("Server: %s\r\n" % self.SERVER_VERSION)
resp_head.append("Date: %s\r\n" % http_date())
# broken clients
resp_head.append("Status: %s\r\n" % str(self.req.response_status))
resp_head.append("Status: %s\r\n" % str(self.status))
# always close the conenction
resp_head.append("Connection: close\r\n")
for name, value in self.req.response_headers.items():
for name, value in self.headers.items():
resp_head.append("%s: %s\r\n" % (name, value))
self.req.socket.send("%s\r\n" % "".join(resp_head))
self.sock.send("%s\r\n" % "".join(resp_head))
for chunk in self.data:
self.req.socket.send(chunk)
self.req.socket.close()
for chunk in self.data:
self.sock.send(chunk)
print "sent"
self.sock.close()
if hasattr(self.data, "close"):
self.data.close()

View File

@ -106,36 +106,36 @@ class Worker(object):
return
raise
# Accept until we hit EAGAIN. We're betting that when we're
# processing clients that more clients are waiting. When
# there's no more clients waiting we go back to the select()
# loop and wait for some lovin.
while self.alive:
#time.sleep(0.01)
try:
conn, addr = self.socket.accept()
conn.setblocking(1)
# handle connection
self.handle(conn, addr)
# Update the fd mtime on each client completion
# to signal that this worker process is alive.
spinner = (spinner+1) % 2
self._fchmod(spinner)
# handle connection
self.handle(conn, addr)
except socket.error, e:
if e[0] in [errno.EAGAIN, errno.ECONNABORTED]:
break # Uh oh!
raise
def handle(self, conn, client):
self.close_on_exec(conn)
try:
req = http.HTTPRequest(conn, client, self.address)
result = self.app(req.read(), req.start_response)
response = http.HTTPResponse(req, result)
response.send()
response = self.app(req.read(), req.start_response)
http.HTTPResponse(conn, response, req).send()
except Exception, e:
log.exception("Error processing request. [%s]" % str(e))
if e[0] == 32: