summaryrefslogtreecommitdiff
path: root/cherrypy
diff options
context:
space:
mode:
Diffstat (limited to 'cherrypy')
-rw-r--r--cherrypy/_cpdispatch.py32
-rw-r--r--cherrypy/_cperror.py19
-rw-r--r--cherrypy/_cplogging.py14
-rw-r--r--cherrypy/_cpreqbody.py2
-rw-r--r--cherrypy/_cprequest.py31
-rw-r--r--cherrypy/_cptools.py36
-rw-r--r--cherrypy/_cptree.py7
-rw-r--r--cherrypy/lib/auth.py19
-rw-r--r--cherrypy/lib/auth_basic.py13
-rw-r--r--cherrypy/lib/auth_digest.py27
-rw-r--r--cherrypy/lib/caching.py21
-rw-r--r--cherrypy/lib/cptools.py81
-rw-r--r--cherrypy/lib/encoding.py29
-rw-r--r--cherrypy/lib/jsontools.py6
-rw-r--r--cherrypy/lib/sessions.py26
-rw-r--r--cherrypy/lib/static.py28
-rw-r--r--cherrypy/test/test.py4
-rw-r--r--cherrypy/wsgiserver/__init__.py8
18 files changed, 217 insertions, 186 deletions
diff --git a/cherrypy/_cpdispatch.py b/cherrypy/_cpdispatch.py
index 92d5e211..af5773cb 100644
--- a/cherrypy/_cpdispatch.py
+++ b/cherrypy/_cpdispatch.py
@@ -52,7 +52,8 @@ def test_callable_spec(callable, callable_args, callable_kwargs):
incorrect, then a 404 Not Found should be raised. Conversely the body
parameters are part of the request; if they are invalid a 400 Bad Request.
"""
- show_mismatched_params = getattr(cherrypy.request, 'show_mismatched_params', False)
+ show_mismatched_params = getattr(
+ cherrypy.serving.request, 'show_mismatched_params', False)
try:
(args, varargs, varkw, defaults) = inspect.getargspec(callable)
except TypeError:
@@ -119,7 +120,7 @@ def test_callable_spec(callable, callable_args, callable_kwargs):
if not varargs and vararg_usage > 0:
raise cherrypy.HTTPError(404)
- body_params = cherrypy.request.body.params or {}
+ body_params = cherrypy.serving.request.body.params or {}
body_params = set(body_params.keys())
qs_params = set(callable_kwargs.keys()) - body_params
@@ -176,7 +177,7 @@ class LateParamPageHandler(PageHandler):
"""
def _get_kwargs(self):
- kwargs = cherrypy.request.params.copy()
+ kwargs = cherrypy.serving.request.params.copy()
if self._kwargs:
kwargs.update(self._kwargs)
return kwargs
@@ -216,7 +217,7 @@ class Dispatcher(object):
def __call__(self, path_info):
"""Set handler and config for the current request."""
- request = cherrypy.request
+ request = cherrypy.serving.request
func, vpath = self.find_handler(path_info)
if func:
@@ -245,7 +246,7 @@ class Dispatcher(object):
These virtual path components are passed to the handler as
positional arguments.
"""
- request = cherrypy.request
+ request = cherrypy.serving.request
app = request.app
root = app.root
dispatch_name = self.dispatch_method_name
@@ -356,7 +357,7 @@ class MethodDispatcher(Dispatcher):
def __call__(self, path_info):
"""Set handler and config for the current request."""
- request = cherrypy.request
+ request = cherrypy.serving.request
resource, vpath = self.find_handler(path_info)
if resource:
@@ -365,7 +366,7 @@ class MethodDispatcher(Dispatcher):
if "GET" in avail and "HEAD" not in avail:
avail.append("HEAD")
avail.sort()
- cherrypy.response.headers['Allow'] = ", ".join(avail)
+ cherrypy.serving.response.headers['Allow'] = ", ".join(avail)
# Find the subhandler
meth = request.method.upper()
@@ -414,20 +415,20 @@ class RoutesDispatcher(object):
"""Set handler and config for the current request."""
func = self.find_handler(path_info)
if func:
- cherrypy.request.handler = LateParamPageHandler(func)
+ cherrypy.serving.request.handler = LateParamPageHandler(func)
else:
- cherrypy.request.handler = cherrypy.NotFound()
+ cherrypy.serving.request.handler = cherrypy.NotFound()
def find_handler(self, path_info):
"""Find the right page handler, and set request.config."""
import routes
- request = cherrypy.request
+ request = cherrypy.serving.request
config = routes.request_config()
config.mapper = self.mapper
- if hasattr(cherrypy.request, 'wsgi_environ'):
- config.environ = cherrypy.request.wsgi_environ
+ if hasattr(request, 'wsgi_environ'):
+ config.environ = request.wsgi_environ
config.host = request.headers.get('Host', None)
config.protocol = request.scheme
config.redirect = self.redirect
@@ -541,7 +542,8 @@ def VirtualHost(next_dispatcher=Dispatcher(), use_x_forwarded_host=True, **domai
"""
from cherrypy.lib import httputil
def vhost_dispatch(path_info):
- header = cherrypy.request.headers.get
+ request = cherrypy.serving.request
+ header = request.headers.get
domain = header('Host', '')
if use_x_forwarded_host:
@@ -554,10 +556,10 @@ def VirtualHost(next_dispatcher=Dispatcher(), use_x_forwarded_host=True, **domai
result = next_dispatcher(path_info)
# Touch up staticdir config. See http://www.cherrypy.org/ticket/614.
- section = cherrypy.request.config.get('tools.staticdir.section')
+ section = request.config.get('tools.staticdir.section')
if section:
section = section[len(prefix):]
- cherrypy.request.config['tools.staticdir.section'] = section
+ request.config['tools.staticdir.section'] = section
return result
return vhost_dispatch
diff --git a/cherrypy/_cperror.py b/cherrypy/_cperror.py
index 6e554876..106c9dd2 100644
--- a/cherrypy/_cperror.py
+++ b/cherrypy/_cperror.py
@@ -29,7 +29,7 @@ class InternalRedirect(CherryPyException):
def __init__(self, path, query_string=""):
import cherrypy
- request = cherrypy.request
+ request = cherrypy.serving.request
self.query_string = query_string
if "?" in path:
@@ -60,7 +60,7 @@ class HTTPRedirect(CherryPyException):
def __init__(self, urls, status=None):
import cherrypy
- request = cherrypy.request
+ request = cherrypy.serving.request
if isinstance(urls, basestring):
urls = [urls]
@@ -99,7 +99,7 @@ class HTTPRedirect(CherryPyException):
HTTPRedirect object and set its output without *raising* the exception.
"""
import cherrypy
- response = cherrypy.response
+ response = cherrypy.serving.response
response.status = status = self.status
if status in (300, 301, 302, 303, 307):
@@ -158,7 +158,7 @@ def clean_headers(status):
"""Remove any headers which should not apply to an error response."""
import cherrypy
- response = cherrypy.response
+ response = cherrypy.serving.response
# Remove headers which applied to the original content,
# but do not apply to the error page.
@@ -211,7 +211,7 @@ class HTTPError(CherryPyException):
"""
import cherrypy
- response = cherrypy.response
+ response = cherrypy.serving.response
clean_headers(self.code)
@@ -219,7 +219,7 @@ class HTTPError(CherryPyException):
# so don't bother cleaning up response values here.
response.status = self.status
tb = None
- if cherrypy.request.show_tracebacks:
+ if cherrypy.serving.request.show_tracebacks:
tb = format_exc()
response.headers['Content-Type'] = "text/html;charset=utf-8"
response.headers.pop('Content-Length', None)
@@ -244,7 +244,8 @@ class NotFound(HTTPError):
def __init__(self, path=None):
if path is None:
import cherrypy
- path = cherrypy.request.script_name + cherrypy.request.path_info
+ request = cherrypy.serving.request
+ path = request.script_name + request.path_info
self.args = (path,)
HTTPError.__init__(self, 404, "The path %r was not found." % path)
@@ -309,7 +310,7 @@ def get_error_page(status, **kwargs):
kwargs[k] = _escape(kwargs[k])
# Use a custom template or callable for the error page?
- pages = cherrypy.request.error_page
+ pages = cherrypy.serving.request.error_page
error_page = pages.get(code) or pages.get('default')
if error_page:
try:
@@ -337,7 +338,7 @@ _ie_friendly_error_sizes = {
def _be_ie_unfriendly(status):
import cherrypy
- response = cherrypy.response
+ response = cherrypy.serving.response
# For some statuses, Internet Explorer 5+ shows "friendly error
# messages" instead of our response.body if the body is smaller
diff --git a/cherrypy/_cplogging.py b/cherrypy/_cplogging.py
index 4ac69b1f..554a5294 100644
--- a/cherrypy/_cplogging.py
+++ b/cherrypy/_cplogging.py
@@ -72,9 +72,9 @@ class LogManager(object):
escaped by prepending a backslash, and all whitespace characters,
which are written in their C-style notation (\\n, \\t, etc).
"""
- request = cherrypy.request
+ request = cherrypy.serving.request
remote = request.remote
- response = cherrypy.response
+ response = cherrypy.serving.response
outheaders = response.headers
inheaders = request.headers
if response.output_status is None:
@@ -88,9 +88,9 @@ class LogManager(object):
't': self.time(),
'r': request.request_line,
's': status,
- 'b': outheaders.get('Content-Length', '') or "-",
- 'f': inheaders.get('Referer', ''),
- 'a': inheaders.get('User-Agent', ''),
+ 'b': dict.get(outheaders, 'Content-Length', '') or "-",
+ 'f': dict.get(inheaders, 'Referer', ''),
+ 'a': dict.get(inheaders, 'User-Agent', ''),
}
for k, v in atoms.items():
if isinstance(v, unicode):
@@ -220,7 +220,7 @@ class WSGIErrorHandler(logging.Handler):
def flush(self):
"""Flushes the stream."""
try:
- stream = cherrypy.request.wsgi_environ.get('wsgi.errors')
+ stream = cherrypy.serving.request.wsgi_environ.get('wsgi.errors')
except (AttributeError, KeyError):
pass
else:
@@ -229,7 +229,7 @@ class WSGIErrorHandler(logging.Handler):
def emit(self, record):
"""Emit a record."""
try:
- stream = cherrypy.request.wsgi_environ.get('wsgi.errors')
+ stream = cherrypy.serving.request.wsgi_environ.get('wsgi.errors')
except (AttributeError, KeyError):
pass
else:
diff --git a/cherrypy/_cpreqbody.py b/cherrypy/_cpreqbody.py
index 2af43c82..a7135eef 100644
--- a/cherrypy/_cpreqbody.py
+++ b/cherrypy/_cpreqbody.py
@@ -588,7 +588,7 @@ class RequestBody(Entity):
# It is possible to send a POST request with no body, for example;
# however, app developers are responsible in that case to set
# cherrypy.request.process_body to False so this method isn't called.
- h = cherrypy.request.headers
+ h = cherrypy.serving.request.headers
if u'Content-Length' not in h and u'Transfer-Encoding' not in h:
raise cherrypy.HTTPError(411)
diff --git a/cherrypy/_cprequest.py b/cherrypy/_cprequest.py
index 40b89561..0c8e3d7c 100644
--- a/cherrypy/_cprequest.py
+++ b/cherrypy/_cprequest.py
@@ -134,26 +134,26 @@ def hooks_namespace(k, v):
v = cherrypy.lib.attributes(v)
if not isinstance(v, Hook):
v = Hook(v)
- cherrypy.request.hooks[hookpoint].append(v)
+ cherrypy.serving.request.hooks[hookpoint].append(v)
def request_namespace(k, v):
"""Attach request attributes declared in config."""
- setattr(cherrypy.request, k, v)
+ setattr(cherrypy.serving.request, k, v)
def response_namespace(k, v):
"""Attach response attributes declared in config."""
# Provides config entries to set default response headers
# http://cherrypy.org/ticket/889
if k[:8] == 'headers.':
- cherrypy.response.headers[k.split('.', 1)[1]] = v
+ cherrypy.serving.response.headers[k.split('.', 1)[1]] = v
else:
- setattr(cherrypy.response, k, v)
+ setattr(cherrypy.serving.response, k, v)
def error_page_namespace(k, v):
"""Attach error pages declared in config."""
if k != 'default':
k = int(k)
- cherrypy.request.error_page[k] = v
+ cherrypy.serving.request.error_page[k] = v
hookpoints = ['on_start_resource', 'before_request_body',
@@ -524,6 +524,7 @@ class Request(object):
attributes to build the outbound stream.
"""
+ response = cherrypy.serving.response
self.stage = 'run'
try:
self.error_response = cherrypy.HTTPError(500).set_response
@@ -548,7 +549,7 @@ class Request(object):
rp = int(req_protocol[5]), int(req_protocol[7])
sp = int(self.server_protocol[5]), int(self.server_protocol[7])
self.protocol = min(rp, sp)
- cherrypy.response.headers.protocol = self.protocol
+ response.headers.protocol = self.protocol
# Rebuild first line of the request (e.g. "GET /path HTTP/1.0").
url = path
@@ -587,28 +588,28 @@ class Request(object):
else:
body = ""
r = bare_error(body)
- response = cherrypy.response
response.output_status, response.header_list, response.body = r
if self.method == "HEAD":
# HEAD requests MUST NOT return a message-body in the response.
- cherrypy.response.body = []
+ response.body = []
try:
cherrypy.log.access()
except:
cherrypy.log.error(traceback=True)
- if cherrypy.response.timed_out:
+ if response.timed_out:
raise cherrypy.TimeoutError()
- return cherrypy.response
+ return response
# Uncomment for stage debugging
# stage = property(lambda self: self._stage, lambda self, v: print(v))
def respond(self, path_info):
"""Generate a response for the resource at self.path_info. (Core)"""
+ response = cherrypy.serving.response
try:
try:
try:
@@ -649,17 +650,17 @@ class Request(object):
self.hooks.run('before_handler')
if self.handler:
self.stage = 'handler'
- cherrypy.response.body = self.handler()
+ response.body = self.handler()
# Finalize
self.stage = 'before_finalize'
self.hooks.run('before_finalize')
- cherrypy.response.finalize()
+ response.finalize()
except (cherrypy.HTTPRedirect, cherrypy.HTTPError), inst:
inst.set_response()
self.stage = 'before_finalize (HTTPError)'
self.hooks.run('before_finalize')
- cherrypy.response.finalize()
+ response.finalize()
finally:
self.stage = 'on_end_resource'
self.hooks.run('on_end_resource')
@@ -760,10 +761,10 @@ class Request(object):
if self.error_response:
self.error_response()
self.hooks.run("after_error_response")
- cherrypy.response.finalize()
+ cherrypy.serving.response.finalize()
except cherrypy.HTTPRedirect, inst:
inst.set_response()
- cherrypy.response.finalize()
+ cherrypy.serving.response.finalize()
# ------------------------- Properties ------------------------- #
diff --git a/cherrypy/_cptools.py b/cherrypy/_cptools.py
index 5c98430a..81dca463 100644
--- a/cherrypy/_cptools.py
+++ b/cherrypy/_cptools.py
@@ -86,7 +86,7 @@ class Tool(object):
else:
conf = {}
- tm = cherrypy.request.toolmaps[self.namespace]
+ tm = cherrypy.serving.request.toolmaps[self.namespace]
if self._name in tm:
conf.update(tm[self._name])
@@ -129,8 +129,8 @@ class Tool(object):
p = conf.pop("priority", None)
if p is None:
p = getattr(self.callable, "priority", self._priority)
- cherrypy.request.hooks.attach(self._point, self.callable,
- priority=p, **conf)
+ cherrypy.serving.request.hooks.attach(self._point, self.callable,
+ priority=p, **conf)
class HandlerTool(Tool):
@@ -159,13 +159,13 @@ class HandlerTool(Tool):
handled = self.callable(*args, **self._merged_args(kwargs))
if not handled:
raise cherrypy.NotFound()
- return cherrypy.response.body
+ return cherrypy.serving.response.body
handle_func.exposed = True
return handle_func
def _wrapper(self, **kwargs):
if self.callable(**kwargs):
- cherrypy.request.handler = None
+ cherrypy.serving.request.handler = None
def _setup(self):
"""Hook this tool into cherrypy.request.
@@ -177,8 +177,8 @@ class HandlerTool(Tool):
p = conf.pop("priority", None)
if p is None:
p = getattr(self.callable, "priority", self._priority)
- cherrypy.request.hooks.attach(self._point, self._wrapper,
- priority=p, **conf)
+ cherrypy.serving.request.hooks.attach(self._point, self._wrapper,
+ priority=p, **conf)
class HandlerWrapperTool(Tool):
@@ -206,10 +206,10 @@ class HandlerWrapperTool(Tool):
self._priority = priority
def callable(self):
- innerfunc = cherrypy.request.handler
+ innerfunc = cherrypy.serving.request.handler
def wrap(*args, **kwargs):
return self.newhandler(innerfunc, *args, **kwargs)
- cherrypy.request.handler = wrap
+ cherrypy.serving.request.handler = wrap
class ErrorTool(Tool):
@@ -227,7 +227,7 @@ class ErrorTool(Tool):
The standard CherryPy request object will automatically call this
method when the tool is "turned on" in config.
"""
- cherrypy.request.error_response = self._wrapper
+ cherrypy.serving.request.error_response = self._wrapper
# Builtin tools #
@@ -266,7 +266,7 @@ class SessionTool(Tool):
The standard CherryPy request object will automatically call this
method when the tool is "turned on" in config.
"""
- hooks = cherrypy.request.hooks
+ hooks = cherrypy.serving.request.hooks
conf = self._merged_args()
@@ -358,11 +358,11 @@ class XMLRPCController(object):
# cherrypy.lib.xmlrpc.on_error
raise Exception('method "%s" is not supported' % attr)
- conf = cherrypy.request.toolmaps['tools'].get("xmlrpc", {})
+ conf = cherrypy.serving.request.toolmaps['tools'].get("xmlrpc", {})
_xmlrpc.respond(body,
conf.get('encoding', 'utf-8'),
conf.get('allow_none', 0))
- return cherrypy.response.body
+ return cherrypy.serving.response.body
default.exposed = True
@@ -378,7 +378,7 @@ class CachingTool(Tool):
"""Caching Tool for CherryPy."""
def _wrapper(self, invalid_methods=("POST", "PUT", "DELETE"), **kwargs):
- request = cherrypy.request
+ request = cherrypy.serving.request
if not hasattr(cherrypy, "_cache"):
# Make a process-wide Cache object.
@@ -402,8 +402,8 @@ class CachingTool(Tool):
conf = self._merged_args()
p = conf.pop("priority", None)
- cherrypy.request.hooks.attach('before_handler', self._wrapper,
- priority=p, **conf)
+ cherrypy.serving.request.hooks.attach('before_handler', self._wrapper,
+ priority=p, **conf)
@@ -427,7 +427,7 @@ class Toolbox(object):
def __enter__(self):
"""Populate request.toolmaps from tools specified in config."""
- cherrypy.request.toolmaps[self.namespace] = map = {}
+ cherrypy.serving.request.toolmaps[self.namespace] = map = {}
def populate(k, v):
toolname, arg = k.split(".", 1)
bucket = map.setdefault(toolname, {})
@@ -436,7 +436,7 @@ class Toolbox(object):
def __exit__(self, exc_type, exc_val, exc_tb):
"""Run tool._setup() for each tool in our toolmap."""
- map = cherrypy.request.toolmaps.get(self.namespace)
+ map = cherrypy.serving.request.toolmaps.get(self.namespace)
if map:
for name, settings in map.items():
if settings.get("on", False):
diff --git a/cherrypy/_cptree.py b/cherrypy/_cptree.py
index 1c4f0b7a..1096248b 100644
--- a/cherrypy/_cptree.py
+++ b/cherrypy/_cptree.py
@@ -82,7 +82,7 @@ class Application(object):
def _get_script_name(self):
if self._script_name is None:
# None signals that the script name should be pulled from WSGI environ.
- return cherrypy.request.wsgi_environ['SCRIPT_NAME'].rstrip("/")
+ return cherrypy.serving.request.wsgi_environ['SCRIPT_NAME'].rstrip("/")
return self._script_name
def _set_script_name(self, value):
if value:
@@ -211,8 +211,9 @@ class Tree(object):
"""
if path is None:
try:
- path = httputil.urljoin(cherrypy.request.script_name,
- cherrypy.request.path_info)
+ request = cherrypy.serving.request
+ path = httputil.urljoin(request.script_name,
+ request.path_info)
except AttributeError:
return None
diff --git a/cherrypy/lib/auth.py b/cherrypy/lib/auth.py
index 1ef87f45..887e716d 100644
--- a/cherrypy/lib/auth.py
+++ b/cherrypy/lib/auth.py
@@ -4,9 +4,10 @@ from cherrypy.lib import httpauth
def check_auth(users, encrypt=None, realm=None):
"""If an authorization header contains credentials, return True, else False."""
- if 'authorization' in cherrypy.request.headers:
+ request = cherrypy.serving.request
+ if 'authorization' in request.headers:
# make sure the provided credentials are correctly set
- ah = httpauth.parseAuthorization(cherrypy.request.headers['authorization'])
+ ah = httpauth.parseAuthorization(request.headers['authorization'])
if ah is None:
raise cherrypy.HTTPError(400, 'Bad Request')
@@ -17,7 +18,7 @@ def check_auth(users, encrypt=None, realm=None):
try:
# backward compatibility
users = users() # expect it to return a dictionary
-
+
if not isinstance(users, dict):
raise ValueError("Authentication users must be a dictionary")
@@ -35,12 +36,12 @@ def check_auth(users, encrypt=None, realm=None):
# validate the authorization by re-computing it here
# and compare it with what the user-agent provided
- if httpauth.checkResponse(ah, password, method=cherrypy.request.method,
+ if httpauth.checkResponse(ah, password, method=request.method,
encrypt=encrypt, realm=realm):
- cherrypy.request.login = ah["username"]
+ request.login = ah["username"]
return True
-
- cherrypy.request.login = False
+
+ request.login = False
return False
def basic_auth(realm, users, encrypt=None):
@@ -55,7 +56,7 @@ def basic_auth(realm, users, encrypt=None):
return
# inform the user-agent this path is protected
- cherrypy.response.headers['www-authenticate'] = httpauth.basicAuth(realm)
+ cherrypy.serving.response.headers['www-authenticate'] = httpauth.basicAuth(realm)
raise cherrypy.HTTPError(401, "You are not authorized to access that resource")
@@ -69,7 +70,7 @@ def digest_auth(realm, users):
return
# inform the user-agent this path is protected
- cherrypy.response.headers['www-authenticate'] = httpauth.digestAuth(realm)
+ cherrypy.serving.response.headers['www-authenticate'] = httpauth.digestAuth(realm)
raise cherrypy.HTTPError(401, "You are not authorized to access that resource")
diff --git a/cherrypy/lib/auth_basic.py b/cherrypy/lib/auth_basic.py
index 581470cc..4cde7833 100644
--- a/cherrypy/lib/auth_basic.py
+++ b/cherrypy/lib/auth_basic.py
@@ -59,11 +59,12 @@ def basic_auth(realm, checkpassword):
'authorization' header. If authentication succeeds, checkpassword
returns True, else it returns False.
"""
-
+
if '"' in realm:
raise ValueError('Realm cannot contain the " (quote) character.')
-
- auth_header = cherrypy.request.headers.get('authorization')
+ request = cherrypy.serving.request
+
+ auth_header = request.headers.get('authorization')
if auth_header is not None:
try:
scheme, params = auth_header.split(' ', 1)
@@ -73,12 +74,12 @@ def basic_auth(realm, checkpassword):
username_password = base64.decodestring(params)
username, password = username_password.split(':', 1)
if checkpassword(realm, username, password):
- cherrypy.request.login = username
+ request.login = username
return # successful authentication
except (ValueError, binascii.Error): # split() error, base64.decodestring() error
raise cherrypy.HTTPError(400, 'Bad Request')
-
+
# Respond with 401 status and a WWW-Authenticate header
- cherrypy.response.headers['www-authenticate'] = 'Basic realm="%s"' % realm
+ cherrypy.serving.response.headers['www-authenticate'] = 'Basic realm="%s"' % realm
raise cherrypy.HTTPError(401, "You are not authorized to access that resource")
diff --git a/cherrypy/lib/auth_digest.py b/cherrypy/lib/auth_digest.py
index 0b629f27..011abcce 100644
--- a/cherrypy/lib/auth_digest.py
+++ b/cherrypy/lib/auth_digest.py
@@ -298,16 +298,16 @@ def www_authenticate(realm, key, algorithm='MD5', nonce=None, qop=qop_auth, stal
def digest_auth(realm, get_ha1, key, debug=False):
"""digest_auth is a CherryPy tool which hooks at before_handler to perform
HTTP Digest Access Authentication, as specified in RFC 2617.
-
+
If the request has an 'authorization' header with a 'Digest' scheme, this
tool authenticates the credentials supplied in that header. If
the request has no 'authorization' header, or if it does but the scheme is
not "Digest", or if authentication fails, the tool sends a 401 response with
a 'WWW-Authenticate' Digest header.
-
+
Arguments:
realm: a string containing the authentication realm.
-
+
get_ha1: a callable which looks up a username in a credentials store
and returns the HA1 string, which is defined in the RFC to be
MD5(username : realm : password). The function's signature is:
@@ -315,27 +315,28 @@ def digest_auth(realm, get_ha1, key, debug=False):
where username is obtained from the request's 'authorization' header.
If username is not found in the credentials store, get_ha1() returns
None.
-
+
key: a secret string known only to the server, used in the synthesis of nonces.
"""
-
- auth_header = cherrypy.request.headers.get('authorization')
+ request = cherrypy.serving.request
+
+ auth_header = request.headers.get('authorization')
nonce_is_stale = False
if auth_header is not None:
try:
- auth = HttpDigestAuthorization(auth_header, cherrypy.request.method, debug=debug)
+ auth = HttpDigestAuthorization(auth_header, request.method, debug=debug)
except ValueError, e:
raise cherrypy.HTTPError(400, 'Bad Request: %s' % e)
-
+
if debug:
TRACE(str(auth))
-
+
if auth.validate_nonce(realm, key):
ha1 = get_ha1(realm, auth.username)
if ha1 is not None:
# note that for request.body to be available we need to hook in at
# before_handler, not on_start_resource like 3.1.x digest_auth does.
- digest = auth.request_digest(ha1, entity_body=cherrypy.request.body)
+ digest = auth.request_digest(ha1, entity_body=request.body)
if digest == auth.response: # authenticated
if debug:
TRACE("digest matches auth.response")
@@ -343,15 +344,15 @@ def digest_auth(realm, get_ha1, key, debug=False):
# The choice of ten minutes' lifetime for nonce is somewhat arbitrary
nonce_is_stale = auth.is_nonce_stale(max_age_seconds=600)
if not nonce_is_stale:
- cherrypy.request.login = auth.username
+ request.login = auth.username
if debug:
TRACE("authentication of %s successful" % auth.username)
return
-
+
# Respond with 401 status and a WWW-Authenticate header
header = www_authenticate(realm, key, stale=nonce_is_stale)
if debug:
TRACE(header)
- cherrypy.response.headers['WWW-Authenticate'] = header
+ cherrypy.serving.response.headers['WWW-Authenticate'] = header
raise cherrypy.HTTPError(401, "You are not authorized to access that resource")
diff --git a/cherrypy/lib/caching.py b/cherrypy/lib/caching.py
index 4e395560..e97decb6 100644
--- a/cherrypy/lib/caching.py
+++ b/cherrypy/lib/caching.py
@@ -123,9 +123,9 @@ class MemoryCache:
self.cursize = 0
def key(self):
- request = cherrypy.request
+ request = cherrypy.serving.request
try:
- response = cherrypy.response
+ response = cherrypy.serving.response
except AttributeError:
response = None
return self.store.get_key_from_request(request, response)
@@ -169,7 +169,7 @@ class MemoryCache:
# checks if there's space for the object
if (obj_size < self.maxobj_size and total_size < self.maxsize):
# add to the expirations list and cache
- expiration_time = cherrypy.response.time + self.delay
+ expiration_time = cherrypy.serving.response.time + self.delay
obj_key = self.key()
bucket = self.expirations.setdefault(expiration_time, [])
bucket.append((obj_size, obj_key))
@@ -204,7 +204,8 @@ def get(invalid_methods=("POST", "PUT", "DELETE"), **kwargs):
* sets request.cacheable = True
* returns False
"""
- request = cherrypy.request
+ request = cherrypy.serving.request
+ response = cherrypy.serving.response
# POST, PUT, DELETE should invalidate (delete) the cached copy.
# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10.
@@ -218,7 +219,6 @@ def get(invalid_methods=("POST", "PUT", "DELETE"), **kwargs):
request.cached = c = bool(cache_data)
request.cacheable = not c
if c:
- response = cherrypy.response
s, h, b, create_time, original_req_headers = cache_data
# Copy the response headers. See http://www.cherrypy.org/ticket/721.
@@ -257,15 +257,14 @@ def tee_output():
if response.headers.get('Pragma', None) != 'no-cache':
# save the cache data
body = ''.join(output)
- vary = [he.value for he in
- cherrypy.response.headers.elements('Vary')]
+ vary = [he.value for he in response.headers.elements('Vary')]
sel_headers = dict([(k, v) for k, v
- in cherrypy.request.headers.items()
+ in cherrypy.serving.request.headers.items()
if k in vary])
cherrypy._cache.put((response.status, response.headers or {},
body, response.time, sel_headers))
- response = cherrypy.response
+ response = cherrypy.serving.response
response.body = tee(response.body)
@@ -286,7 +285,7 @@ def expires(secs=0, force=False):
none of the above response headers are set.
"""
- response = cherrypy.response
+ response = cherrypy.serving.response
headers = response.headers
cacheable = False
@@ -304,7 +303,7 @@ def expires(secs=0, force=False):
if secs == 0:
if force or "Pragma" not in headers:
headers["Pragma"] = "no-cache"
- if cherrypy.request.protocol >= (1, 1):
+ if cherrypy.serving.request.protocol >= (1, 1):
if force or "Cache-Control" not in headers:
headers["Cache-Control"] = "no-cache, must-revalidate"
# Set an explicit Expires date in the past.
diff --git a/cherrypy/lib/cptools.py b/cherrypy/lib/cptools.py
index cfa607b0..12594a4c 100644
--- a/cherrypy/lib/cptools.py
+++ b/cherrypy/lib/cptools.py
@@ -35,7 +35,7 @@ def validate_etags(autotags=False):
will be incorrect, and your application will break.
See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24
"""
- response = cherrypy.response
+ response = cherrypy.serving.response
# Guard against being run twice.
if hasattr(response, "ETag"):
@@ -58,7 +58,7 @@ def validate_etags(autotags=False):
# anything other than a 2xx or 412 status, then the If-Match header
# MUST be ignored."
if status >= 200 and status <= 299:
- request = cherrypy.request
+ request = cherrypy.serving.request
conditions = request.headers.elements('If-Match') or []
conditions = [str(x) for x in conditions]
@@ -81,12 +81,12 @@ def validate_since():
If no code has set the Last-Modified response header, then no validation
will be performed.
"""
- response = cherrypy.response
+ response = cherrypy.serving.response
lastmod = response.headers.get('Last-Modified')
if lastmod:
status, reason, msg = _httputil.valid_status(response.status)
- request = cherrypy.request
+ request = cherrypy.serving.request
since = request.headers.get('If-Unmodified-Since')
if since and since != lastmod:
@@ -122,7 +122,7 @@ def proxy(base=None, local='X-Forwarded-Host', remote='X-Forwarded-For',
want to rewrite remote.ip, set the 'remote' arg to an empty string.
"""
- request = cherrypy.request
+ request = cherrypy.serving.request
if scheme:
s = request.headers.get(scheme, None)
@@ -138,7 +138,7 @@ def proxy(base=None, local='X-Forwarded-Host', remote='X-Forwarded-For',
if local:
base = request.headers.get(local, base)
if not base:
- port = cherrypy.request.local.port
+ port = request.local.port
if port == 80:
base = '127.0.0.1'
else:
@@ -166,7 +166,7 @@ def ignore_headers(headers=('Range',)):
for example, Apache duplicates the work that CP does for 'Range'
headers, and will doubly-truncate the response.
"""
- request = cherrypy.request
+ request = cherrypy.serving.request
for name in headers:
if name in request.headers:
del request.headers[name]
@@ -175,7 +175,7 @@ def ignore_headers(headers=('Range',)):
def response_headers(headers=None):
"""Set headers on the response."""
for name, value in (headers or []):
- cherrypy.response.headers[name] = value
+ cherrypy.serving.response.headers[name] = value
response_headers.failsafe = True
@@ -191,7 +191,7 @@ def referer(pattern, accept=True, accept_missing=False, error=403,
message: a string to include in the response body on failure.
"""
try:
- match = bool(re.match(pattern, cherrypy.request.headers['Referer']))
+ match = bool(re.match(pattern, cherrypy.serving.request.headers['Referer']))
if accept == match:
return
except KeyError:
@@ -236,16 +236,18 @@ Message: %(error_msg)s
def do_login(self, username, password, from_page='..', **kwargs):
"""Login. May raise redirect, or return True if request handled."""
+ response = cherrypy.serving.response
error_msg = self.check_username_and_password(username, password)
if error_msg:
body = self.login_screen(from_page, username, error_msg)
- cherrypy.response.body = body
- if "Content-Length" in cherrypy.response.headers:
+ response.body = body
+ if "Content-Length" in response.headers:
# Delete Content-Length header so finalize() recalcs it.
- del cherrypy.response.headers["Content-Length"]
+ del response.headers["Content-Length"]
return True
else:
- cherrypy.session[self.session_key] = cherrypy.request.login = username
+ cherrypy.serving.request.login = username
+ cherrypy.session[self.session_key] = username
self.on_login(username)
raise cherrypy.HTTPRedirect(from_page or "/")
@@ -255,40 +257,43 @@ Message: %(error_msg)s
username = sess.get(self.session_key)
sess[self.session_key] = None
if username:
- cherrypy.request.login = None
+ cherrypy.serving.request.login = None
self.on_logout(username)
raise cherrypy.HTTPRedirect(from_page)
def do_check(self):
"""Assert username. May raise redirect, or return True if request handled."""
sess = cherrypy.session
- request = cherrypy.request
+ request = cherrypy.serving.request
+ response = cherrypy.serving.response
username = sess.get(self.session_key)
if not username:
sess[self.session_key] = username = self.anonymous()
if not username:
- cherrypy.response.body = self.login_screen(cherrypy.url(qs=request.query_string))
- if "Content-Length" in cherrypy.response.headers:
+ response.body = self.login_screen(cherrypy.url(qs=request.query_string))
+ if "Content-Length" in response.headers:
# Delete Content-Length header so finalize() recalcs it.
- del cherrypy.response.headers["Content-Length"]
+ del response.headers["Content-Length"]
return True
- cherrypy.request.login = username
+ request.login = username
self.on_check(username)
def run(self):
- request = cherrypy.request
+ request = cherrypy.serving.request
+ response = cherrypy.serving.response
+
path = request.path_info
if path.endswith('login_screen'):
return self.login_screen(**request.params)
elif path.endswith('do_login'):
if request.method != 'POST':
- cherrypy.response.headers['Allow'] = "POST"
+ response.headers['Allow'] = "POST"
raise cherrypy.HTTPError(405)
return self.do_login(**request.params)
elif path.endswith('do_logout'):
if request.method != 'POST':
- cherrypy.response.headers['Allow'] = "POST"
+ response.headers['Allow'] = "POST"
raise cherrypy.HTTPError(405)
return self.do_logout(**request.params)
else:
@@ -315,22 +320,24 @@ def log_traceback(severity=logging.ERROR):
def log_request_headers():
"""Write request headers to the cherrypy error log."""
- h = [" %s: %s" % (k, v) for k, v in cherrypy.request.header_list]
+ h = [" %s: %s" % (k, v) for k, v in cherrypy.serving.request.header_list]
cherrypy.log('\nRequest Headers:\n' + '\n'.join(h), "HTTP")
def log_hooks():
"""Write request.hooks to the cherrypy error log."""
+ request = cherrypy.serving.request
+
msg = []
# Sort by the standard points if possible.
from cherrypy import _cprequest
points = _cprequest.hookpoints
- for k in cherrypy.request.hooks.keys():
+ for k in request.hooks.keys():
if k not in points:
points.append(k)
for k in points:
msg.append(" %s:" % k)
- v = cherrypy.request.hooks.get(k, [])
+ v = request.hooks.get(k, [])
v.sort()
for h in v:
msg.append(" %r" % h)
@@ -346,7 +353,7 @@ def redirect(url='', internal=True):
def trailing_slash(missing=True, extra=False, status=None):
"""Redirect if path_info has (missing|extra) trailing slash."""
- request = cherrypy.request
+ request = cherrypy.serving.request
pi = request.path_info
if request.is_index is True:
@@ -375,7 +382,7 @@ def flatten():
else:
for y in flattener(x):
yield y
- response = cherrypy.response
+ response = cherrypy.serving.response
response.body = flattener(response.body)
@@ -407,10 +414,11 @@ def accept(media=None):
return
if isinstance(media, basestring):
media = [media]
+ request = cherrypy.serving.request
# Parse the Accept request header, and try to match one
# of the requested media-ranges (in order of preference).
- ranges = cherrypy.request.headers.elements('Accept')
+ ranges = request.headers.elements('Accept')
if not ranges:
# Any media type is acceptable.
return media[0]
@@ -433,7 +441,7 @@ def accept(media=None):
return element.value
# No suitable media-range found.
- ah = cherrypy.request.headers.get('Accept')
+ ah = request.headers.get('Accept')
if ah is None:
msg = "Your client did not send an Accept header."
else:
@@ -467,22 +475,23 @@ class MonitoredHeaderMap(_httputil.HeaderMap):
def autovary(ignore=None):
"""Auto-populate the Vary response header based on request.header access."""
- req_h = cherrypy.request.headers
- cherrypy.request.headers = MonitoredHeaderMap()
- cherrypy.request.headers.update(req_h)
+ request = cherrypy.serving.request
+
+ req_h = request.headers
+ request.headers = MonitoredHeaderMap()
+ request.headers.update(req_h)
if ignore is None:
ignore = set(['Content-Disposition', 'Content-Length', 'Content-Type'])
def set_response_header():
- resp_h = cherrypy.response.headers
+ resp_h = cherrypy.serving.response.headers
v = set([e.value for e in resp_h.elements('Vary')])
- v = v.union(cherrypy.request.headers.accessed_headers)
+ v = v.union(request.headers.accessed_headers)
v = v.difference(ignore)
v = list(v)
v.sort()
resp_h['Vary'] = ', '.join(v)
- cherrypy.request.hooks.attach(
- 'before_finalize', set_response_header, 95)
+ request.hooks.attach('before_finalize', set_response_header, 95)
diff --git a/cherrypy/lib/encoding.py b/cherrypy/lib/encoding.py
index 287228dc..2e469e90 100644
--- a/cherrypy/lib/encoding.py
+++ b/cherrypy/lib/encoding.py
@@ -29,11 +29,11 @@ class ResponseEncoder:
setattr(self, k, v)
self.attempted_charsets = set()
-
- if cherrypy.request.handler is not None:
+ request = cherrypy.serving.request
+ if request.handler is not None:
# Replace request.handler with self
- self.oldhandler = cherrypy.request.handler
- cherrypy.request.handler = self
+ self.oldhandler = request.handler
+ request.handler = self
def encode_stream(self, encoding):
"""Encode a streaming response body.
@@ -72,9 +72,10 @@ class ResponseEncoder:
return True
def find_acceptable_charset(self):
- response = cherrypy.response
+ request = cherrypy.serving.request
+ response = cherrypy.serving.response
- if cherrypy.response.stream:
+ if response.stream:
encoder = self.encode_stream
else:
encoder = self.encode_string
@@ -93,7 +94,7 @@ class ResponseEncoder:
# Parse the Accept-Charset request header, and try to provide one
# of the requested charsets (in order of user preference).
- encs = cherrypy.request.headers.elements('Accept-Charset')
+ encs = request.headers.elements('Accept-Charset')
charsets = [enc.value.lower() for enc in encs]
if self.encoding is not None:
@@ -132,7 +133,7 @@ class ResponseEncoder:
return encoding
# No suitable encoding found.
- ac = cherrypy.request.headers.get('Accept-Charset')
+ ac = request.headers.get('Accept-Charset')
if ac is None:
msg = "Your client did not send an Accept-Charset header."
else:
@@ -141,6 +142,7 @@ class ResponseEncoder:
raise cherrypy.HTTPError(406, msg)
def __call__(self, *args, **kwargs):
+ response = cherrypy.serving.response
self.body = self.oldhandler(*args, **kwargs)
if isinstance(self.body, basestring):
@@ -157,14 +159,14 @@ class ResponseEncoder:
elif self.body is None:
self.body = []
- ct = cherrypy.response.headers.elements("Content-Type")
+ ct = response.headers.elements("Content-Type")
if ct:
ct = ct[0]
if (not self.text_only) or ct.value.lower().startswith("text/"):
# Set "charset=..." param on response Content-Type header
ct.params['charset'] = self.find_acceptable_charset()
if self.add_charset:
- cherrypy.response.headers["Content-Type"] = str(ct)
+ response.headers["Content-Type"] = str(ct)
return self.body
@@ -223,7 +225,8 @@ def gzip(compress_level=5, mime_types=['text/html', 'text/plain']):
* No 'gzip' or 'x-gzip' with a qvalue > 0 is present
* The 'identity' value is given with a qvalue > 0.
"""
- response = cherrypy.response
+ request = cherrypy.serving.request
+ response = cherrypy.serving.response
set_vary_header(response, "Accept-Encoding")
@@ -233,10 +236,10 @@ def gzip(compress_level=5, mime_types=['text/html', 'text/plain']):
# If returning cached content (which should already have been gzipped),
# don't re-zip.
- if getattr(cherrypy.request, "cached", False):
+ if getattr(request, "cached", False):
return
- acceptable = cherrypy.request.headers.elements('Accept-Encoding')
+ acceptable = request.headers.elements('Accept-Encoding')
if not acceptable:
# If no Accept-Encoding field is present in a request,
# the server MAY assume that the client will accept any
diff --git a/cherrypy/lib/jsontools.py b/cherrypy/lib/jsontools.py
index ef231183..b867a9e6 100644
--- a/cherrypy/lib/jsontools.py
+++ b/cherrypy/lib/jsontools.py
@@ -20,7 +20,7 @@ else:
json_encode = json.JSONEncoder().iterencode
def json_in(*args, **kwargs):
- request = cherrypy.request
+ request = cherrypy.serving.request
_h = request.headers
if ('Content-Type' not in _h
or _h.elements('Content-Type')[0].value != 'application/json'):
@@ -37,8 +37,8 @@ def json_in(*args, **kwargs):
request.json = json
def json_out(*args, **kwargs):
- request = cherrypy.request
- response = cherrypy.response
+ request = cherrypy.serving.request
+ response = cherrypy.serving.response
real_handler = request.handler
def json_handler(*args, **kwargs):
diff --git a/cherrypy/lib/sessions.py b/cherrypy/lib/sessions.py
index c84794eb..11bce96f 100644
--- a/cherrypy/lib/sessions.py
+++ b/cherrypy/lib/sessions.py
@@ -578,21 +578,23 @@ def save():
if not hasattr(cherrypy.serving, "session"):
return
+ request = cherrypy.serving.request
+ response = cherrypy.serving.response
# Guard against running twice
- if hasattr(cherrypy.request, "_sessionsaved"):
+ if hasattr(request, "_sessionsaved"):
return
- cherrypy.request._sessionsaved = True
+ request._sessionsaved = True
- if cherrypy.response.stream:
+ if response.stream:
# If the body is being streamed, we have to save the data
# *after* the response has been written out
- cherrypy.request.hooks.attach('on_end_request', cherrypy.session.save)
+ request.hooks.attach('on_end_request', cherrypy.session.save)
else:
# If the body is not being streamed, we save the data now
# (so we can release the lock).
- if isinstance(cherrypy.response.body, types.GeneratorType):
- cherrypy.response.collapse_body()
+ if isinstance(response.body, types.GeneratorType):
+ response.collapse_body()
cherrypy.session.save()
save.failsafe = True
@@ -635,7 +637,7 @@ def init(storage_type='ram', path=None, path_header=None, name='session_id',
you're using for more information.
"""
- request = cherrypy.request
+ request = cherrypy.serving.request
# Guard against running twice
if hasattr(request, "_session_init_flag"):
@@ -662,7 +664,7 @@ def init(storage_type='ram', path=None, path_header=None, name='session_id',
cherrypy.serving.session = sess = storage_class(id, **kwargs)
def update_cookie(id):
"""Update the cookie every time the session id changes."""
- cherrypy.response.cookie[name] = id
+ cherrypy.serving.response.cookie[name] = id
sess.id_observers.append(update_cookie)
# Create cherrypy.session which will proxy to cherrypy.serving.session
@@ -695,9 +697,9 @@ def set_response_cookie(path=None, path_header=None, name='session_id',
be set. If True, the cookie 'secure' value will be set (to 1).
"""
# Set response cookie
- cookie = cherrypy.response.cookie
+ cookie = cherrypy.serving.response.cookie
cookie[name] = cherrypy.serving.session.id
- cookie[name]['path'] = (path or cherrypy.request.headers.get(path_header)
+ cookie[name]['path'] = (path or cherrypy.serving.request.headers.get(path_header)
or '/')
# We'd like to use the "max-age" param as indicated in
@@ -716,9 +718,9 @@ def set_response_cookie(path=None, path_header=None, name='session_id',
def expire():
"""Expire the current session cookie."""
- name = cherrypy.request.config.get('tools.sessions.name', 'session_id')
+ name = cherrypy.serving.request.config.get('tools.sessions.name', 'session_id')
one_year = 60 * 60 * 24 * 365
e = time.time() - one_year
- cherrypy.response.cookie[name]['expires'] = httputil.HTTPDate(e)
+ cherrypy.serving.response.cookie[name]['expires'] = httputil.HTTPDate(e)
diff --git a/cherrypy/lib/static.py b/cherrypy/lib/static.py
index 697fa8e8..db64890a 100644
--- a/cherrypy/lib/static.py
+++ b/cherrypy/lib/static.py
@@ -29,7 +29,7 @@ def serve_file(path, content_type=None, disposition=None, name=None):
header will be written.
"""
- response = cherrypy.response
+ response = cherrypy.serving.response
# If path is relative, users should fix it by making path absolute.
# That is, CherryPy should not guess where the application root is.
@@ -94,7 +94,7 @@ def serve_fileobj(fileobj, content_type=None, disposition=None, name=None):
position.
"""
- response = cherrypy.response
+ response = cherrypy.serving.response
try:
st = os.fstat(fileobj.fileno())
@@ -121,13 +121,13 @@ def serve_fileobj(fileobj, content_type=None, disposition=None, name=None):
def _serve_fileobj(fileobj, content_type, content_length):
"""Internal. Set response.body to the given file object, perhaps ranged."""
- response = cherrypy.response
+ response = cherrypy.serving.response
# HTTP/1.0 didn't have Range/Accept-Ranges headers, or the 206 code
- if cherrypy.request.protocol >= (1, 1):
+ request = cherrypy.serving.request
+ if request.protocol >= (1, 1):
response.headers["Accept-Ranges"] = "bytes"
- r = httputil.get_ranges(cherrypy.request.headers.get('Range'),
- content_length)
+ r = httputil.get_ranges(request.headers.get('Range'), content_length)
if r == []:
response.headers['Content-Range'] = "bytes */%s" % content_length
message = "Invalid Range (first-byte-pos greater than Content-Length)"
@@ -221,10 +221,11 @@ def staticdir(section, dir, root="", match="", content_types=None, index=""):
'/home/me', the Request-URI is 'myapp', and the index arg is
'index.html', the file '/home/me/myapp/index.html' will be sought.
"""
- if cherrypy.request.method not in ('GET', 'HEAD'):
+ request = cherrypy.serving.request
+ if request.method not in ('GET', 'HEAD'):
return False
- if match and not re.search(match, cherrypy.request.path_info):
+ if match and not re.search(match, request.path_info):
return False
# Allow the use of '~' to refer to a user's home directory.
@@ -242,13 +243,13 @@ def staticdir(section, dir, root="", match="", content_types=None, index=""):
if section == 'global':
section = "/"
section = section.rstrip(r"\/")
- branch = cherrypy.request.path_info[len(section) + 1:]
+ branch = request.path_info[len(section) + 1:]
branch = unquote(branch.lstrip(r"\/"))
# If branch is "", filename will end in a slash
filename = os.path.join(dir, branch)
cherrypy.log('Checking file %r to fulfill %r' %
- (filename, cherrypy.request.path_info),
+ (filename, request.path_info),
context='tools.staticdir', severity=logging.DEBUG)
# There's a chance that the branch pulled from the URL might
@@ -263,7 +264,7 @@ def staticdir(section, dir, root="", match="", content_types=None, index=""):
if index:
handled = _attempt(os.path.join(filename, index), content_types)
if handled:
- cherrypy.request.is_index = filename[-1] in (r"\/")
+ request.is_index = filename[-1] in (r"\/")
return handled
def staticfile(filename, root=None, match="", content_types=None):
@@ -277,10 +278,11 @@ def staticfile(filename, root=None, match="", content_types=None):
a string (e.g. "gif") and 'content-type' is the value to write
out in the Content-Type response header (e.g. "image/gif").
"""
- if cherrypy.request.method not in ('GET', 'HEAD'):
+ request = cherrypy.serving.request
+ if request.method not in ('GET', 'HEAD'):
return False
- if match and not re.search(match, cherrypy.request.path_info):
+ if match and not re.search(match, request.path_info):
return False
# If filename is relative, make absolute using "root".
diff --git a/cherrypy/test/test.py b/cherrypy/test/test.py
index 3d75b6bf..76a3b0f2 100644
--- a/cherrypy/test/test.py
+++ b/cherrypy/test/test.py
@@ -18,6 +18,8 @@ serverpem = os.path.join(os.getcwd(), localDir, 'test.pem')
import sys
import warnings
+from cherrypy.lib import profiler
+
class TestHarness(object):
"""A test harness for the CherryPy framework and CherryPy applications."""
@@ -152,7 +154,7 @@ class LocalServer(object):
except ImportError:
warnings.warn("Error importing wsgiconq. pyconquer will not run.")
else:
- app = wsgiconq.WSGILogger(app)
+ app = wsgiconq.WSGILogger(app, c_calls=True)
if self.validate:
try:
from wsgiref import validate
diff --git a/cherrypy/wsgiserver/__init__.py b/cherrypy/wsgiserver/__init__.py
index eb335b8d..5ab12737 100644
--- a/cherrypy/wsgiserver/__init__.py
+++ b/cherrypy/wsgiserver/__init__.py
@@ -557,7 +557,13 @@ class HTTPRequest(object):
data = StringIO.StringIO()
while True:
line = self.rfile.readline().strip().split(";", 1)
- chunk_size = int(line.pop(0), 16)
+ try:
+ chunk_size = line.pop(0)
+ chunk_size = int(chunk_size, 16)
+ except ValueError:
+ self.simple_response("400 Bad Request",
+ "Bad chunked transfer size: " + repr(chunk_size))
+ return
if chunk_size <= 0:
break
## if line: chunk_extension = line[0]