Hi Matt
I'd certainly be interested in seeing that script, as I'd like to
compare it against the one below, which was my solution to the same
problem. However I dont really know enough about twisted to be sure this
was the right way to do it.
To be honest i cobbled this together after looking at twisted_http.py
and scanning some of the twisted src files. twisted/web/twcgi may well
have been a better place to start had I known it existed!
Cheers
Jon
from twisted.protocols import http
from twisted.web import proxy,server
from twisted.internet import reactor, protocol
HTTP_PORT = 8098
SCGI_PORT = 4000
SCGI_PROTOCOL_VERSION = "1"
class SCGIProtocol(protocol.Protocol):
def __init__(self,request):
self.request = request
self.data = ""
def connectionMade(self):
self.transport.write(self.request.get_scgi_netstring())
def connectionLost(self, reason):
self.request.write(self.data.replace("Status:","HTTP/1.1"))
self.request.finish()
def dataReceived(self,data):
self.data += data
class SCGIReverseProxyRequest(proxy.ReverseProxyRequest):
def process(self):
scgi_ns=self.get_scgi_netstring()
cc = protocol.ClientCreator(reactor,SCGIProtocol,self)
df = cc.connectTCP("localhost", SCGI_PORT)
self.startedWriting = 1
def get_scgi_netstring (self):
host = self.getHeader('host') or self.getHost()
serverName = host.split(':')[0]
content_type = self.getHeader('content-type')
typ, remote_addr, remote_port = self.transport.getPeer()
t = range(22)
bdy = self.content.read()
t[0] = "CONTENT_LENGTH",str(len(bdy or ""))
t[1]= "SCGI", SCGI_PROTOCOL_VERSION
t[2]= "SERVER_SOFTWARE", server.version or ""
t[3]= "SERVER_PROTOCOL", self.clientproto or ""
t[4]= "SERVER_NAME", serverName or ""
t[5]= "SERVER_ADMIN", ""
t[6]= "SERVER_ADDR", ""
t[7]= "SERVER_PORT", str(HTTP_PORT)
t[8]= "REMOTE_ADDR", self.getClientIP() or ""
t[9]= "REMOTE_PORT", str(remote_port) or ""
t[10]= "REMOTE_USER", self.getUser() or ""
t[11]= "REQUEST_METHOD", self.method or ""
t[12]= "REQUEST_URI", self.uri or ""
x = self.uri.split('?', 2)
if len(x) == 2:
t[13]= "QUERY_STRING", x[1] or ""
else:
t[13]= "QUERY_STRING",""
t[14]= "SCRIPT_NAME", self.uri
t[15]= "HTTP_USER_AGENT", self.getHeader("User-Agent") or ""
t[16]= "HTTP_COOKIE", self.getHeader("Cookie") or ""
t[17]= "HTTPS", "" #lookup_env(r, "HTTPS")
t[18]= "CONTENT_TYPE", self.getHeader("Content-type") or ""
t[19]= "DOCUMENT_ROOT", "" #ap_document_root(r)
t[20]= "HTTP_ACCEPT", self.getHeader("Accept") or ""
t[21]= "HTTP_REFERER", self.getHeader("Referer") or ""
### now make a netstring
buffer="".join([ "%s\0%s\0" % i for i in t])
ns = "%lu:%s,%s" % (len(buffer),buffer,bdy)
return ns
class SCGIReverseProxy(proxy.ReverseProxy):
requestFactory = SCGIReverseProxyRequest
def main():
f = http.HTTPFactory()
f.protocol = SCGIReverseProxy
reactor.listenTCP(HTTP_PORT, f)
reactor.run()
if __name__ == '__main__':
main()