fix parser + write function

This commit is contained in:
benoitc 2010-01-18 17:23:26 +01:00
parent ccd24a15ae
commit f583b618df
7 changed files with 44 additions and 24 deletions

View File

@ -139,7 +139,6 @@ class Arbiter(object):
self.manage_workers() self.manage_workers()
while True: while True:
try: try:
sig = self.SIG_QUEUE.pop(0) if len(self.SIG_QUEUE) else None sig = self.SIG_QUEUE.pop(0) if len(self.SIG_QUEUE) else None
if sig is None: if sig is None:
self.sleep() self.sleep()

View File

@ -148,10 +148,10 @@ class HttpParser(object):
if chunk_size <= 0: if chunk_size <= 0:
self._chunk_eof = True self._chunk_eof = True
# we put data # we put data
return None, data[:end_offset] return '', data[:end_offset]
self.chunk_size = 0 self.chunk_size = 0
return buf[chunk_size:], data[:end_offset] return buf[chunk_size:], data[:end_offset]
return None, data return '', data
def trailing_header(self, data): def trailing_header(self, data):
i = data.find("\r\n\r\n") i = data.find("\r\n\r\n")
@ -164,17 +164,17 @@ class HttpParser(object):
""" """
dlen = len(data) dlen = len(data)
chunk = None chunk = ''
if self.is_chunked: if self.is_chunked:
chunk, data = self.read_chunk(data) chunk, data = self.read_chunk(data)
if not chunk: if not chunk:
return None, data return '', data
else: else:
if self._content_len > 0: if self._content_len > 0:
nr = min(dlen, self._content_len) nr = min(dlen, self._content_len)
chunk = data[:nr] chunk = data[:nr]
self._content_len -= nr self._content_len -= nr
data = None data = ''
self.start_offset = 0 self.start_offset = 0
return (chunk, data) return (chunk, data)

View File

@ -54,6 +54,19 @@ class RequestError(Exception):
class HTTPRequest(object): class HTTPRequest(object):
SERVER_VERSION = "gunicorn/%s" % __version__ SERVER_VERSION = "gunicorn/%s" % __version__
DEFAULTS = {
"wsgi.url_scheme": 'http',
"wsgi.input": StringIO.StringIO(),
"wsgi.errors": sys.stderr,
"wsgi.version": (1, 0),
"wsgi.multithread": False,
"wsgi.multiprocess": True,
"wsgi.run_once": False,
"SCRIPT_NAME": "",
"SERVER_SOFTWARE": "gunicorn/%s" % __version__
}
def __init__(self, socket, client_address, server_address): def __init__(self, socket, client_address, server_address):
self.socket = socket self.socket = socket
@ -68,6 +81,7 @@ class HTTPRequest(object):
self.log = logging.getLogger(__name__) self.log = logging.getLogger(__name__)
def read(self): def read(self):
environ = {}
headers = {} headers = {}
remain = CHUNK_SIZE remain = CHUNK_SIZE
buf = "" buf = ""
@ -82,7 +96,8 @@ class HTTPRequest(object):
if i != -1: break if i != -1: break
if not headers: if not headers:
return {} environ.update(self.DEFAULTS)
return environ
buf = buf[i:] buf = buf[i:]
@ -139,4 +154,4 @@ class HTTPRequest(object):
if not isinstance(value, basestring): if not isinstance(value, basestring):
value = str(value) value = str(value)
self.response_headers[name] = value.strip() self.response_headers[name] = value.strip()
self.start_response_called = True self.start_response_called = True

View File

@ -58,11 +58,12 @@ class HTTPResponse(object):
write(self.sock, "%s\r\n" % "".join(resp_head)) write(self.sock, "%s\r\n" % "".join(resp_head))
for chunk in self.data:
for chunk in list(self.data):
write(self.sock, chunk) write(self.sock, chunk)
close(self.sock) close(self.sock)
if hasattr(self.data, "close"): if hasattr(self.data, "close"):
self.data.close() self.data.close()

View File

@ -35,7 +35,7 @@ import os
import StringIO import StringIO
import tempfile import tempfile
from gunicorn.util import MAX_BODY, CHUNK_SIZE from gunicorn.util import MAX_BODY, CHUNK_SIZE, read_partial
class TeeInput(object): class TeeInput(object):
@ -51,7 +51,6 @@ class TeeInput(object):
if len(buf) > 0: if len(buf) > 0:
chunk, self.buf = parser.filter_body(buf) chunk, self.buf = parser.filter_body(buf)
print chunk
if chunk: if chunk:
self.tmp.write(chunk) self.tmp.write(chunk)
self.tmp.seek(0) self.tmp.seek(0)
@ -61,7 +60,7 @@ class TeeInput(object):
def len(self): def len(self):
if self._len: return self._len if self._len: return self._len
if self.socket: if self.socket:
pos = self.tmp.tell() pos = self.tmp.tell()
while True: while True:
if not self._tee(CHUNK_SIZE): if not self._tee(CHUNK_SIZE):
break break
@ -79,10 +78,12 @@ class TeeInput(object):
if length is None: if length is None:
r = self.tmp.read() or "" r = self.tmp.read() or ""
print "avant %s" % str(len(r))
while True: while True:
chunk = self._tee(CHUNK_SIZE) chunk = self._tee(CHUNK_SIZE)
if not chunk: break if not chunk: break
r += chunk r += chunk
print "apres %s" % str(len(r))
return r return r
else: else:
diff = self._tmp_size() - self.tmp.tell() diff = self._tmp_size() - self.tmp.tell()
@ -139,7 +140,9 @@ class TeeInput(object):
data = read_partial(self.socket, length) data = read_partial(self.socket, length)
self.buf += data self.buf += data
chunk, self.buf = self.parser.filter_body(self.buf) chunk, self.buf = self.parser.filter_body(self.buf)
print self.buf
if chunk: if chunk:
print chunk
self.tmp.write(chunk) self.tmp.write(chunk)
self.tmp.seek(0, os.SEEK_END) self.tmp.seek(0, os.SEEK_END)
return chunk return chunk
@ -165,9 +168,9 @@ class TeeInput(object):
else: else:
return int(os.fstat(self.tmp.fileno())[6]) return int(os.fstat(self.tmp.fileno())[6])
def _ensure_length(buf, length): def _ensure_length(self, buf, length):
if not buf or not self._len: if not buf or not self._len:
return buf return buf
while len(buf) < length and self.len != self.tmp.pos(): while len(buf) < length and self.len != self.tmp.tell():
buf += self._tee(length - len(buf)) buf += self._tee(length - len(buf))
return buf return buf

View File

@ -70,16 +70,19 @@ def read_partial(sock, length):
def write(sock, data): def write(sock, data):
buf = "" buf = ""
buf += data buf += data
dlen = len(data)
while buf: while buf:
try: try:
bytes = sock.send(buf) bytes = sock.send(buf)
buf = buf[bytes:] if bytes < dlen:
return bytes buf = buf[bytes:]
continue
return dlen
except socket.error, e: except socket.error, e:
if e[0] in (errno.EWOULDBLOCK, errno.EAGAIN): if e[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
break raise
elif e[0] in (errno.EPIPE,): elif e[0] in (errno.EPIPE,):
continue break
raise raise
def write_nonblock(sock, data): def write_nonblock(sock, data):

View File

@ -116,7 +116,7 @@ class Worker(object):
while self.alive: while self.alive:
try: try:
client, addr = self.socket.accept() client, addr = self.socket.accept()
# handle connection # handle connection
self.handle(client, addr) self.handle(client, addr)
@ -139,7 +139,6 @@ class Worker(object):
except Exception, e: except Exception, e:
self.log.exception("Error processing request. [%s]" % str(e)) self.log.exception("Error processing request. [%s]" % str(e))
msg = "HTTP/1.0 500 Internal Server Error\r\n\r\n" msg = "HTTP/1.0 500 Internal Server Error\r\n\r\n"
#util.write_nonblock(client, msg)
util.close(client) util.close(client)
del client del client