0001"""
0002A Webware HTTPRequest object, implemented based on the WSGI request
0003environment dictionary.
0004"""
0005
0006import time
0007import traceback
0008import cgi
0009import sys, os
0010from wkcommon import NoDefault, requestURI, deprecated
0011from Cookie import SimpleCookie as Cookie
0012
0013class HTTPRequest(object):
0014
0015 def __init__(self, transaction, environ):
0016 self._environ = environ
0017 self._transaction = transaction
0018 if environ.has_key('webkit.time'):
0019 self._time = environ['webkit.time']
0020 else:
0021 self._time = time.time()
0022 self._input = environ['wsgi.input']
0023 self._setupPath()
0024 self._setupFields()
0025 self._setupCookies()
0026 self._pathInfo = None
0027 self._serverRootPath = ""
0028
0029 self._sessionExpired = False
0030
0031 def _setupPath(self):
0032 self._environ['PATH_INFO'] = self._environ.get('PATH_INFO', '')
0033 if not self._environ.has_key('REQUEST_URI'):
0034 self._environ['REQUEST_URI'] = requestURI(self._environ)
0035
0036 self._adapterName = self._environ.get('SCRIPT_NAME')
0037
0038 def _setupFields(self):
0039 self._environ.setdefault('QUERY_STRING', '')
0040 self._fieldStorage = cgi.FieldStorage(
0041 self._input,
0042 environ=self._environ,
0043 keep_blank_values=True,
0044 strict_parsing=False)
0045 try:
0046 keys = self._fieldStorage.keys()
0047 except TypeError:
0048
0049 keys = []
0050 dict = {}
0051 for key in keys:
0052 value = self._fieldStorage[key]
0053 if not isinstance(value, list):
0054 if not value.filename:
0055
0056 value = value.value
0057 else:
0058 value = [v.value for v in value]
0059 dict[key] = value
0060 if self._environ['REQUEST_METHOD'].upper() == 'POST':
0061
0062 self._getFields = cgi.parse_qs(
0063 self._environ.get('QUERY_STRING', ''),
0064 keep_blank_values=True,
0065 strict_parsing=False)
0066 for name, value in self._getFields.items():
0067 if not dict.has_key(name):
0068 if isinstance(value, list) and len(value) == 1:
0069
0070
0071
0072 value = value[0]
0073 dict[name] = value
0074 self._fields = dict
0075
0076 def _setupCookies(self):
0077 cookies = Cookie()
0078 if self._environ.has_key('HTTP_COOKIE'):
0079 try:
0080 cookies.load(self._environ['HTTP_COOKIE'])
0081 except:
0082 traceback.print_exc(file=self._environ['wsgi.errors'])
0083 dict = {}
0084 for key in cookies.keys():
0085 dict[key] = cookies[key].value
0086 self._cookies = dict
0087
0088 def protocol(self):
0089 return 'HTTP/1.0'
0090
0091 def time(self):
0092 return self._time
0093
0094 def timeStamp(self):
0095 return time.asctime(time.localtime(self.time()))
0096
0097
0098
0099 def transaction(self):
0100 return self._transaction
0101
0102 def setTransaction(self, trans):
0103 self._transaction = trans
0104
0105
0106
0107 def value(self, name, default=NoDefault):
0108 if self._fields.has_key(name):
0109 return self._fields[name]
0110 else:
0111 return self.cookie(name, default)
0112
0113 def hasValue(self, name):
0114 return self._fields.has_key(name) or self._cookies.has_key(name)
0115
0116 def extraURLPath(self):
0117 return self._environ.get('PATH_INFO', '')
0118
0119
0120
0121
0122 def fieldStorage(self):
0123 return self._fieldStorage
0124
0125 def field(self, name, default=NoDefault):
0126 if default is NoDefault:
0127 return self._fields[name]
0128 else:
0129 return self._fields.get(name, default)
0130
0131 def hasField(self, name):
0132 return self._fields.has_key(name)
0133
0134 def fields(self):
0135 return self._fields
0136
0137 def setField(self, name, value):
0138 self._fields[name] = value
0139
0140 def delField(self, name):
0141 del self._fields[name]
0142
0143
0144
0145 def cookie(self, name, default=NoDefault):
0146 """ Returns the value of the specified cookie. """
0147 if default is NoDefault:
0148 return self._cookies[name]
0149 else:
0150 return self._cookies.get(name, default)
0151
0152 def hasCookie(self, name):
0153 return self._cookies.has_key(name)
0154
0155 def cookies(self):
0156 """
0157 Returns a dictionary-style object of all Cookie objects the
0158 client sent with this request."""
0159 return self._cookies
0160
0161
0162 def serverDictionary(self):
0163 """
0164 Returns a dictionary with the data the web server gave us,
0165 like HTTP_HOST or HTTP_USER_AGENT. """
0166 return self._environ
0167
0168
0169
0170 def session(self):
0171 """ Returns the session associated with this request, either
0172 as specified by sessionId() or newly created. This is a
0173 convenience for transaction.session() """
0174 return self._transaction.session()
0175
0176 def isSessionExpired(self):
0177 """ Returns bool: whether or not this request originally
0178 contained an expired session ID. Only works if the
0179 Application.config setting "IgnoreInvalidSession" is set to 1;
0180 otherwise you get a canned error page on an invalid session,
0181 so your servlet never gets processed. """
0182 return self._sessionExpired
0183
0184 def setSessionExpired(self, sessionExpired):
0185 self._sessionExpired = sessionExpired
0186
0187
0188
0189 def remoteUser(self):
0190 """ Always returns None since authentication is not yet
0191 supported. Take from CGI variable REMOTE_USER. """
0192
0193 return self._environ['REMOTE_USER']
0194
0195
0196
0197 def remoteAddress(self):
0198 """ Returns a string containing the Internet Protocol (IP)
0199 address of the client that sent the request. """
0200 return self._environ['REMOTE_ADDR']
0201
0202 def remoteName(self):
0203 """ Returns the fully qualified name of the client that sent
0204 the request, or the IP address of the client if the name
0205 cannot be determined. """
0206 env = self._environ
0207 return env.get('REMOTE_NAME', env['REMOTE_ADDR'])
0208
0209
0210
0211 def urlPath(self):
0212 raise NotImplementedError
0213
0214 def originalURLPath(self):
0215 environ = self._environ.get('recursive.previous_environ', self._environ)
0216 url = environ.get("SCRIPT_NAME", '') + environ.get('PATH_INFO', '')
0217
0218 return url
0219
0220 def urlPathDir(self):
0221 raise NotImplementedError
0222
0223 def getstate(self):
0224 raise NotImplementedError
0225
0226 def setURLPath(self, path):
0227 raise NotImplementedError
0228
0229 def serverSidePath(self, path=None):
0230 raise NotImplementedError
0231
0232 def serverSideContextPath(self, path=None):
0233 here = sys.modules[self.transaction().servlet().__class__.__module__].__file__
0234
0235 base = os.path.dirname(here)
0236 if path:
0237 return os.path.join(base, path)
0238 else:
0239 return base
0240
0241 def contextName(self):
0242 return ''
0243
0244 def servletURI(self):
0245 """This is the URI of the servlet, without any query strings or extra path info"""
0246
0247 raise NotImplementedError
0248
0249 def uriWebKitRoot(self):
0250 raise NotImplementedError
0251
0252 def fsPath(self):
0253 raise NotImplementedError
0254
0255 def serverURL(self):
0256 raise NotImplementedError
0257
0258 def serverURLDir(self):
0259 raise NotImplementedError
0260
0261 def siteRoot(self):
0262 raise NotImplementedError
0263
0264 def siteRootFromCurrentServlet(self):
0265 raise NotImplementedError
0266
0267 def servletPathFromSiteRoot(self):
0268 raise NotImplementedError
0269
0270
0271
0272 def adapterName(self):
0273 """
0274 Returns the name of the adapter as it appears in the URL.
0275 Example: '/WebKit.cgi'
0276 This is useful in special cases when you are constructing URLs. See Testing/Main.py for an example use.
0277 """
0278 deprecated()
0279 return '/'.join(self._environ['SCRIPT_NAME'].split('/')[:-1])
0280
0281 def rawRequest(self):
0282 raise NotImplementedError
0283
0284 def environ(self):
0285 return self._environ
0286
0287 def rawInput(self, rewind=0):
0288 """
0289 This gives you a file-like object for the data that was
0290 sent with the request (e.g., the body of a POST request,
0291 or the documented uploaded in a PUT request).
0292
0293 The file might not be rewound to the beginning if there
0294 was valid, form-encoded POST data. Pass rewind=1 if
0295 you want to be sure you get the entire body of the request.
0296 """
0297 fs = self.fieldStorage()
0298 if rewind:
0299 fs.file.seek(0)
0300 return fs.file
0301
0302
0303
0304
0305
0306 def servletPath(self):
0307 raise NotImplementedError
0308
0309 def contextPath(self):
0310 raise NotImplementedError
0311
0312 def pathInfo(self):
0313 raise NotImplementedError
0314
0315 def pathTranslated(self):
0316 raise NotImplementedError
0317
0318 def queryString(self):
0319 """
0320 Returns the query string portion of the URL for this
0321 request. Taken from the CGI variable QUERY_STRING. """
0322 return self._environ.get('QUERY_STRING', '')
0323
0324 def uri(self):
0325 """
0326 Returns the request URI, which is the entire URL except
0327 for the query string. """
0328 return self._environ['REQUEST_URI']
0329
0330 def method(self):
0331 """
0332 Returns the HTTP request method (in all uppercase), typically
0333 from the set GET, POST, PUT, DELETE, OPTIONS and TRACE."""
0334 return self._environ['REQUEST_METHOD'].upper()
0335
0336 def sessionId(self):
0337 """ Returns a string with the session id specified by the
0338 client, or None if there isn't one. """
0339 sid = self.value('_SID_', None)
0340 return sid
0341
0342 def config(self):
0343 return self._environ.get('paste.config', {})
0344
0345
0346
0347 def info(self):
0348 raise NotImplementedError
0349
0350 def htmlInfo(self):
0351 raise NotImplementedError