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,249 +242,267 @@ 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)
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':
seqf=list
if type_name == 'tuple':
seqf=tuple
tuple_items[key]=1
if type_name == 'method':
if l: meth=key
else: meth=item
if 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
# 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=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
flags=flags|SEQUENCE
elif type_name == 'tuple':
seqf=tuple
tuple_items[key]=1
flags=flags|SEQUENCE
elif type_name == 'method':
if l: meth=key
else: meth=item
elif type_name == 'default_method':
if not meth:
if l: meth=key
else: meth=item
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
#Split the key and its attribute
if record_flag or records_flag:
key=split(key,".")
key, attr=join(key[:-1],"."), key[-1]
if flags:
# skip over empty fields
if flags&EMPTY: continue
#Split the key and its attribute
if flags&REC:
key=split(key,".")
key, attr=join(key[:-1],"."), key[-1]
# defer conversion
if converter is not None:
try:
item=converter(item)
except:
if not item and not setting_a_default and defaults.has_key(key):
item = defaults[key]
if record_flag:
item=getattr(item,attr)
if records_flag:
item.reverse()
item = item[0]
item=getattr(item,attr)
else:
raise
# defer conversion
if flags&CONVERTED:
try:
item=converter(item)
except:
if (not item and not (flags&DEFAULT) and
defaults.has_key(key)):
item = defaults[key]
if flags&RECORD:
item=getattr(item,attr)
if flags&RECORDS:
item.reverse()
item = item[0]
item=getattr(item,attr)
else:
raise
#Determine which dictionary to use
if setting_a_default:
mapping_object = defaults
else:
mapping_object = form
#Insert in dictionary
if mapping_object.has_key(key):
if records_flag:
#Get the list and the last record
#in the list
reclist = mapping_object[key]
reclist.reverse()
x=reclist[0]
reclist.reverse()
if not hasattr(x,attr):
#If the attribute does not
#exist, set it
if seqf: item=[item]
reclist.remove(x)
setattr(x,attr,item)
reclist.append(x)
mapping_object[key] = reclist
else:
if seqf:
# If the attribute is a
# sequence, append the item
# to the existing attribute
#Determine which dictionary to use
if flags&DEFAULT:
mapping_object = defaults
else:
mapping_object = form
#Insert in dictionary
if mapping_object.has_key(key):
if flags&records:
#Get the list and the last record
#in the list
reclist = mapping_object[key]
reclist.reverse()
x=reclist[0]
reclist.reverse()
if not hasattr(x,attr):
#If the attribute does not
#exist, set it
if seqf: item=[item]
reclist.remove(x)
y = getattr(x, attr)
y.append(item)
setattr(x, attr, y)
setattr(x,attr,item)
reclist.append(x)
mapping_object[key] = reclist
else:
# Create a new record and add
# it to the list
n=record()
setattr(n,attr,item)
reclist.append(n)
mapping_object[key]=reclist
elif record_flag:
b=mapping_object[key]
if seqf:
item=[item]
if not hasattr(b,attr):
# if it does not have the
# attribute, set it
setattr(b,attr,item)
else:
# it has the attribute so
# append the item to it
setattr(b,attr,getattr(b,attr)+item)
if flags&SEQUENCE:
# If the attribute is a
# sequence, append the item
# to the existing attribute
reclist.remove(x)
y = getattr(x, attr)
y.append(item)
setattr(x, attr, y)
reclist.append(x)
mapping_object[key] = reclist
else:
# Create a new record and add
# it to the list
n=record()
setattr(n,attr,item)
reclist.append(n)
mapping_object[key]=reclist
elif flags&RECORD:
b=mapping_object[key]
if flags&SEQUENCE:
item=[item]
if not hasattr(b,attr):
# if it does not have the
# attribute, set it
setattr(b,attr,item)
else:
# it has the attribute so
# append the item to it
setattr(b,attr,getattr(b,attr)+item)
else:
# it is not a sequence so
# set the attribute
setattr(b,attr,item)
else:
# it is not a sequence so
# set the attribute
setattr(b,attr,item)
else:
# it is not a record or list of records
found=mapping_object[key]
if type(found) is lt:
found.append(item)
# 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:
# The dictionary does not have the key
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 flags&RECORD:
# Create a new record, set its attribute
# and put it in the dictionary
if seqf: item=[item]
r = mapping_object[key]=record()
setattr(r,attr,item)
else:
found=[found,item]
mapping_object[key]=found
# it is not a record or list of records
if seqf: item=[item]
mapping_object[key]=item
else:
# The dictionary does not have the key
if records_flag:
# 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:
# Create a new record, set its attribute
# and put it in the dictionary
if seqf: item=[item]
r = mapping_object[key]=record()
setattr(r,attr,item)
else:
# it is not a record or list of records
if seqf: item=[item]
mapping_object[key]=item
# 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
for keys, values in defaults.items():
if not form.has_key(keys) and not form == {}:
# 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 the key is mapped to a record, get the
# record
r = form[keys]
for k, v in values.__dict__.items():
# loop through the attributes and values
# in the default dictionary
if not hasattr(r, k):
# if the form dictionary doesn't have
# the attribute, set it to the default
setattr(r,k,v)
form[keys] = r
else:
# the key is mapped to a list
l = form[keys]
for x in values:
# for each x in the list
if hasattr(x, '__class__') and x.__class__ is record:
# if the x is a record
for k, v in x.__dict__.items():
# 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
if not hasattr(y, k):
setattr(y, k, v)
else:
# x is not a record
if not a in l:
l.append(a)
form[keys] = l
if defaults:
for keys, values in defaults.items():
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:
if getattr(values, '__class__',0) is record:
# if the key is mapped to a record, get the
# record
r = form[keys]
for k, v in values.__dict__.items():
# loop through the attributes and values
# in the default dictionary
if not hasattr(r, k):
# if the form dictionary doesn't have
# the attribute, set it to the default
setattr(r,k,v)
form[keys] = r
else:
# the key is mapped to a list
l = form[keys]
for x in values:
# for each x in the list
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
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
if not hasattr(y, k):
setattr(y, k, v)
else:
# x is not a record
if not a in l:
l.append(a)
form[keys] = l
# Convert to tuples
for key in tuple_items.keys():
# Split the key and get the attr
k=split(key, ".")
k,attr=join(k[:-1], "."), k[-1]
a = attr
# remove any type_names in the attr
while not a=='':
a=split(a, ":")
a,new=join(a[:-1], ":"), a[-1]
attr = new
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 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
if hasattr(item,attr):
value=tuple(getattr(item,attr))
setattr(item,attr,value)
else:
# It is mapped to a list of records
for x in item:
# loop through the records
if hasattr(x, attr):
# If the record has the attribute
# convert it to a tuple and set it
value=tuple(getattr(x,attr))
setattr(x,attr,value)
else:
# the form does not have the split key
if form.has_key(key):
# if it has the original key, get the item
# convert it to a tuple
item=form[key]
item=tuple(form[key])
form[key]=item
if tuple_items:
for key in tuple_items.keys():
# Split the key and get the attr
k=split(key, ".")
k,attr=join(k[:-1], "."), k[-1]
a = attr
# remove any type_names in the attr
while not a=='':
a=split(a, ":")
a,new=join(a[:-1], ":"), a[-1]
attr = new
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 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
if hasattr(item,attr):
value=tuple(getattr(item,attr))
setattr(item,attr,value)
else:
# It is mapped to a list of records
for x in item:
# loop through the records
if hasattr(x, attr):
# If the record has the attribute
# convert it to a tuple and set it
value=tuple(getattr(x,attr))
setattr(x,attr,value)
else:
# the form does not have the split key
if form.has_key(key):
# if it has the original key, get the item
# convert it to a tuple
item=form[key]
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