aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/twcgi.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/twcgi.py')
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/twcgi.py299
1 files changed, 0 insertions, 299 deletions
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/twcgi.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/twcgi.py
deleted file mode 100755
index 5ab580dd..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/web/twcgi.py
+++ /dev/null
@@ -1,299 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_cgi -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""
-I hold resource classes and helper classes that deal with CGI scripts.
-"""
-
-# System Imports
-import string
-import os
-import urllib
-
-# Twisted Imports
-from twisted.web import http
-from twisted.internet import reactor, protocol
-from twisted.spread import pb
-from twisted.python import log, filepath
-from twisted.web import resource, server, static
-
-
-class CGIDirectory(resource.Resource, filepath.FilePath):
- def __init__(self, pathname):
- resource.Resource.__init__(self)
- filepath.FilePath.__init__(self, pathname)
-
- def getChild(self, path, request):
- fnp = self.child(path)
- if not fnp.exists():
- return static.File.childNotFound
- elif fnp.isdir():
- return CGIDirectory(fnp.path)
- else:
- return CGIScript(fnp.path)
- return resource.NoResource()
-
- def render(self, request):
- notFound = resource.NoResource(
- "CGI directories do not support directory listing.")
- return notFound.render(request)
-
-
-
-class CGIScript(resource.Resource):
- """
- L{CGIScript} is a resource which runs child processes according to the CGI
- specification.
-
- The implementation is complex due to the fact that it requires asynchronous
- IPC with an external process with an unpleasant protocol.
- """
- isLeaf = 1
- def __init__(self, filename, registry=None):
- """
- Initialize, with the name of a CGI script file.
- """
- self.filename = filename
-
-
- def render(self, request):
- """
- Do various things to conform to the CGI specification.
-
- I will set up the usual slew of environment variables, then spin off a
- process.
-
- @type request: L{twisted.web.http.Request}
- @param request: An HTTP request.
- """
- script_name = "/"+string.join(request.prepath, '/')
- serverName = string.split(request.getRequestHostname(), ':')[0]
- env = {"SERVER_SOFTWARE": server.version,
- "SERVER_NAME": serverName,
- "GATEWAY_INTERFACE": "CGI/1.1",
- "SERVER_PROTOCOL": request.clientproto,
- "SERVER_PORT": str(request.getHost().port),
- "REQUEST_METHOD": request.method,
- "SCRIPT_NAME": script_name, # XXX
- "SCRIPT_FILENAME": self.filename,
- "REQUEST_URI": request.uri,
- }
-
- client = request.getClient()
- if client is not None:
- env['REMOTE_HOST'] = client
- ip = request.getClientIP()
- if ip is not None:
- env['REMOTE_ADDR'] = ip
- pp = request.postpath
- if pp:
- env["PATH_INFO"] = "/"+string.join(pp, '/')
-
- if hasattr(request, "content"):
- # request.content is either a StringIO or a TemporaryFile, and
- # the file pointer is sitting at the beginning (seek(0,0))
- request.content.seek(0,2)
- length = request.content.tell()
- request.content.seek(0,0)
- env['CONTENT_LENGTH'] = str(length)
-
- qindex = string.find(request.uri, '?')
- if qindex != -1:
- qs = env['QUERY_STRING'] = request.uri[qindex+1:]
- if '=' in qs:
- qargs = []
- else:
- qargs = [urllib.unquote(x) for x in qs.split('+')]
- else:
- env['QUERY_STRING'] = ''
- qargs = []
-
- # Propogate HTTP headers
- for title, header in request.getAllHeaders().items():
- envname = string.upper(string.replace(title, '-', '_'))
- if title not in ('content-type', 'content-length'):
- envname = "HTTP_" + envname
- env[envname] = header
- # Propogate our environment
- for key, value in os.environ.items():
- if key not in env:
- env[key] = value
- # And they're off!
- self.runProcess(env, request, qargs)
- return server.NOT_DONE_YET
-
-
- def runProcess(self, env, request, qargs=[]):
- """
- Run the cgi script.
-
- @type env: A C{dict} of C{str}, or C{None}
- @param env: The environment variables to pass to the processs that will
- get spawned. See
- L{twisted.internet.interfaces.IReactorProcess.spawnProcess} for more
- information about environments and process creation.
-
- @type request: L{twisted.web.http.Request}
- @param request: An HTTP request.
-
- @type qargs: A C{list} of C{str}
- @param qargs: The command line arguments to pass to the process that
- will get spawned.
- """
- p = CGIProcessProtocol(request)
- reactor.spawnProcess(p, self.filename, [self.filename] + qargs, env,
- os.path.dirname(self.filename))
-
-
-
-class FilteredScript(CGIScript):
- """
- I am a special version of a CGI script, that uses a specific executable.
-
- This is useful for interfacing with other scripting languages that adhere to
- the CGI standard. My C{filter} attribute specifies what executable to run,
- and my C{filename} init parameter describes which script to pass to the
- first argument of that script.
-
- To customize me for a particular location of a CGI interpreter, override
- C{filter}.
-
- @type filter: C{str}
- @ivar filter: The absolute path to the executable.
- """
-
- filter = '/usr/bin/cat'
-
-
- def runProcess(self, env, request, qargs=[]):
- """
- Run a script through the C{filter} executable.
-
- @type env: A C{dict} of C{str}, or C{None}
- @param env: The environment variables to pass to the processs that will
- get spawned. See
- L{twisted.internet.interfaces.IReactorProcess.spawnProcess} for more
- information about environments and process creation.
-
- @type request: L{twisted.web.http.Request}
- @param request: An HTTP request.
-
- @type qargs: A C{list} of C{str}
- @param qargs: The command line arguments to pass to the process that
- will get spawned.
- """
- p = CGIProcessProtocol(request)
- reactor.spawnProcess(p, self.filter,
- [self.filter, self.filename] + qargs, env,
- os.path.dirname(self.filename))
-
-
-
-class CGIProcessProtocol(protocol.ProcessProtocol, pb.Viewable):
- handling_headers = 1
- headers_written = 0
- headertext = ''
- errortext = ''
-
- # Remotely relay producer interface.
-
- def view_resumeProducing(self, issuer):
- self.resumeProducing()
-
- def view_pauseProducing(self, issuer):
- self.pauseProducing()
-
- def view_stopProducing(self, issuer):
- self.stopProducing()
-
- def resumeProducing(self):
- self.transport.resumeProducing()
-
- def pauseProducing(self):
- self.transport.pauseProducing()
-
- def stopProducing(self):
- self.transport.loseConnection()
-
- def __init__(self, request):
- self.request = request
-
- def connectionMade(self):
- self.request.registerProducer(self, 1)
- self.request.content.seek(0, 0)
- content = self.request.content.read()
- if content:
- self.transport.write(content)
- self.transport.closeStdin()
-
- def errReceived(self, error):
- self.errortext = self.errortext + error
-
- def outReceived(self, output):
- """
- Handle a chunk of input
- """
- # First, make sure that the headers from the script are sorted
- # out (we'll want to do some parsing on these later.)
- if self.handling_headers:
- text = self.headertext + output
- headerEnds = []
- for delimiter in '\n\n','\r\n\r\n','\r\r', '\n\r\n':
- headerend = text.find(delimiter)
- if headerend != -1:
- headerEnds.append((headerend, delimiter))
- if headerEnds:
- # The script is entirely in control of response headers; disable the
- # default Content-Type value normally provided by
- # twisted.web.server.Request.
- self.request.defaultContentType = None
-
- headerEnds.sort()
- headerend, delimiter = headerEnds[0]
- self.headertext = text[:headerend]
- # This is a final version of the header text.
- linebreak = delimiter[:len(delimiter)//2]
- headers = self.headertext.split(linebreak)
- for header in headers:
- br = header.find(': ')
- if br == -1:
- log.msg( 'ignoring malformed CGI header: %s' % header )
- else:
- headerName = header[:br].lower()
- headerText = header[br+2:]
- if headerName == 'location':
- self.request.setResponseCode(http.FOUND)
- if headerName == 'status':
- try:
- statusNum = int(headerText[:3]) #"XXX <description>" sometimes happens.
- except:
- log.msg( "malformed status header" )
- else:
- self.request.setResponseCode(statusNum)
- else:
- # Don't allow the application to control these required headers.
- if headerName.lower() not in ('server', 'date'):
- self.request.responseHeaders.addRawHeader(headerName, headerText)
- output = text[headerend+len(delimiter):]
- self.handling_headers = 0
- if self.handling_headers:
- self.headertext = text
- if not self.handling_headers:
- self.request.write(output)
-
- def processEnded(self, reason):
- if reason.value.exitCode != 0:
- log.msg("CGI %s exited with exit code %s" %
- (self.request.uri, reason.value.exitCode))
- if self.errortext:
- log.msg("Errors from CGI %s: %s" % (self.request.uri, self.errortext))
- if self.handling_headers:
- log.msg("Premature end of headers in %s: %s" % (self.request.uri, self.headertext))
- self.request.write(
- resource.ErrorPage(http.INTERNAL_SERVER_ERROR,
- "CGI Script Error",
- "Premature end of script headers.").render(self.request))
- self.request.unregisterProducer()
- self.request.finish()