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
...@@ -169,34 +169,46 @@ class HTTPRequest(BaseRequest): ...@@ -169,34 +169,46 @@ 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):
# "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,
):
# Avoid the overhead of scrubbing the environment in the # Avoid the overhead of scrubbing the environment in the
# case of request cloning for traversal purposes. If the # case of request cloning for traversal purposes. If the
# clean flag is set, we know we can use the passed in # clean flag is set, we know we can use the passed in
# environ dict directly. # environ dict directly.
if not clean: environ=sane_environment(environ) 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') 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
...@@ -241,15 +241,13 @@ def publish_module(module_name, ...@@ -241,15 +241,13 @@ def publish_module(module_name,
after_list=[None] after_list=[None]
try: try:
try: try:
try: if response is None:
if response is None: response=Response(stdout=stdout, stderr=stderr)
response=Response(stdout=stdout, stderr=stderr) else:
else: stdout=response.stdout
stdout=response.stdout if request is None:
if request is None: request=Request(stdin, environ, response)
request=Request(stdin, environ, response) request.processInputs()
finally:
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
...@@ -250,15 +250,13 @@ def publish_module(module_name, ...@@ -250,15 +250,13 @@ def publish_module(module_name,
from Publish import publish from Publish import publish
try: try:
try: try:
try: if response is None:
if response is None: response=Response(stdout=stdout, stderr=stderr)
response=Response(stdout=stdout, stderr=stderr) else:
else: stdout=response.stdout
stdout=response.stdout if request is None:
if request is None: request=Request(stdin, environ, response)
request=Request(stdin, environ, response) request.processInputs()
finally:
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