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