Commit a9f2bb81 authored by Jim Fulton's avatar Jim Fulton

Added a new protocol for request objects. There is a new method,

processInputs that is called by the publisher at the start of request
processing. Any request processing that can raise errors must be
defered at least until this method is called so that the publisher can
handle the errors. BaseRequest now has an empty implementation for
this method and HTTPRequest defers most of it's initialization to this
method.

This fixes a bug in handling of form inut errors, which were being
raised as ZServer server errors.
parent 2006abe1
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
# attributions are listed in the accompanying credits file. # attributions are listed in the accompanying credits file.
# #
############################################################################## ##############################################################################
__version__='$Revision: 1.11 $'[11:-2] __version__='$Revision: 1.12 $'[11:-2]
from string import join, split, find, rfind, lower, upper from string import join, split, find, rfind, lower, upper
from urllib import quote from urllib import quote
...@@ -122,11 +122,17 @@ class BaseRequest: ...@@ -122,11 +122,17 @@ class BaseRequest:
_auth=None _auth=None
def __init__(self, other=None, **kw): def __init__(self, other=None, **kw):
"""The constructor is not allowed to raise errors
"""
if other is None: other=kw if other is None: other=kw
else: else:
for k, v in kw.items(): other[k]=v for k, v in kw.items(): other[k]=v
self.other=other self.other=other
def processInputs(self):
"""Do any input processing that could raise errors
"""
def __len__(self): def __len__(self):
return 1 return 1
......
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
# #
############################################################################## ##############################################################################
__version__='$Revision: 1.18 $'[11:-2] __version__='$Revision: 1.19 $'[11:-2]
import regex, sys, os, string import regex, sys, os, string
from string import lower, atoi, rfind, split, strip, join, upper, find from string import lower, atoi, rfind, split, strip, join, upper, find
...@@ -170,7 +170,21 @@ class HTTPRequest(BaseRequest): ...@@ -170,7 +170,21 @@ class HTTPRequest(BaseRequest):
_hacked_path=None _hacked_path=None
args=() args=()
def __init__(self, stdin, environ, response, clean=0, def __init__(self, stdin, environ, response, clean=0):
# Avoid the overhead of scrubbing the environment in the
# case of request cloning for traversal purposes. If the
# clean flag is set, we know we can use the passed in
# environ dict directly.
if not clean: environ=sane_environment(environ)
self.stdin=stdin
self.environ=environ
self.response=response
other=self.other={}
def processInputs(
self,
# "static" variables that we want to be local for speed # "static" variables that we want to be local for speed
SEQUENCE=1, SEQUENCE=1,
DEFAULT=2, DEFAULT=2,
...@@ -182,21 +196,19 @@ class HTTPRequest(BaseRequest): ...@@ -182,21 +196,19 @@ class HTTPRequest(BaseRequest):
hasattr=hasattr, hasattr=hasattr,
getattr=getattr, getattr=getattr,
setattr=setattr, setattr=setattr,
search_type=regex.compile( search_type=regex.compile(':[a-zA-Z][a-zA-Z0-9_]+$').search,
':[a-zA-Z][a-zA-Z0-9_]+$'
).search,
rfind=string.rfind, rfind=string.rfind,
): ):
# Avoid the overhead of scrubbing the environment in the """Process request inputs
# case of request cloning for traversal purposes. If the
# clean flag is set, we know we can use the passed in
# environ dict directly.
if not clean: environ=sane_environment(environ)
We need to delay input parsing so that it is done under publisher control for
error handling prposes.
"""
response=self.response
environ=self.environ
method=environ.get('REQUEST_METHOD','GET') method=environ.get('REQUEST_METHOD','GET')
if method != 'GET': fp=stdin if method != 'GET': fp=self.stdin
else: fp=None else: fp=None
if environ.has_key('HTTP_AUTHORIZATION'): if environ.has_key('HTTP_AUTHORIZATION'):
...@@ -205,7 +217,7 @@ class HTTPRequest(BaseRequest): ...@@ -205,7 +217,7 @@ class HTTPRequest(BaseRequest):
del environ['HTTP_AUTHORIZATION'] del environ['HTTP_AUTHORIZATION']
form={} form={}
other=self.other={} other=self.other
meth=None meth=None
fs=FieldStorage(fp=fp,environ=environ,keep_blank_values=1) fs=FieldStorage(fp=fp,environ=environ,keep_blank_values=1)
if not hasattr(fs,'list') or fs.list is None: if not hasattr(fs,'list') or fs.list is None:
...@@ -217,7 +229,7 @@ class HTTPRequest(BaseRequest): ...@@ -217,7 +229,7 @@ class HTTPRequest(BaseRequest):
global xmlrpc global xmlrpc
if xmlrpc is None: import xmlrpc if xmlrpc is None: import xmlrpc
meth, self.args = xmlrpc.parse_input(fs.value) meth, self.args = xmlrpc.parse_input(fs.value)
response=xmlrpc.response(response) response=self.response=xmlrpc.response(response)
other['REQUEST_METHOD']='' # We don't want index_html! other['REQUEST_METHOD']='' # We don't want index_html!
else: else:
self._file=fs.file self._file=fs.file
...@@ -529,10 +541,8 @@ class HTTPRequest(BaseRequest): ...@@ -529,10 +541,8 @@ class HTTPRequest(BaseRequest):
self.form=form self.form=form
self.cookies=cookies self.cookies=cookies
other['RESPONSE']=self.response=response other['RESPONSE']=response
self.environ=environ
self.stdin=stdin
have_env=environ.has_key have_env=environ.has_key
b=script=strip(environ['SCRIPT_NAME']) b=script=strip(environ['SCRIPT_NAME'])
......
...@@ -84,8 +84,8 @@ ...@@ -84,8 +84,8 @@
############################################################################## ##############################################################################
__doc__="""Python Object Publisher -- Publish Python objects on web servers __doc__="""Python Object Publisher -- Publish Python objects on web servers
$Id: Publish.py,v 1.133 1999/08/03 15:40:38 jim Exp $""" $Id: Publish.py,v 1.134 1999/08/04 12:01:20 jim Exp $"""
__version__='$Revision: 1.133 $'[11:-2] __version__='$Revision: 1.134 $'[11:-2]
import sys, os import sys, os
from string import lower, atoi, rfind, strip from string import lower, atoi, rfind, strip
...@@ -239,7 +239,6 @@ def publish_module(module_name, ...@@ -239,7 +239,6 @@ def publish_module(module_name,
must_die=0 must_die=0
status=200 status=200
after_list=[None] after_list=[None]
try:
try: try:
try: try:
if response is None: if response is None:
...@@ -248,8 +247,7 @@ def publish_module(module_name, ...@@ -248,8 +247,7 @@ def publish_module(module_name,
stdout=response.stdout stdout=response.stdout
if request is None: if request is None:
request=Request(stdin, environ, response) request=Request(stdin, environ, response)
finally: request.processInputs()
pass
response=request.response # could have changed! response=request.response # could have changed!
response = publish(request, module_name, after_list, debug=debug) response = publish(request, module_name, after_list, debug=debug)
except SystemExit, v: except SystemExit, v:
......
...@@ -162,9 +162,9 @@ Examples ...@@ -162,9 +162,9 @@ Examples
s s
$Id: Test.py,v 1.31 1999/06/29 18:24:43 jim Exp $ $Id: Test.py,v 1.32 1999/08/04 12:01:20 jim Exp $
''' '''
__version__='$Revision: 1.31 $'[11:-2] __version__='$Revision: 1.32 $'[11:-2]
import sys, traceback, profile, os, getopt, string import sys, traceback, profile, os, getopt, string
from time import clock from time import clock
...@@ -248,7 +248,6 @@ def publish_module(module_name, ...@@ -248,7 +248,6 @@ def publish_module(module_name,
from Response import Response from Response import Response
from Request import Request from Request import Request
from Publish import publish from Publish import publish
try:
try: try:
try: try:
if response is None: if response is None:
...@@ -257,8 +256,7 @@ def publish_module(module_name, ...@@ -257,8 +256,7 @@ def publish_module(module_name,
stdout=response.stdout stdout=response.stdout
if request is None: if request is None:
request=Request(stdin, environ, response) request=Request(stdin, environ, response)
finally: request.processInputs()
pass
response=request.response # could have changed! response=request.response # could have changed!
for k, v in extra.items(): request[k]=v for k, v in extra.items(): request[k]=v
response = publish(request, module_name, after_list, debug=debug) response = publish(request, module_name, after_list, debug=debug)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment