Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: third_party/twisted_8_1/twisted/web/twcgi.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/twisted_8_1/twisted/web/trp.py ('k') | third_party/twisted_8_1/twisted/web/util.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # -*- test-case-name: twisted.web.test.test_cgi -*-
2 # Copyright (c) 2001-2004 Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5
6 """I hold resource classes and helper classes that deal with CGI scripts.
7 """
8
9 # System Imports
10 import string
11 import os
12 import sys
13 import urllib
14
15 # Twisted Imports
16 from twisted.web import http
17 from twisted.internet import reactor, protocol
18 from twisted.spread import pb
19 from twisted.python import log, filepath
20
21 # Sibling Imports
22 import server
23 import error
24 import html
25 import resource
26 import static
27 from server import NOT_DONE_YET
28
29 class CGIDirectory(resource.Resource, filepath.FilePath):
30 def __init__(self, pathname):
31 resource.Resource.__init__(self)
32 filepath.FilePath.__init__(self, pathname)
33
34 def getChild(self, path, request):
35 fnp = self.child(path)
36 if not fnp.exists():
37 return static.File.childNotFound
38 elif fnp.isdir():
39 return CGIDirectory(fnp.path)
40 else:
41 return CGIScript(fnp.path)
42 return error.NoResource()
43
44 def render(self, request):
45 return error.NoResource("CGI directories do not support directory listin g.").render(request)
46
47 class CGIScript(resource.Resource):
48 """I represent a CGI script.
49
50 My implementation is complex due to the fact that it requires asynchronous
51 IPC with an external process with an unpleasant protocol.
52 """
53 isLeaf = 1
54 def __init__(self, filename, registry=None):
55 """Initialize, with the name of a CGI script file.
56 """
57 self.filename = filename
58
59 def render(self, request):
60 """Do various things to conform to the CGI specification.
61
62 I will set up the usual slew of environment variables, then spin off a
63 process.
64 """
65 script_name = "/"+string.join(request.prepath, '/')
66 python_path = string.join(sys.path, os.pathsep)
67 serverName = string.split(request.getRequestHostname(), ':')[0]
68 env = {"SERVER_SOFTWARE": server.version,
69 "SERVER_NAME": serverName,
70 "GATEWAY_INTERFACE": "CGI/1.1",
71 "SERVER_PROTOCOL": request.clientproto,
72 "SERVER_PORT": str(request.getHost().port),
73 "REQUEST_METHOD": request.method,
74 "SCRIPT_NAME": script_name, # XXX
75 "SCRIPT_FILENAME": self.filename,
76 "REQUEST_URI": request.uri,
77 }
78
79 client = request.getClient()
80 if client is not None:
81 env['REMOTE_HOST'] = client
82 ip = request.getClientIP()
83 if ip is not None:
84 env['REMOTE_ADDR'] = ip
85 pp = request.postpath
86 if pp:
87 env["PATH_INFO"] = "/"+string.join(pp, '/')
88
89 if hasattr(request, "content"):
90 # request.content is either a StringIO or a TemporaryFile, and
91 # the file pointer is sitting at the beginning (seek(0,0))
92 request.content.seek(0,2)
93 length = request.content.tell()
94 request.content.seek(0,0)
95 env['CONTENT_LENGTH'] = str(length)
96
97 qindex = string.find(request.uri, '?')
98 if qindex != -1:
99 qs = env['QUERY_STRING'] = request.uri[qindex+1:]
100 if '=' in qs:
101 qargs = []
102 else:
103 qargs = [urllib.unquote(x) for x in qs.split('+')]
104 else:
105 env['QUERY_STRING'] = ''
106 qargs = []
107
108 # Propogate HTTP headers
109 for title, header in request.getAllHeaders().items():
110 envname = string.upper(string.replace(title, '-', '_'))
111 if title not in ('content-type', 'content-length'):
112 envname = "HTTP_" + envname
113 env[envname] = header
114 # Propogate our environment
115 for key, value in os.environ.items():
116 if not env.has_key(key):
117 env[key] = value
118 # And they're off!
119 self.runProcess(env, request, qargs)
120 return NOT_DONE_YET
121
122 def runProcess(self, env, request, qargs=[]):
123 p = CGIProcessProtocol(request)
124 reactor.spawnProcess(p, self.filename, [self.filename]+qargs, env, os.pa th.dirname(self.filename))
125
126
127 class FilteredScript(CGIScript):
128 """I am a special version of a CGI script, that uses a specific executable.
129
130 This is useful for interfacing with other scripting languages that adhere
131 to the CGI standard (cf. PHPScript). My 'filter' attribute specifies what
132 executable to run, and my 'filename' init parameter describes which script
133 to pass to the first argument of that script.
134 """
135
136 filter = '/usr/bin/cat'
137
138 def runProcess(self, env, request, qargs=[]):
139 p = CGIProcessProtocol(request)
140 reactor.spawnProcess(p, self.filter, [self.filter, self.filename]+qargs, env, os.path.dirname(self.filename))
141
142
143 class PHP3Script(FilteredScript):
144 """I am a FilteredScript that uses the default PHP3 command on most systems.
145 """
146
147 filter = '/usr/bin/php3'
148
149
150 class PHPScript(FilteredScript):
151 """I am a FilteredScript that uses the PHP command on most systems.
152 Sometimes, php wants the path to itself as argv[0]. This is that time.
153 """
154
155 filter = '/usr/bin/php4'
156
157
158 class CGIProcessProtocol(protocol.ProcessProtocol, pb.Viewable):
159 handling_headers = 1
160 headers_written = 0
161 headertext = ''
162 errortext = ''
163
164 # Remotely relay producer interface.
165
166 def view_resumeProducing(self, issuer):
167 self.resumeProducing()
168
169 def view_pauseProducing(self, issuer):
170 self.pauseProducing()
171
172 def view_stopProducing(self, issuer):
173 self.stopProducing()
174
175 def resumeProducing(self):
176 self.transport.resumeProducing()
177
178 def pauseProducing(self):
179 self.transport.pauseProducing()
180
181 def stopProducing(self):
182 self.transport.loseConnection()
183
184 def __init__(self, request):
185 self.request = request
186
187 def connectionMade(self):
188 self.request.registerProducer(self, 1)
189 self.request.content.seek(0, 0)
190 content = self.request.content.read()
191 if content:
192 self.transport.write(content)
193 self.transport.closeStdin()
194
195 def errReceived(self, error):
196 self.errortext = self.errortext + error
197
198 def outReceived(self, output):
199 """
200 Handle a chunk of input
201 """
202 # First, make sure that the headers from the script are sorted
203 # out (we'll want to do some parsing on these later.)
204 if self.handling_headers:
205 text = self.headertext + output
206 headerEnds = []
207 for delimiter in '\n\n','\r\n\r\n','\r\r', '\n\r\n':
208 headerend = string.find(text,delimiter)
209 if headerend != -1:
210 headerEnds.append((headerend, delimiter))
211 if headerEnds:
212 headerEnds.sort()
213 headerend, delimiter = headerEnds[0]
214 self.headertext = text[:headerend]
215 # This is a final version of the header text.
216 linebreak = delimiter[:len(delimiter)/2]
217 headers = string.split(self.headertext, linebreak)
218 for header in headers:
219 br = string.find(header,': ')
220 if br == -1:
221 log.msg( 'ignoring malformed CGI header: %s' % header )
222 else:
223 headerName = string.lower(header[:br])
224 headerText = header[br+2:]
225 if headerName == 'location':
226 self.request.setResponseCode(http.FOUND)
227 if headerName == 'status':
228 try:
229 statusNum = int(headerText[:3]) #"XXX <descripti on>" sometimes happens.
230 except:
231 log.msg( "malformed status header" )
232 else:
233 self.request.setResponseCode(statusNum)
234 else:
235 self.request.setHeader(headerName,headerText)
236 output = text[headerend+len(delimiter):]
237 self.handling_headers = 0
238 if self.handling_headers:
239 self.headertext = text
240 if not self.handling_headers:
241 self.request.write(output)
242
243 def processEnded(self, reason):
244 if reason.value.exitCode != 0:
245 log.msg("CGI %s exited with exit code %s" %
246 (self.request.uri, reason.value.exitCode))
247 if self.errortext:
248 log.msg("Errors from CGI %s: %s" % (self.request.uri, self.errortext ))
249 if self.handling_headers:
250 log.msg("Premature end of headers in %s: %s" % (self.request.uri, se lf.headertext))
251 self.request.write(
252 error.ErrorPage(http.INTERNAL_SERVER_ERROR,
253 "CGI Script Error",
254 "Premature end of script headers.").render(self. request))
255 self.request.unregisterProducer()
256 self.request.finish()
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/web/trp.py ('k') | third_party/twisted_8_1/twisted/web/util.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698