[Zope-Checkins] CVS: Zope3/lib/python/Zope/Publisher/HTTP - HTTPRequest.py:1.1.2.21.2.5 HTTPResponse.py:1.1.2.13.4.5 IHTTPApplicationRequest.py:1.1.2.1.2.1 IHTTPApplicationResponse.py:1.1.2.3 IHTTPRequest.py:1.1.2.2.4.2 BrowserPayload.py:NONE IPayload.py:NONE
Jim Fulton
jim@zope.com
Mon, 25 Mar 2002 18:31:13 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/Publisher/HTTP
In directory cvs.zope.org:/tmp/cvs-serv31034/Zope/Publisher/HTTP
Modified Files:
Tag: Zope3-publisher-refactor-branch
HTTPRequest.py HTTPResponse.py IHTTPApplicationRequest.py
IHTTPApplicationResponse.py IHTTPRequest.py
Removed Files:
Tag: Zope3-publisher-refactor-branch
BrowserPayload.py IPayload.py
Log Message:
Refactord BaseRequest/BaseResponse and HTTPRequest/Response some more:
- Use slots so I can keep track of what's going on. ;)
- Use properties for environment, cookies, headers, URLs.
- Put URL responsibilities in HTTPRequest.
- Have HTTP traverse delegate to and augment Base traverse.
=== Zope3/lib/python/Zope/Publisher/HTTP/HTTPRequest.py 1.1.2.21.2.4 => 1.1.2.21.2.5 ===
from IHTTPCredentials import IHTTPCredentials
from IHTTPRequest import IHTTPRequest
+from IHTTPApplicationRequest import IHTTPApplicationRequest
+
+from Zope.Publisher.RequestDataProperty \
+ import RequestDataProperty, RequestDataMapper, RequestDataGetter
+
+class CookieMapper(RequestDataMapper):
+ _mapname = '_cookies'
+
+class HeaderGetter(RequestDataGetter):
+ _gettrname = 'getHeader'
+
+_marker = object()
+
+class URLGetter:
+
+ def __init__(self, request):
+ self.__request = request
+
+ def __str__(self):
+ return self.__request.getURL()
+
+ def __getitem__(self, name):
+ i = int(name)
+ try:
+ if i < 0:
+ i = -i
+ return self.__request.getURL(i)
+ else:
+ return self.__request.getApplicationURL(i)
+ except IndexError, v:
+ if v[0] == i:
+ raise KeyError, name
+ raise
+
+ def get(self, name, default=None):
+ i = int(name)
+ try:
+ if i < 0:
+ return self.__request.getURL(-i)
+ else:
+ return self.__request.getApplicationURL(i)
+ except IndexError, v:
+ if v == i:
+ return default
+ raise
DEFAULT_PORTS = {'http': '80', 'https': '443'}
STAGGER_RETRIES = 1
@@ -34,9 +79,6 @@
URLmatch=re.compile('URL(PATH)?([0-9]+)$').match
BASEmatch=re.compile('BASE(PATH)?([0-9]+)$').match
-_marker = []
-
-
class HTTPRequest(BaseRequest):
"""
Model HTTP request data.
@@ -84,20 +126,30 @@
other variables, form data, and then cookies.
"""
- __implements__ = BaseRequest.__implements__, IHTTPCredentials, IHTTPRequest
+ __implements__ = (BaseRequest.__implements__,
+ IHTTPCredentials, IHTTPRequest, IHTTPApplicationRequest,
+ )
+
+ __slots__ = (
+ '_auth', # The value of the HTTP_AUTHORIZATION header.
+ '_cookies', # The request cookies
+ '_path_suffix', # Extra traversal steps after normal traversal
+ '_retry_count', # How many times the request has been retried
+ '_app_url', # The application URL
+ '_app_path', # The path part of the application URL
+ '_app_names', # The application path as a sequence
+ '_app_base', # The application URL without the last name
+ '_app_server', # The server path of the application url
+ '_orig_env', # The original environment
+ )
-
- __auth = None # The value of the HTTP_AUTHORIZATION header.
- __cookies = None
-
- retry_count = 0
- retry_max_count = 3
+ retry_max_count = 3 # How many times we're willing to retry
def __init__(self, body_instream, outstream, environ):
super(HTTPRequest, self).__init__(body_instream, outstream, environ)
- self.__orig_env = environ
+ self._orig_env = environ
environ = sane_environment(environ)
if environ.has_key('HTTP_AUTHORIZATION'):
@@ -106,48 +158,143 @@
self._environ = environ
- self.__setupPath()
self.__setupCookies()
+ self.__setupPath()
+ self.__setupURLBase()
+ def __setupURLBase(self):
- def __setupCookies(self)
+ get_env = self._environ.get
+
+ ################################################################
+ # Get base info first. This isn't likely to cause
+ # errors and might be useful to error handlers.
+ base = script = get_env('SCRIPT_NAME','').strip()
+
+ # _script and the other _names are meant for URL construction
+ self._app_names = app_names = filter(None, script.split('/'))
+ self._app_path = map(quote, app_names)
+
+ # Remove trailing /'s
+ while base and base.endswith('/'):
+ base = base[:-1]
+
+ # strip off last element of the URL
+ p = base.rfind('/')
+ if p >= 0:
+ base = base[:p+1]
+ else:
+ base = ''
+
+ # strip off leading /'s
+ while base and base.startswith('/'):
+ base = base[1:]
+
+ # get server URL and store it too, since we are already looking it up
+ server_url = get_env('SERVER_URL', None)
+ if server_url is not None:
+ self._app_server = server_url = server_url.strip()
+ else:
+ server_url = self.__deduceServerURL()
+
+ if server_url.endswith('/'):
+ server_url = server_url[:-1]
+
+ # put the complete base URL together
+ if base:
+ self._app_base = "%s/%s" % (server_url, base)
+ else:
+ self._app_base = server_url
+
+ # strip off leading /'s of script
+ while script.startswith('/'):
+ script = script[1:]
+
+ self._app_server = server_url
+
+ # put the script URL together
+ if script:
+ script = "%s/%s" % (server_url,script)
+ else:
+ script = server_url
+
+ self._app_url = script
+
+ def __deduceServerURL(self):
+ environ = self._environ
+ have_env = environ.has_key
+
+ if have_env('HTTPS') and (
+ environ['HTTPS'] == "on" or environ['HTTPS'] == "ON"):
+ protocol = 'https'
+
+ elif (have_env('SERVER_PORT_SECURE') and
+ environ['SERVER_PORT_SECURE'] == "1"):
+ protocol = 'https'
+ else: protocol = 'http'
+
+ if have_env('HTTP_HOST'):
+ host = environ['HTTP_HOST'].strip()
+ hostname, port = splitport(host)
+
+ else:
+ hostname = environ.get('SERVER_NAME', '').strip()
+ port = environ.get('SERVER_PORT', '')
+
+
+ if (not port or DEFAULT_PORTS.get(protocol, 80) == port):
+ host = hostname
+ else:
+ host = hostname + ':' + port
+
+ server_url = '%s://%s' % (protocol, host)
+ return server_url
+
+ def __setupCookies(self):
################################################################
# Cookie values should *not* be appended to existing form
# vars with the same name - they are more like default values
# for names not otherwise specified in the form.
- other = self._other
cookies={}
cookie_header = self._environ.get('HTTP_COOKIE','')
if cookie_header:
parse_cookie(cookie_header, cookies)
- for cookie, item in cookies.items():
- other.setdefault(cookie, item)
-
- self.__cookies = cookies
+ self._cookies = cookies
def __setupPath(self):
- path = self.get('PATH_INFO', '').strip()
- if path.startswith('/'): path = path[1:] # XXX Why? Not sure
+ path = self.get('PATH_INFO', '/').strip()
+
+ if path.endswith('/'):
+ path = path[:-1] # XXX Why? Not sure
+ self._endswithslash = 1
+
+ if path.startswith('/'):
+ path = path[1:] # XXX Why? Not sure
+
clean = []
for item in path.split('/'):
- if not item or item == '.':
+ if item == '.':
continue
elif item == '..':
- del clean[-1]
+ try: del clean[-1]
+ except IndexError:
+ raise NotFound('..')
else: clean.append(item)
clean.reverse()
self.setTraversalStack(clean)
+ self._path_suffix = None
+
######################################
# from: Zope.Publisher.IPublisherRequest.IPublisherRequest
def supportsRetry(self):
'See Zope.Publisher.IPublisherRequest.IPublisherRequest'
- if self.retry_count < self.retry_max_count:
+ if self._retry_count < self.retry_max_count:
if STAGGER_RETRIES:
time.sleep(whrandom.uniform(0, 2**(self.retry_count)))
return 1
@@ -158,9 +305,9 @@
self.retry_count = self.retry_count + 1
self.body_instream.seek(0)
request = self.__class__(
- body_instream = self.__body_instream,
+ body_instream = self._body_instream,
outstream = self.getResponse().getOutputStream(),
- environ = self.__orig_env
+ environ = self._orig_env
)
request.retry_count = self.retry_count
return request
@@ -169,89 +316,12 @@
def traverse(self, object):
'See Zope.Publisher.IPublisherRequest.IPublisherRequest'
- publication = self.getPublication()
-
- traversal_altered = 0 # flag for adding traversal steps
- add_steps = None
- path_str = self.get('PATH_INFO', '').strip()
-
- traversal_stack = self._splitPath(path_str)
- traversal_stack.reverse()
- self.setTraversalStack(traversal_stack)
-
- self.traversed = traversed = []
- traversed.append(object)
- steps = self.steps
- self.quoted_steps = quoted_steps = map(pc_quote, steps)
-
- prev_object = None
- while 1:
- if object is not prev_object:
- # Invoke hooks (but not more than once).
- publication.callTraversalHooks(self, object)
- # A hook may have called changeTraversalStack().
- traversal_stack = self.getTraversalStack()
-
- prev_object = object
-
- if traversal_stack:
- # Traverse to the next step.
- entry_name = traversal_stack.pop()
- if entry_name:
- qstep = pc_quote(entry_name)
- quoted_steps.append(qstep)
-
- if traversal_altered:
- # The effective URL includes the altered traversal.
- #import pdb; pdb.set_trace()
- e_url = self.effective_url or self.URL
- self.effective_url = '%s/%s' % (e_url, qstep)
- else:
- # Build up the URL to the object, but not
- # to the default traversal.
- self.URL = '%s/%s' % (self.URL, qstep)
- subobject = publication.traverseName(
- self, object, entry_name)
- object = subobject
- traversed.append(object)
- steps.append(entry_name)
-
- else:
- add_steps = self._request_default
-
- if add_steps:
- self._request_default = None
-
- if add_steps is None:
- object, add_steps = publication.getDefaultTraversal(
- self, object)
-
- if add_steps:
- traversal_altered = 1
- traversal_stack.extend(add_steps)
- else:
- # Finished traversal.
- break
-
- if traversal_altered:
- eurl = self.effective_url
- loc = eurl.rfind('/')
- # XXX Quick bug fix, need better impl
- if loc >= 0:
- eurl = eurl[:loc+1]
- self.response.setBase(eurl)
-
-
- self.traversed = tuple(traversed) # No more changes allowed
- self._afterTraveral() # Sometimes we want to do something here
- return object
-
-
- # This method is not part of the interface.
- def _afterTraversal(self):
- '''Do whatever needs to be done after an object traveral'''
- pass
+ ob = super(HTTPRequest, self).traverse(object)
+ if self._path_suffix:
+ self._traversal_stack = self._path_suffix
+ ob = super(HTTPRequest, self).traverse(ob)
+ return ob
# This method is not part of the interface.
def _splitPath(self, path):
@@ -290,13 +360,19 @@
name='HTTP_%s' % name
return environ.get(name, default)
+ headers = RequestDataProperty(HeaderGetter)
+
def getCookies(self):
'See Zope.Publisher.HTTP.IHTTPRequest.IHTTPRequest'
- return self.__cookies
+ return self._cookies
+
+ cookies = RequestDataProperty(CookieMapper)
def setPathSuffix(self, steps):
'See Zope.Publisher.HTTP.IHTTPRequest.IHTTPRequest'
- self.__path_suffix = steps
+ steps = list(steps)
+ steps.reverse()
+ self._path_suffix = steps
#
############################################################
@@ -327,6 +403,68 @@
def _createResponse(self, outstream):
# Should be overridden by subclasses
return HTTPResponse(outstream)
+
+
+ def getURL(self, level=0, path_only=0):
+ names = self._app_names + self._traversed_names
+ if level:
+ if level > len(names):
+ raise IndexError, level
+ names = names[:-level]
+ names = map(quote, names)
+
+ if path_only:
+ if not names: return '/'
+ return '/' + '/'.join(names)
+ else:
+ if not names: return self._app_server
+ return "%s/%s" % (self._app_server, '/'.join(names))
+
+ def getApplicationURL(self, depth=0, path_only=0):
+ if depth:
+ names = self._traversed_names
+ if depth > len(names):
+ raise IndexError, depth
+ names = self._app_names + names[:depth]
+ else:
+ names = self._app_names
+
+ names = map(quote, names)
+
+ if path_only:
+ return names and ('/' + '/'.join(names)) or '/'
+ else:
+ return (names and ("%s/%s" % (self._app_server, '/'.join(names)))
+ or self._app_server)
+
+ URL = RequestDataProperty(URLGetter)
+
+ ######################################
+ # from: Interface.Common.Mapping.IReadMapping
+
+ def get(self, key, default=None):
+ 'See Interface.Common.Mapping.IReadMapping'
+
+ result = self._cookies.get(key, self)
+ if result is not self: return result
+
+ result = self._environ.get(key, self)
+ if result is not self: return result
+
+ return default
+
+ #
+ ############################################################
+
+ ######################################
+ # from: Interface.Common.Mapping.IEnumerableMapping
+
+ def keys(self):
+ 'See Interface.Common.Mapping.IEnumerableMapping'
+ d = {}
+ d.update(self._environ)
+ d.update(self._cookies)
+ return d.keys()
=== Zope3/lib/python/Zope/Publisher/HTTP/HTTPResponse.py 1.1.2.13.4.4 => 1.1.2.13.4.5 ===
from Zope.Publisher.BaseResponse import BaseResponse
from Zope.Publisher.Exceptions import Redirect
+from IHTTPResponse import IHTTPResponse
+from IHTTPApplicationResponse import IHTTPApplicationResponse
+from Zope.Exceptions.ExceptionFormatter import format_exception
# Possible HTTP status responses
status_reasons = {
@@ -96,22 +99,29 @@
__implements__ = IHTTPResponse, IHTTPApplicationResponse, \
BaseResponse.__implements__
- base = None
- realm = 'Zope'
- _error_format = 'text/html'
- _wrote_headers = 0
- _streaming = 0
- __status = 200 # The response status (usually an integer)
- reason = 'Ok'
+ __slots__ = (
+ '_header_output', # XXX what is this
+ '_headers',
+ '_cookies',
+ '_accumulated_headers', # Headers that can have multiples
+ '_wrote_headers',
+ '_streaming',
+ '_status', # The response status (usually an integer)
+ '_reason' # The reason that goes with the status
+ )
def __init__(self, outstream, header_output = None):
- self.__header_output = header_output
+ self._header_output = header_output
super(HTTPResponse, self).__init__(outstream)
- self.__headers = {}
- self.__cookies = {}
- self.__accumulated_headers = []
+ self._headers = {}
+ self._cookies = {}
+ self._accumulated_headers = []
+ self._wrote_headers = 0
+ self._streaming = 0
+ self._status = 200
+ self._reason = 'Ok'
############################################################
@@ -129,7 +139,7 @@
status = status_codes[status]
else:
status=500
- self.__status = status
+ self._status = status
if reason is None:
if status == 200:
@@ -138,12 +148,12 @@
reason = status_reasons[status]
else:
reason = 'Unknown'
- self.reason = reason
+ self._reason = reason
def getStatus(self):
'See Zope.Publisher.HTTP.IHTTPResponse.IHTTPResponse'
- return self.__status
+ return self._status
def setHeader(self, name, value, literal=0):
@@ -153,24 +163,24 @@
self.addHeader(name, value)
else:
name = literal and name or key
- self.__headers[name]=value
+ self._headers[name]=value
def addHeader(self, name, value):
'See Zope.Publisher.HTTP.IHTTPResponse.IHTTPResponse'
- accum = self.accumulated_headers
+ accum = self._accumulated_headers
accum.append('%s: %s' % (name, value))
def getHeader(self, name, default=None):
'See Zope.Publisher.HTTP.IHTTPResponse.IHTTPResponse'
- return self.__headers.get(name, default)
+ return self._headers.get(name, default)
def getHeaders(self):
'See Zope.Publisher.HTTP.IHTTPResponse.IHTTPResponse'
result = {}
- headers = self.__headers
+ headers = self._headers
if (not self._streaming and not headers.has_key('content-length')
and not headers.has_key('transfer-encoding')):
@@ -196,9 +206,9 @@
def appendToHeader(self, name, value, delimiter=','):
'See Zope.Publisher.HTTP.IHTTPResponse.IHTTPResponse'
- headers = self.headers
+ headers = self._headers
if headers.has_key(name):
- h = self.header[name]
+ h = self._header[name]
h = "%s%s\r\n\t%s" % (h, delimiter, value)
else: h = value
self.setHeader(name, h)
@@ -206,7 +216,7 @@
def appendToCookie(self, name, value):
'See Zope.Publisher.HTTP.IHTTPResponse.IHTTPResponse'
- cookies = self.cookies
+ cookies = self._cookies
if cookies.has_key(name): cookie = cookies[name]
else: cookie = cookies[name] = {}
if cookie.has_key('value'):
@@ -219,7 +229,7 @@
dict={'max_age':0, 'expires':'Wed, 31-Dec-97 23:59:59 GMT'}
for k, v in kw.items():
dict[k]=v
- cookies=self.cookies
+ cookies=self._cookies
if cookies.has_key(name):
# Cancel previous setCookie().
del cookies[name]
@@ -228,7 +238,7 @@
def setCookie(self, name, value, **kw):
'See Zope.Publisher.HTTP.IHTTPResponse.IHTTPResponse'
- cookies=self.cookies
+ cookies=self._cookies
if cookies.has_key(name):
cookie=cookies[name]
else: cookie=cookies[name]={}
@@ -246,9 +256,9 @@
######################################
# from: Zope.Publisher.IPublisherResponse.IPublisherResponse
-
def handleException(self, exc_info):
"""
+ Calls self.setBody() with an error response.
"""
t, v = exc_info[:2]
if isinstance(t, ClassType):
@@ -263,18 +273,34 @@
# for apps to control the status code.
self.setStatus(tname)
- tb = escape(traceback_string(t, v, exc_info[2]))
- self.setBody(tb)
+ tb = ''.join(format_exception(t, v, exc_info[2], 1))
+ body = self._html(title, "%s" % tb)
+ self.setBody(body)
+
+
+ def _html(self, title, content):
+ t = escape(title)
+ return (
+ "<html><head><title>%s</title></head>\n"
+ "<body><h2>%s</h2>\n"
+ "%s\n"
+ "</body></html>\n" %
+ (t, t, content)
+ )
+
+
+
+
def retry(self):
"""
Returns a response object to be used in a retry attempt
"""
- return self.__class__(self.outstream,
- self.header_output)
+ return self.__class__(self._outstream,
+ self._header_output)
def _updateContentLength(self):
- blen = str(len(self.body))
+ blen = str(len(self._body))
if blen.endswith('L'):
blen = blen[:-1]
self.setHeader('content-length', blen)
@@ -287,7 +313,7 @@
def _cookie_list(self):
cookie_list = []
- for name, attrs in self.cookies.items():
+ for name, attrs in self._cookies.items():
# Note that as of May 98, IE4 ignores cookies with
# quoted cookie attr values, so only the value part
@@ -316,26 +342,26 @@
def getHeaderText(self, m):
- lst = ['Status: %s %s' % (self.status, self.reason)]
+ lst = ['Status: %s %s' % (self._status, self._reason)]
lst.extend(map(lambda x: '%s: %s' % x, m.items()))
lst.extend(self._cookie_list())
- lst.extend(self.__accumulated_headers)
+ lst.extend(self._accumulated_headers)
return ('%s\r\n\r\n' % '\r\n'.join(lst))
def outputHeaders(self):
headers = self.getHeaders()
- header_output = self.header_output
+ header_output = self._header_output
if header_output is not None:
# Use the IHeaderOutput interface.
- header_output.setResponseStatus(self.status, self.reason)
+ header_output.setResponseStatus(self._status, self._reason)
header_output.setResponseHeaders(headers)
header_output.appendResponseHeaders(self._cookie_list())
header_output.appendResponseHeaders(self.__accumulated_headers)
else:
# Write directly to outstream.
headers_text = self.getHeaderText(headers)
- self.outstream.write(headers_text)
+ self._outstream.write(headers_text)
######################################
@@ -372,13 +398,13 @@
if not self._wrote_headers:
self.outputHeaders()
self._wrote_headers = 1
- self.outstream.write(data)
+ self._outstream.write(data)
def outputBody(self):
"""
Outputs the response body.
"""
- self.output(self.body)
+ self.output(self._body)
def _formatException(etype, value, tb, limit=None):
=== Zope3/lib/python/Zope/Publisher/HTTP/IHTTPApplicationRequest.py 1.1.2.1 => 1.1.2.1.2.1 ===
from Zope.Publisher.IApplicationRequest import IApplicationRequest
+from Interface.Attribute import Attribute
class IHTTPApplicationRequest(IApplicationRequest):
"""HTTP request data.
This object provides access to request data. This includes, the
- input headers, form data, server data, and cookies.
+ input headers, server data, and cookies.
Request objects are created by the object publisher and will be
passed to published objects through the argument name, REQUEST.
@@ -51,5 +52,88 @@
The request object may be used as a mapping object, in which case
values will be looked up in the order: environment variables,
- other variables, form data, and then cookies.
+ other variables, cookies, and special.
"""
+
+ def __getitem__(key):
+ """Return HTTP request data
+
+ Request data sre retrieved from one of:
+
+ - Environment variables
+
+ These variables include input headers, server data, and other
+ request-related data. The variable names are as <a
+ href="http://hoohoo.ncsa.uiuc.edu/cgi/env.html">specified</a>
+ in the <a
+ href="http://hoohoo.ncsa.uiuc.edu/cgi/interface.html">CGI
+ specification</a>
+
+ - Cookies
+
+ These are the cookie data, if present.
+
+ Cookies are searched before environmental data.
+ """
+
+ def getCookies():
+ """Return the cookie data
+
+ Data are returned as a mapping object, mapping cookie name to value.
+ """
+
+ return IMapping(str, str)
+
+ cookies = Attribute(
+ """Request cookie data
+
+ This is a read-only mapping from variable name to value.
+ """)
+
+ def getHeader(name, default=None):
+ """Get a header value
+
+ Return the named HTTP header, or an optional default
+ argument or None if the header is not found. Note that
+ both original and CGI-ified header names are recognized,
+ e.g. 'Content-Type', 'CONTENT_TYPE' and 'HTTP_CONTENT_TYPE'
+ should all return the Content-Type header, if available.
+ """
+
+ headers = Attribute(
+ """Request header data
+
+ This is a read-only mapping from variable name to value.
+ """)
+
+ URL = Attribute(
+ """Request URL data
+
+ When convered to a string, this gives the effective published URL.
+
+ This is object can also be used as a mapping object. The keys
+ must be integers or strings that can be converted to
+ integers. A non-negative integer returns a URL n steps from
+ the URL of the top-level application objects. A negative
+ integer gives a URL that is -n steps back from the effective
+ URL.
+
+ For example, 'request.URL[-2]' is equivalent to the Zope 2
+ 'request["URL2"]'. The notion is that this would be used in
+ path expressions, like 'request/URL/-2'.
+ """)
+
+
+ def getURL(level=0, path_only=0):
+ """Return the published URL with level names removed from the end.
+
+ If path_only is true, then only a path will be returned.
+ """
+
+ def getApplicationURL(depth=0, path_only=0):
+ """Return the application URL plus depth steps
+
+ If path_only is true, then only a path will be returned.
+ """
+
+
=== Zope3/lib/python/Zope/Publisher/HTTP/IHTTPApplicationResponse.py 1.1.2.2 => 1.1.2.3 ===
class IHTTPApplicationResponse(IApplicationResponse):
- """This interface expands IHTTPResponse interface by methods that
- will be used by the application.
+ """HTTP Response
"""
- def __getitem__(key):
- """Return HTTP request data
-
- Request data sre retrieved from one of:
-
- - Environment variables
-
- These variables include input headers, server data, and other
- request-related data. The variable names are as <a
- href="http://hoohoo.ncsa.uiuc.edu/cgi/env.html">specified</a>
- in the <a
- href="http://hoohoo.ncsa.uiuc.edu/cgi/interface.html">CGI
- specification</a>
-
- - Cookies
-
- These are the cookie data, if present.
-
- Cookies are searched before environmental data.
- """
-
- def getCookies():
- """Return the cookie data
-
- Data are returned as a mapping object, mapping cookie name to value.
- """
-
- return IMapping(str, str)
-
- cookies = Attribute(
- """Request cookie data
-
- This is a read-only mapping from variable name to value.
- """)
-
- def getHeader(name, default=None):
- """Get a header value
-
- Return the named HTTP header, or an optional default
- argument or None if the header is not found. Note that
- both original and CGI-ified header names are recognized,
- e.g. 'Content-Type', 'CONTENT_TYPE' and 'HTTP_CONTENT_TYPE'
- should all return the Content-Type header, if available.
- """
-
- headers = Attribute(
- """Request header data
-
- This is a read-only mapping from variable name to value.
- """)
-
- URL = Attribute(
- """Request URL data
-
- When convered to a string, this gives the effective published URL.
-
- This is object can also be used as a mapping object. The keys
- must be integers or strings that can be converted to
- integers. A non-negative integer returns a URL n steps from
- the URL of the top-level application objects. A negative
- integer gives a URL that is -n steps back from the effective
- URL.
-
- For example, 'request.URL[-2]' is equivalent to the Zope 2
- 'request["URL2"]'. The notion is that this would be used in
- path expressions, like 'request/URL/-2'.
- """
-
- def redirect(self, location, status=302):
+ def redirect(location, status=302):
"""Causes a redirection without raising an error.
"""
=== Zope3/lib/python/Zope/Publisher/HTTP/IHTTPRequest.py 1.1.2.2.4.1 => 1.1.2.2.4.2 ===
class IHTTPRequest(Interface):
- def __getitem__(key):
- """Return HTTP request data
-
- Request data are divided into five categories:
-
- - Environment variables
-
- These variables include input headers, server data, and other
- request-related data. The variable names are as <a
- href="http://hoohoo.ncsa.uiuc.edu/cgi/env.html">specified</a>
- in the <a
- href="http://hoohoo.ncsa.uiuc.edu/cgi/interface.html">CGI
- specification</a>
-
- - Form data
-
- These are data extracted from either a URL-encoded query
- string or body, if present.
-
- - Cookies
-
- These are the cookie data, if present.
-
- - Lazy Data
-
- These are callables which are deferred until explicitly
- referenced, at which point they are resolved and stored as
- application data.
-
- - Other
-
- Data that may be set by an application object.
-
- """
-
- def getCookies():
- """Return the cookie data
-
- Data are returned as a mapping object, mapping cookie name to value.
- """
-
- return IMapping(str, str)
-
- def getHeader(name, default=None):
- """Get a header value
-
- Return the named HTTP header, or an optional default
- argument or None if the header is not found. Note that
- both original and CGI-ified header names are recognized,
- e.g. 'Content-Type', 'CONTENT_TYPE' and 'HTTP_CONTENT_TYPE'
- should all return the Content-Type header, if available.
- """
-
def setPathSuffix(steps):
"""Add additional trversal steps to be taken after all other traversal
=== Removed File Zope3/lib/python/Zope/Publisher/HTTP/BrowserPayload.py ===
=== Removed File Zope3/lib/python/Zope/Publisher/HTTP/IPayload.py ===