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 @@
# 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 urllib import quote
......@@ -122,11 +122,17 @@ class BaseRequest:
_auth=None
def __init__(self, other=None, **kw):
"""The constructor is not allowed to raise errors
"""
if other is None: other=kw
else:
for k, v in kw.items(): other[k]=v
self.other=other
def processInputs(self):
"""Do any input processing that could raise errors
"""
def __len__(self):
return 1
......
......@@ -83,7 +83,7 @@
#
##############################################################################
__version__='$Revision: 1.18 $'[11:-2]
__version__='$Revision: 1.19 $'[11:-2]
import regex, sys, os, string
from string import lower, atoi, rfind, split, strip, join, upper, find
......@@ -169,34 +169,46 @@ class HTTPRequest(BaseRequest):
"""
_hacked_path=None
args=()
def __init__(self, stdin, environ, response, clean=0,
# "static" variables that we want to be local for speed
SEQUENCE=1,
DEFAULT=2,
RECORD=4,
RECORDS=8,
REC=12, # RECORD|RECORDS
EMPTY=16,
CONVERTED=32,
hasattr=hasattr,
getattr=getattr,
setattr=setattr,
search_type=regex.compile(
':[a-zA-Z][a-zA-Z0-9_]+$'
).search,
rfind=string.rfind,
):
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
SEQUENCE=1,
DEFAULT=2,
RECORD=4,
RECORDS=8,
REC=12, # RECORD|RECORDS
EMPTY=16,
CONVERTED=32,
hasattr=hasattr,
getattr=getattr,
setattr=setattr,
search_type=regex.compile(':[a-zA-Z][a-zA-Z0-9_]+$').search,
rfind=string.rfind,
):
"""Process request inputs
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')
if method != 'GET': fp=stdin
if method != 'GET': fp=self.stdin
else: fp=None
if environ.has_key('HTTP_AUTHORIZATION'):
......@@ -205,7 +217,7 @@ class HTTPRequest(BaseRequest):
del environ['HTTP_AUTHORIZATION']
form={}
other=self.other={}
other=self.other
meth=None
fs=FieldStorage(fp=fp,environ=environ,keep_blank_values=1)
if not hasattr(fs,'list') or fs.list is None:
......@@ -217,7 +229,7 @@ class HTTPRequest(BaseRequest):
global xmlrpc
if xmlrpc is None: import xmlrpc
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!
else:
self._file=fs.file
......@@ -529,10 +541,8 @@ class HTTPRequest(BaseRequest):
self.form=form
self.cookies=cookies
other['RESPONSE']=self.response=response
other['RESPONSE']=response
self.environ=environ
self.stdin=stdin
have_env=environ.has_key
b=script=strip(environ['SCRIPT_NAME'])
......
......@@ -84,8 +84,8 @@
##############################################################################
__doc__="""Python Object Publisher -- Publish Python objects on web servers
$Id: Publish.py,v 1.133 1999/08/03 15:40:38 jim Exp $"""
__version__='$Revision: 1.133 $'[11:-2]
$Id: Publish.py,v 1.134 1999/08/04 12:01:20 jim Exp $"""
__version__='$Revision: 1.134 $'[11:-2]
import sys, os
from string import lower, atoi, rfind, strip
......@@ -241,15 +241,13 @@ def publish_module(module_name,
after_list=[None]
try:
try:
try:
if response is None:
response=Response(stdout=stdout, stderr=stderr)
else:
stdout=response.stdout
if request is None:
request=Request(stdin, environ, response)
finally:
pass
if response is None:
response=Response(stdout=stdout, stderr=stderr)
else:
stdout=response.stdout
if request is None:
request=Request(stdin, environ, response)
request.processInputs()
response=request.response # could have changed!
response = publish(request, module_name, after_list, debug=debug)
except SystemExit, v:
......
......@@ -162,9 +162,9 @@ Examples
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
from time import clock
......@@ -250,15 +250,13 @@ def publish_module(module_name,
from Publish import publish
try:
try:
try:
if response is None:
response=Response(stdout=stdout, stderr=stderr)
else:
stdout=response.stdout
if request is None:
request=Request(stdin, environ, response)
finally:
pass
if response is None:
response=Response(stdout=stdout, stderr=stderr)
else:
stdout=response.stdout
if request is None:
request=Request(stdin, environ, response)
request.processInputs()
response=request.response # could have changed!
for k, v in extra.items(): request[k]=v
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