Commit 865cc5ce authored by cathi's avatar cathi

Improved string output for Request. Added new form types in HTTPRequest.py.

parent 7da93bf1
...@@ -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.8 $'[11:-2] __version__='$Revision: 1.9 $'[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
...@@ -181,8 +181,9 @@ class BaseRequest: ...@@ -181,8 +181,9 @@ class BaseRequest:
return result return result
def __str__(self): def __str__(self):
L1 = self.items()
return join(map(lambda item: "%s:\t%s" % item, self.items()), "\n") L1.sort()
return join(map(lambda item: "%s:\t%s" % item, L1), "\n")
__repr__=__str__ __repr__=__str__
......
...@@ -82,9 +82,10 @@ ...@@ -82,9 +82,10 @@
# attributions are listed in the accompanying credits file. # attributions are listed in the accompanying credits file.
# #
############################################################################## ##############################################################################
__version__='$Revision: 1.8 $'[11:-2]
import regex, sys, os __version__='$Revision: 1.9 $'[11:-2]
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
from BaseRequest import BaseRequest from BaseRequest import BaseRequest
from HTTPResponse import HTTPResponse from HTTPResponse import HTTPResponse
...@@ -188,7 +189,16 @@ class HTTPRequest(BaseRequest): ...@@ -188,7 +189,16 @@ class HTTPRequest(BaseRequest):
del environ['HTTP_AUTHORIZATION'] del environ['HTTP_AUTHORIZATION']
form={} form={}
form_has=form.has_key defaults={}
# add class
class record:
def __str__(self):
L1 = self.__dict__.items()
L1.sort()
return join(map(lambda item: "%s: %s" %item, L1), ", ")
__repr__ = __str__
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:
...@@ -206,14 +216,12 @@ class HTTPRequest(BaseRequest): ...@@ -206,14 +216,12 @@ class HTTPRequest(BaseRequest):
else: else:
fslist=fs.list fslist=fs.list
tuple_items={} tuple_items={}
type_re=regex.compile(':[a-zA-Z][a-zA-Z0-9_]+') type_re=regex.compile(':[a-zA-Z][a-zA-Z0-9_]+')
type_search=type_re.search type_search=type_re.search
lt=type([]) lt=type([])
CGI_name=isCGI_NAME CGI_name=isCGI_NAME
for item in fslist: for item in fslist:
key=unquote(item.name) key=unquote(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,42 +232,245 @@ class HTTPRequest(BaseRequest): ...@@ -224,42 +232,245 @@ class HTTPRequest(BaseRequest):
else: else:
item=item.value item=item.value
# tuple, list flag
seqf=None 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
# the appropriate flags
l=type_search(key) l=type_search(key)
while l >= 0: while l >= 0:
type_name=type_re.group(0)[1:] type_name=type_re.group(0)[1:]
key=key[:l]+key[l+len(type_name)+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': if type_name == 'list':
seqf=list seqf=list
elif type_name == 'tuple': if type_name == 'tuple':
seqf=tuple seqf=tuple
tuple_items[key]=1 tuple_items[key]=1
elif type_name == 'method': if type_name == 'method':
if l: meth=key if l: meth=key
else: meth=item else: meth=item
elif type_name == 'default_method': if type_name == 'default_method':
if not meth: if not meth:
if l: meth=key if l: meth=key
else: meth=item else: meth=item
else: if type_name == 'default':
item=type_converters[type_name](item) 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) l=type_search(key)
# skip over empty fields
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 form_has(key): #Split the key and its attribute
found=form[key] if record_flag or records_flag:
if type(found) is lt: found.append(item) 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
#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
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 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)
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)
else: else:
found=[found,item] found=[found,item]
form[key]=found mapping_object[key]=found
else: 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] if seqf: item=[item]
form[key]=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
#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
# Convert to tuples
for key in tuple_items.keys(): 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]) item=tuple(form[key])
form[key]=item form[key]=item
...@@ -297,6 +508,7 @@ class HTTPRequest(BaseRequest): ...@@ -297,6 +508,7 @@ class HTTPRequest(BaseRequest):
if p >= 0: b=b[:p+1] if p >= 0: b=b[:p+1]
else: b='' else: b=''
while b and b[0]=='/': b=b[1:] while b and b[0]=='/': b=b[1:]
if have_env('SERVER_URL'): if have_env('SERVER_URL'):
server_url=strip(environ['SERVER_URL']) server_url=strip(environ['SERVER_URL'])
else: else:
...@@ -318,8 +530,7 @@ class HTTPRequest(BaseRequest): ...@@ -318,8 +530,7 @@ class HTTPRequest(BaseRequest):
if server_url[-1:]=='/': server_url=server_url[:-1] if server_url[-1:]=='/': server_url=server_url[:-1]
if b: self.base="%s/%s" % (server_url,b) self.base="%s/%s" % (server_url,b)
else: self.base=server_url
while script[:1]=='/': script=script[1:] while script[:1]=='/': script=script[1:]
if script: script="%s/%s" % (server_url,script) if script: script="%s/%s" % (server_url,script)
else: script=server_url else: script=server_url
...@@ -414,7 +625,6 @@ class HTTPRequest(BaseRequest): ...@@ -414,7 +625,6 @@ class HTTPRequest(BaseRequest):
l=rfind(URL,'/') l=rfind(URL,'/')
if l >= 0: URL=URL[:l] if l >= 0: URL=URL[:l]
else: raise KeyError, key else: raise KeyError, key
if len(URL) < len(self.base) and n > 1: raise KeyError, key
other[key]=URL other[key]=URL
return URL return URL
...@@ -429,12 +639,14 @@ class HTTPRequest(BaseRequest): ...@@ -429,12 +639,14 @@ class HTTPRequest(BaseRequest):
if key[:1]=='B' and BASEmatch(key) >= 0: if key[:1]=='B' and BASEmatch(key) >= 0:
n=ord(key[4])-ord('0') n=ord(key[4])-ord('0')
if n: if n:
if self.environ.get('SCRIPT_NAME',''): n=n-1 if self.environ.get('SCRIPT_NAME',''): n=n-1
if len(self.steps) < n: if len(self.steps) < n:
raise KeyError, key raise KeyError, key
v=self.script v=self.script
while v[-1:]=='/': v=v[:-1] while v[-1:]=='/': v=v[:-1]
v=join([v]+self.steps[:n],'/') v=join([v]+self.steps[:n-1],'/')
else: else:
v=self.base v=self.base
while v[-1:]=='/': v=v[:-1] while v[-1:]=='/': v=v[:-1]
...@@ -481,36 +693,6 @@ class HTTPRequest(BaseRequest): ...@@ -481,36 +693,6 @@ class HTTPRequest(BaseRequest):
return keys.keys() return keys.keys()
def __str__(self):
result="<h3>form</h3><table>"
row='<tr valign="top" align="left"><th>%s</th><td>%s</td></tr>'
for k,v in self.form.items():
result=result + row % (k,v)
result=result+"</table><h3>cookies</h3><table>"
for k,v in self.cookies.items():
result=result + row % (k,v)
result=result+"</table><h3>other</h3><table>"
for k,v in self.other.items():
if k in ('PARENTS','RESPONSE'): continue
result=result + row % (k,v)
for n in "0123456789":
key = "URL%s"%n
try: result=result + row % (key,self[key])
except KeyError: pass
for n in "0123456789":
key = "BASE%s"%n
try: result=result + row % (key,self[key])
except KeyError: pass
result=result+"</table><h3>environ</h3><table>"
for k,v in self.environ.items():
if not hide_key(k):
result=result + row % (k,v)
return result+"</table>"
__repr__=__str__
def _authUserPW(self): def _authUserPW(self):
global base64 global base64
auth=self._auth auth=self._auth
...@@ -627,3 +809,36 @@ def parse_cookie(text, ...@@ -627,3 +809,36 @@ def parse_cookie(text,
if not already_have(name): result[name]=value if not already_have(name): result[name]=value
return apply(parse_cookie,(text[l:],result)) return apply(parse_cookie,(text[l:],result))
...@@ -562,6 +562,45 @@ def parse_qs(qs, keep_blank_values=0, strict_parsing=0): ...@@ -562,6 +562,45 @@ def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
If true, errors raise a ValueError exception. If true, errors raise a ValueError exception.
""" """
dict = {} dict = {}
for name_value in name_value_pairs:
nv = string.splitfields(name_value, '=')
if len(nv) != 2:
if strict_parsing:
raise ValueError, "bad query field: %s" % `name_value`
continue
name = urllib.unquote(string.replace(nv[0], '+', ' '))
value = urllib.unquote(string.replace(nv[1], '+', ' '))
if len(value) or keep_blank_values:
if dict.has_key (name):
dict[name].append(value)
else:
dict[name] = [value]
return dict
def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
"""Parse a query given as a string argument.
Arguments:
qs: URL-encoded query string to be parsed
keep_blank_values: flag indicating whether blank values in
URL encoded queries should be treated as blank strings.
A true value inicates that blanks should be retained as
blank strings. The default false value indicates that
blank values are to be ignored and treated as if they were
not included.
strict_parsing: flag indicating what to do with parsing errors.
If false (the default), errors are silently ignored.
If true, errors raise a ValueError exception.
Returns a list, as God intended.
"""
name_value_pairs = string.splitfields(qs, '&')
r=[]
for name, value in parse_qsl(qs, keep_blank_values, strict_parsing): for name, value in parse_qsl(qs, keep_blank_values, strict_parsing):
if len(value) or keep_blank_values: if len(value) or keep_blank_values:
if dict.has_key(name): if dict.has_key(name):
...@@ -592,6 +631,7 @@ def parse_qsl(qs, keep_blank_values=0, strict_parsing=0): ...@@ -592,6 +631,7 @@ def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
""" """
name_value_pairs = string.splitfields(qs, '&') name_value_pairs = string.splitfields(qs, '&')
r=[] r=[]
for name_value in name_value_pairs: for name_value in name_value_pairs:
nv = string.splitfields(name_value, '=') nv = string.splitfields(name_value, '=')
if len(nv) != 2: if len(nv) != 2:
...@@ -958,10 +998,17 @@ class FieldStorage: ...@@ -958,10 +998,17 @@ class FieldStorage:
def read_urlencoded(self): def read_urlencoded(self):
"""Internal: read data in query string format.""" """Internal: read data in query string format."""
qs = self.fp.read(self.length) qs = self.fp.read(self.length)
self.list = list = []
append=list.append
for key, value in parse_qsl(qs, self.keep_blank_values, self.strict_parsing):
append(MiniFieldStorage(key, value))
self.list = list = [] self.list = list = []
for key, value in parse_qsl(qs, self.keep_blank_values, for key, value in parse_qsl(qs, self.keep_blank_values,
self.strict_parsing): self.strict_parsing):
list.append(MiniFieldStorage(key, value)) list.append(MiniFieldStorage(key, value))
self.skip_lines() self.skip_lines()
FieldStorageClass = None FieldStorageClass = None
......
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