summaryrefslogtreecommitdiff
path: root/wsgitools/scgi/asynchronous.py
diff options
context:
space:
mode:
Diffstat (limited to 'wsgitools/scgi/asynchronous.py')
-rw-r--r--wsgitools/scgi/asynchronous.py50
1 files changed, 24 insertions, 26 deletions
diff --git a/wsgitools/scgi/asynchronous.py b/wsgitools/scgi/asynchronous.py
index 386e1d0..51c1d55 100644
--- a/wsgitools/scgi/asynchronous.py
+++ b/wsgitools/scgi/asynchronous.py
@@ -1,16 +1,12 @@
__all__ = []
import asyncore
+import io
import socket
import sys
-# Cannot use io module as it is broken in 2.6.
-# Writing a str to a io.StringIO results in an exception.
-try:
- import cStringIO as io
-except ImportError:
- import StringIO as io
import errno
+from wsgitools.internal import bytes2str, str2bytes
from wsgitools.scgi import _convert_environ, FileWrapper
if sys.version_info[0] >= 3:
@@ -42,20 +38,21 @@ class SCGIConnection(asyncore.dispatcher):
self.state = SCGIConnection.NEW # internal state
self.environ = config.copy() # environment passed to wsgi app
self.reqlen = -1 # request length used in two different meanings
- self.inbuff = "" # input buffer
- self.outbuff = "" # output buffer
+ self.inbuff = b"" # input buffer
+ self.outbuff = b"" # output buffer
self.wsgihandler = None # wsgi application
self.wsgiiterator = None # wsgi application iterator
self.outheaders = () # headers to be sent
# () -> unset, (..,..) -> set, True -> sent
- self.body = io.StringIO() # request body
+ self.body = io.BytesIO() # request body
def _try_send_headers(self):
if self.outheaders != True:
assert not self.outbuff
status, headers = self.outheaders
headdata = "".join(map("%s: %s\r\n".__mod__, headers))
- self.outbuff = "Status: %s\r\n%s\r\n" % (status, headdata)
+ headdata = "Status: %s\r\n%s\r\n" % (status, headdata)
+ self.outbuff = str2bytes(headdata)
self.outheaders = True
def _wsgi_write(self, data):
@@ -79,12 +76,13 @@ class SCGIConnection(asyncore.dispatcher):
data = self.recv(self.blocksize)
self.inbuff += data
if self.state == SCGIConnection.NEW:
- if ':' in self.inbuff:
- reqlen, self.inbuff = self.inbuff.split(':', 1)
- if not reqlen.isdigit():
+ if b':' in self.inbuff:
+ reqlen, self.inbuff = self.inbuff.split(b':', 1)
+ try:
+ reqlen = int(reqlen)
+ except ValueError: # invalid request format
self.close()
- return # invalid request format
- reqlen = int(reqlen)
+ return
if reqlen > self.maxrequestsize:
self.close()
return # request too long
@@ -98,20 +96,21 @@ class SCGIConnection(asyncore.dispatcher):
buff = self.inbuff[:self.reqlen]
remainder = self.inbuff[self.reqlen:]
- while buff.count('\0') >= 2:
- key, value, buff = buff.split('\0', 2)
- self.environ[key] = value
+ while buff.count(b'\0') >= 2:
+ key, value, buff = buff.split(b'\0', 2)
+ self.environ[bytes2str(key)] = bytes2str(value)
self.reqlen -= len(key) + len(value) + 2
self.inbuff = buff + remainder
if self.reqlen == 0:
- if self.inbuff.startswith(','):
+ if self.inbuff.startswith(b','):
self.inbuff = self.inbuff[1:]
- if not self.environ.get("CONTENT_LENGTH", "bad").isdigit():
+ try:
+ self.reqlen = int(self.environ["CONTENT_LENGTH"])
+ except ValueError:
self.close()
return
- self.reqlen = int(self.environ["CONTENT_LENGTH"])
if self.reqlen > self.maxpostsize:
self.close()
return
@@ -124,7 +123,7 @@ class SCGIConnection(asyncore.dispatcher):
if len(self.inbuff) >= self.reqlen:
self.body.write(self.inbuff[:self.reqlen])
self.body.seek(0)
- self.inbuff = ""
+ self.inbuff = b""
self.reqlen = 0
_convert_environ(self.environ)
self.environ["wsgi.input"] = self.body
@@ -141,7 +140,7 @@ class SCGIConnection(asyncore.dispatcher):
else:
self.body.write(self.inbuff)
self.reqlen -= len(self.inbuff)
- self.inbuff = ""
+ self.inbuff = b""
def start_response(self, status, headers, exc_info=None):
assert isinstance(status, str)
@@ -170,7 +169,7 @@ class SCGIConnection(asyncore.dispatcher):
if len(self.outbuff) < self.blocksize:
self._try_send_headers()
for data in self.wsgiiterator:
- assert isinstance(data, str)
+ assert isinstance(data, bytes)
if data:
self.outbuff += data
break
@@ -262,7 +261,7 @@ class SCGIServer(asyncore.dispatcher):
"""asyncore interface"""
try:
ret = self.accept()
- except socket.error, err:
+ except socket.error as err:
# See http://bugs.python.org/issue6706
if err.args[0] not in (errno.ECONNABORTED, errno.EAGAIN):
raise
@@ -275,4 +274,3 @@ class SCGIServer(asyncore.dispatcher):
"""Runs the server. It will not return and you can invoke
C{asyncore.loop()} instead achieving the same effect."""
asyncore.loop()
-