Commit 8babcee3 authored by Jim Fulton's avatar Jim Fulton

Made a number of optimizations to the new form processing logic.

Did I break anything? :)

Also changed xml-rpc handling so that index_html is not used.
parent 60b6d59f
......@@ -83,7 +83,7 @@
#
##############################################################################
__version__='$Revision: 1.13 $'[11:-2]
__version__='$Revision: 1.14 $'[11:-2]
import regex, sys, os, string
from string import lower, atoi, rfind, split, strip, join, upper, find
......@@ -91,7 +91,7 @@ from BaseRequest import BaseRequest
from HTTPResponse import HTTPResponse
from cgi import FieldStorage
from urllib import quote, unquote
from Converters import type_converters
from Converters import get_converter
from maybe_lock import allocate_lock
xmlrpc=None # Placeholder for module that we'll import if we have to.
......@@ -170,7 +170,23 @@ class HTTPRequest(BaseRequest):
_hacked_path=None
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
# case of request cloning for traversal purposes. If the
# clean flag is set, we know we can use the passed in
......@@ -189,8 +205,7 @@ class HTTPRequest(BaseRequest):
del environ['HTTP_AUTHORIZATION']
form={}
defaults={}
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:
......@@ -203,17 +218,20 @@ class HTTPRequest(BaseRequest):
if xmlrpc is None: import xmlrpc
meth, self.args = xmlrpc.parse_input(fs.value)
response=xmlrpc.response(response)
other['REQUEST_METHOD']='' # We don't want index_html!
else:
self._file=fs.file
else:
fslist=fs.list
tuple_items={}
type_re=regex.compile(':[a-zA-Z][a-zA-Z0-9_]+')
type_search=type_re.search
lt=type([])
CGI_name=isCGI_NAME
defaults={}
converter=seqf=None
for item in fslist:
key=unquote(item.name)
key=item.name
if (hasattr(item,'file') and hasattr(item,'filename')
and hasattr(item,'headers')):
if (item.file and
......@@ -224,75 +242,77 @@ class HTTPRequest(BaseRequest):
else:
item=item.value
# tuple, list flag
seqf=None
# default flag
setting_a_default=0
# record flag
record_flag=0
# records_flag
records_flag=0
# empty_flag
empty_flag=0
# Use converter variable to defer conversion
converter=None
# add dictionary of types
d1 = {'list':1, 'tuple':1, 'method':1, 'default_method':1,
'default':1, 'record':1, 'records':1, 'ignore_empty':1}
flags=0
# Loop through the different types and set
# the appropriate flags
l=type_search(key)
# We'll search from the back to the front.
# We'll do the search in two steps. First, we'll
# do a string search, and then we'll check it with
# a regex search.
l=rfind(key,':')
if l >= 0:
l=search_type(key,l)
while l >= 0:
type_name=type_re.group(0)[1:]
key=key[:l]+key[l+len(type_name)+1:]
if type_name not in d1.keys():
converter=type_converters[type_name]
else:
if type_name == 'list':
type_name=key[l+1:]
key=key[:l]
c=get_converter(type_name, None)
if c is not None:
converter=c
flags=flags|CONVERTED
elif type_name == 'list':
seqf=list
if type_name == 'tuple':
flags=flags|SEQUENCE
elif type_name == 'tuple':
seqf=tuple
tuple_items[key]=1
if type_name == 'method':
flags=flags|SEQUENCE
elif type_name == 'method':
if l: meth=key
else: meth=item
if type_name == 'default_method':
elif type_name == 'default_method':
if not meth:
if l: meth=key
else: meth=item
if type_name == 'default':
setting_a_default = 1
if type_name == 'record':
record_flag = 1
if type_name == 'records':
records_flag = 1
if type_name == 'ignore_empty':
if item == "":
empty_flag = 1
l=type_search(key)
# skip over empty fields
if empty_flag: continue
elif type_name == 'default':
flags=flags|DEFAULT
elif type_name == 'record':
flags=flags|RECORD
elif type_name == 'records':
flags=flags|RECORDS
elif type_name == 'ignore_empty':
if not item: flags=flags|EMPTY
l=rfind(key,':')
if l < 0: break
l=search_type(key,l)
# Filter out special names from form:
if CGI_name(key) or key[:5]=='HTTP_': continue
if flags:
# skip over empty fields
if flags&EMPTY: continue
#Split the key and its attribute
if record_flag or records_flag:
if flags&REC:
key=split(key,".")
key, attr=join(key[:-1],"."), key[-1]
# defer conversion
if converter is not None:
if flags&CONVERTED:
try:
item=converter(item)
except:
if not item and not setting_a_default and defaults.has_key(key):
if (not item and not (flags&DEFAULT) and
defaults.has_key(key)):
item = defaults[key]
if record_flag:
if flags&RECORD:
item=getattr(item,attr)
if records_flag:
if flags&RECORDS:
item.reverse()
item = item[0]
item=getattr(item,attr)
......@@ -300,14 +320,14 @@ class HTTPRequest(BaseRequest):
raise
#Determine which dictionary to use
if setting_a_default:
if flags&DEFAULT:
mapping_object = defaults
else:
mapping_object = form
#Insert in dictionary
if mapping_object.has_key(key):
if records_flag:
if flags&records:
#Get the list and the last record
#in the list
reclist = mapping_object[key]
......@@ -323,7 +343,7 @@ class HTTPRequest(BaseRequest):
reclist.append(x)
mapping_object[key] = reclist
else:
if seqf:
if flags&SEQUENCE:
# If the attribute is a
# sequence, append the item
# to the existing attribute
......@@ -340,9 +360,9 @@ class HTTPRequest(BaseRequest):
setattr(n,attr,item)
reclist.append(n)
mapping_object[key]=reclist
elif record_flag:
elif flags&RECORD:
b=mapping_object[key]
if seqf:
if flags&SEQUENCE:
item=[item]
if not hasattr(b,attr):
# if it does not have the
......@@ -366,14 +386,14 @@ class HTTPRequest(BaseRequest):
mapping_object[key]=found
else:
# The dictionary does not have the key
if records_flag:
if flags&RECORDS:
# Create a new record, set its attribute
# and put it in the dictionary as a list
a = record()
if seqf: item=[item]
setattr(a,attr,item)
mapping_object[key]=[a]
elif record_flag:
elif flags&RECORD:
# Create a new record, set its attribute
# and put it in the dictionary
if seqf: item=[item]
......@@ -384,16 +404,31 @@ class HTTPRequest(BaseRequest):
if seqf: item=[item]
mapping_object[key]=item
else:
# This branch is for case when no type was specified.
mapping_object = form
#Insert in dictionary
if mapping_object.has_key(key):
# it is not a record or list of records
found=mapping_object[key]
if type(found) is lt:
found.append(item)
else:
found=[found,item]
mapping_object[key]=found
else:
mapping_object[key]=item
#insert defaults into form dictionary
if defaults:
for keys, values in defaults.items():
if not form.has_key(keys) and not form == {}:
if not form.has_key(keys):
# if the form does not have the key and the
# form is not empty, set the default
form[keys]=values
else:
# the form has the key
if not form == {}:
if hasattr(values, '__class__') and values.__class__ is record:
if getattr(values, '__class__',0) is record:
# if the key is mapped to a record, get the
# record
r = form[keys]
......@@ -410,15 +445,15 @@ class HTTPRequest(BaseRequest):
l = form[keys]
for x in values:
# for each x in the list
if hasattr(x, '__class__') and x.__class__ is record:
if getattr(x, '__class__',0) is record:
# if the x is a record
for k, v in x.__dict__.items():
# loop through each attribute and value in the
# record
# loop through each attribute and value in
# the record
for y in l:
# loop through each record in the form list
# if it doesn't have the attributes in the
# default dictionary, set them
# loop through each record in the form
# list if it doesn't have the attributes
# in the default dictionary, set them
if not hasattr(y, k):
setattr(y, k, v)
else:
......@@ -428,6 +463,7 @@ class HTTPRequest(BaseRequest):
form[keys] = l
# Convert to tuples
if tuple_items:
for key in tuple_items.keys():
# Split the key and get the attr
k=split(key, ".")
......@@ -441,7 +477,8 @@ class HTTPRequest(BaseRequest):
if form.has_key(k):
# If the form has the split key get its value
item =form[k]
if hasattr(item, '__class__') and item.__class__ is record:
if (hasattr(item, '__class__') and
item.__class__ is record):
# if the value is mapped to a record, check if it
# has the attribute, if it has it, convert it to
# a tuple and set it
......@@ -466,7 +503,6 @@ class HTTPRequest(BaseRequest):
item=tuple(form[key])
form[key]=item
other=self.other={}
other.update(form)
if meth:
if environ.has_key('PATH_INFO'):
......@@ -855,3 +891,13 @@ class record:
return join(map(lambda item: "%s: %s" %item, L1), ", ")
__repr__ = __str__
# Flags
SEQUENCE=1
DEFAULT=2
RECORD=4
RECORDS=8
REC=RECORD|RECORDS
EMPTY=16
CONVERTED=32
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