summaryrefslogtreecommitdiff
path: root/paste/webkit/wkrequest.py
diff options
context:
space:
mode:
Diffstat (limited to 'paste/webkit/wkrequest.py')
-rw-r--r--paste/webkit/wkrequest.py344
1 files changed, 344 insertions, 0 deletions
diff --git a/paste/webkit/wkrequest.py b/paste/webkit/wkrequest.py
new file mode 100644
index 0000000..6b1785e
--- /dev/null
+++ b/paste/webkit/wkrequest.py
@@ -0,0 +1,344 @@
+"""
+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']['webkit_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
+
+ ## Inspection ##
+
+ def info(self):
+ raise NotImplementedError
+
+ def htmlInfo(self):
+ raise NotImplementedError