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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
|
"""
A Webware HTTPRequest object, implemented based on the WSGI request
environment dictionary.
"""
import time
import traceback
import cgi
from wkcommon import NoDefault, requestURI, deprecated
from Cookie import SimpleCookie as Cookie
class HTTPRequest(object):
def __init__(self, transaction, environ):
self._environ = environ
self._transaction = transaction
if environ.has_key('webkit.time'):
self._time = environ['webkit.time']
else:
self._time = time.time()
self._input = environ['wsgi.input']
self._setupPath()
self._setupFields()
self._setupCookies()
self._pathInfo = None
self._serverRootPath = ""
# @@: I'm leaving out automatic path sessions
self._sessionExpired = False
def _setupPath(self):
self._environ['PATH_INFO'] = self._environ.get('PATH_INFO', '')
if not self._environ.has_key('REQUEST_URI'):
self._environ['REQUEST_URI'] = requestURI(self._environ)
# @@: Not necessarily true for WSGI:
self._adapterName = self._environ.get('SCRIPT_NAME')
def _setupFields(self):
self._fieldStorage = cgi.FieldStorage(
self._input,
environ=self._environ,
keep_blank_values=True,
strict_parsing=False)
try:
keys = self._fieldStorage.keys()
except TypeError:
# Maybe an XML-RPC request
keys = []
dict = {}
for key in keys:
value = self._fieldStorage[key]
if not isinstance(value, list):
if not value.filename:
# Turn the MiniFieldStorage into a string:
value = value.value
else:
value = [v.value for v in value]
dict[key] = value
if self._environ['REQUEST_METHOD'].upper() == 'POST':
# Then we must also parse GET variables
self._getFields = cgi.parse_qs(
self._environ.get('QUERY_STRING', ''),
keep_blank_values=True,
strict_parsing=False)
for name, value in self._getFields.items():
if not dict.has_key(name):
if isinstance(value, list) and len(value) == 1:
# parse_qs always returns a list of lists,
# while FieldStorage only uses lists for
# keys that actually repeat; this fixes that.
value = value[0]
dict[name] = value
self._fields = dict
def _setupCookies(self):
cookies = Cookie()
if self._environ.has_key('HTTP_COOKIE'):
try:
cookies.load(self._environ['HTTP_COOKIE'])
except:
traceback.print_exc(file=self._environ['wsgi.errors'])
dict = {}
for key in cookies.keys():
dict[key] = cookies[key].value
self._cookies = dict
def protocol(self):
return 'HTTP/1.0'
def time(self):
return self._time
def timeStamp(self):
return time.asctime(time.localtime(self.time()))
## Transactions ##
def transaction(self):
return self._transaction
def setTransaction(self, trans):
self._transaction = trans
## Values ##
def value(self, name, default=NoDefault):
if self._fields.has_key(name):
return self._fields[name]
else:
return self.cookie(name, default)
def hasValue(self, name):
return self._fields.has_key(name) or self._cookies.has_key(name)
def extraURLPath(self):
return self._environ.get('PATH_INFO', '')
## Fields ##
def fieldStorage(self):
return self._fieldStorage
def field(self, name, default=NoDefault):
if default is NoDefault:
return self._fields[name]
else:
return self._fields.get(name, default)
def hasField(self, name):
return self._fields.has_key(name)
def fields(self):
return self._fields
def setField(self, name, value):
self._fields[name] = value
def delField(self, name):
del self._fields[name]
## Cookies ##
def cookie(self, name, default=NoDefault):
""" Returns the value of the specified cookie. """
if default is NoDefault:
return self._cookies[name]
else:
return self._cookies.get(name, default)
def hasCookie(self, name):
return self._cookies.has_key(name)
def cookies(self):
"""
Returns a dictionary-style object of all Cookie objects the
client sent with this request."""
return self._cookies
## Variables passed by server ##
def serverDictionary(self):
"""
Returns a dictionary with the data the web server gave us,
like HTTP_HOST or HTTP_USER_AGENT. """
return self._environ
## Sessions ##
def session(self):
""" Returns the session associated with this request, either
as specified by sessionId() or newly created. This is a
convenience for transaction.session() """
return self._transaction.session()
def isSessionExpired(self):
""" Returns bool: whether or not this request originally
contained an expired session ID. Only works if the
Application.config setting "IgnoreInvalidSession" is set to 1;
otherwise you get a canned error page on an invalid session,
so your servlet never gets processed. """
return self._sessionExpired
def setSessionExpired(self, sessionExpired):
self._sessionExpired = sessionExpired
## Authentication ##
def remoteUser(self):
""" Always returns None since authentication is not yet
supported. Take from CGI variable REMOTE_USER. """
# @@ 2000-03-26 ce: maybe belongs in section below. clean up docs
return self._environ['REMOTE_USER']
## Remote info ##
def remoteAddress(self):
""" Returns a string containing the Internet Protocol (IP)
address of the client that sent the request. """
return self._environ['REMOTE_ADDR']
def remoteName(self):
""" Returns the fully qualified name of the client that sent
the request, or the IP address of the client if the name
cannot be determined. """
env = self._environ
return env.get('REMOTE_NAME', env['REMOTE_ADDR'])
## Path ##
def urlPath(self):
raise NotImplementedError
def originalURLPath(self):
environ = self._environ.get('recursive.previous_environ', self._environ)
url = environ.get("SCRIPT_NAME", '') + environ.get('PATH_INFO', '')
#self._environ['wsgi.errors'].write('Original URL: %r (from %r)\n' % (url, environ))
return url
def urlPathDir(self):
raise NotImplementedError
def getstate(self):
raise NotImplementedError
def setURLPath(self, path):
raise NotImplementedError
def serverSidePath(self, path=None):
raise NotImplementedError
def serverSideContextPath(self, path=None):
base = self._environ['paste.config']['publish_dir']
if path:
return os.path.join(base, path)
else:
return base
def contextName(self):
return ''
def servletURI(self):
"""This is the URI of the servlet, without any query strings or extra path info"""
# @@: should be implemented
raise NotImplementedError
def uriWebKitRoot(self):
raise NotImplementedError
def fsPath(self):
raise NotImplementedError
def serverURL(self):
raise NotImplementedError
def serverURLDir(self):
raise NotImplementedError
def siteRoot(self):
raise NotImplementedError
def siteRootFromCurrentServlet(self):
raise NotImplementedError
def servletPathFromSiteRoot(self):
raise NotImplementedError
## Special ##
def adapterName(self):
"""
Returns the name of the adapter as it appears in the URL.
Example: '/WebKit.cgi'
This is useful in special cases when you are constructing URLs. See Testing/Main.py for an example use.
"""
deprecated()
return '/'.join(self._environ['SCRIPT_NAME'].split('/')[:-1])
def rawRequest(self):
raise NotImplementedError
def environ(self):
return self._environ
def rawInput(self, rewind=0):
"""
This gives you a file-like object for the data that was
sent with the request (e.g., the body of a POST request,
or the documented uploaded in a PUT request).
The file might not be rewound to the beginning if there
was valid, form-encoded POST data. Pass rewind=1 if
you want to be sure you get the entire body of the request.
"""
fs = self.fieldStorage()
if rewind:
fs.file.seek(0)
return fs.file
## Information ##
# @@ 2000-05-10: See FUTURE section of class doc string
def servletPath(self):
raise NotImplementedError
def contextPath(self):
raise NotImplementedError
def pathInfo(self):
raise NotImplementedError
def pathTranslated(self):
raise NotImplementedError
def queryString(self):
"""
Returns the query string portion of the URL for this
request. Taken from the CGI variable QUERY_STRING. """
return self._environ.get('QUERY_STRING', '')
def uri(self):
"""
Returns the request URI, which is the entire URL except
for the query string. """
return self._environ['REQUEST_URI']
def method(self):
"""
Returns the HTTP request method (in all uppercase), typically
from the set GET, POST, PUT, DELETE, OPTIONS and TRACE."""
return self._environ['REQUEST_METHOD'].upper()
def sessionId(self):
""" Returns a string with the session id specified by the
client, or None if there isn't one. """
sid = self.value('_SID_', None)
return sid
def config(self):
return self._environ.get('paste.config', {})
## Inspection ##
def info(self):
raise NotImplementedError
def htmlInfo(self):
raise NotImplementedError
|