/usr/share/pyshared/twisted/web2/channel/scgi.py is in python-twisted-web2 8.1.0-3build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | from twisted.internet import protocol
from twisted.web2 import responsecode
from twisted.web2.channel import cgi as cgichannel
class SCGIChannelRequest(cgichannel.BaseCGIChannelRequest):
scgi_vers = "1"
_data = ""
headerLen = None
def __init__(self):
pass
def writeHeaders(self, code, headers):
l = []
code_message = responsecode.RESPONSES.get(code, "Unknown Status")
l.append("Status: %s %s\n" % (code, code_message))
if headers is not None:
for name, valuelist in headers.getAllRawHeaders():
for value in valuelist:
l.append("%s: %s\r\n" % (name, value))
l.append('\r\n')
self.transport.writeSequence(l)
def makeRequest(self, vars):
scgi_vers = vars['SCGI']
if scgi_vers != self.scgi_vers:
_abortWithError(responsecode.INTERNAL_SERVER_ERROR, "Twisted.web SCGITransport: Unknown SCGI version %s" % vars['SCGI'])
cgichannel.BaseCGIChannelRequest.makeRequest(self, vars)
def dataReceived(self, data):
if self.request is None:
# Reading headers
self._data += data
if self.headerLen is None:
# Haven't gotten a length prefix yet
datas = data.split(':', 1)
if len(datas) == 1:
return
self.headerLen = int(datas[0]) + 1 # +1 for the "," at the end
self._data = datas[1]
if len(self._data) >= self.headerLen:
# Got all headers
headerdata=self._data[:self.headerLen]
data=self._data[self.headerLen:]
items = headerdata.split('\0')
assert (len(items) % 2) == 1, "malformed headers"
assert items[-1]==','
env = {}
for i in range(0, len(items) - 1, 2):
env[items[i]] = items[i+1]
self.makeRequest(env)
self.request.process()
if self._dataRemaining == 0:
self.request.handleContentComplete()
return
if not data:
return # no extra data in this packet
# Fall through, self.request is now set, handle data
else:
return
if self._dataRemaining <= 0:
return
if self._dataRemaining < len(data):
data = data[:self._dataRemaining]
self._dataRemaining -= len(data)
self.request.handleContentChunk(data)
if self._dataRemaining == 0:
self.request.handleContentComplete()
def connectionLost(self, reason):
if self.request is not None:
self.request.connectionLost(reason)
class SCGIFactory(protocol.ServerFactory):
protocol = SCGIChannelRequest
def __init__(self, requestFactory):
self.requestFactory=requestFactory
def buildProtocol(self, addr):
p = protocol.ServerFactory.buildProtocol(self, addr)
p.requestFactory=self.requestFactory
return p
__all__ = ['SCGIFactory']
|