Commit 6ecda668 authored by Jim Fulton's avatar Jim Fulton

Added support for file upload via newcgi module.

parent 50c195d3
......@@ -49,13 +49,14 @@ class ModulePublisher:
return response
def validate(self,object,module,response):
if type(object) is types.ModuleType: self.forbiddenError()
if hasattr(object,'__allow_groups__'):
groups=object.__allow_groups__
try: realm=module.__realm__
except: self.forbiddenError()
try:
user=realm.user(self.env("HTTP_AUTHORIZATION"))
if type(groups) is type({}):
if type(groups) is types.DictType:
groups=map(lambda k,d=groups: d[k], groups.keys())
for g in groups:
if g.has_key(user): return None
......@@ -114,7 +115,7 @@ class ModulePublisher:
else:
self.notFoundError()
function=f
if not (p=='__doc__' or function.__doc__):
if not (p=='__doc__' or function.__doc__) or p[0]=='_':
raise 'Forbidden',function
self.validate(function,theModule,response)
......@@ -135,45 +136,79 @@ class ModulePublisher:
else:
return response.setBody(function)
query=self.get_data()
query=self.request
query['RESPONSE']=response
last_name=len(names) - (len(defaults or []))
for name in names[:last_name]:
if not query.has_key(name):
self.badRequestError(name)
args={}
for name in names:
if query.has_key(name):
q=query[name]
if type(q) is type([]) and len(q) == 1: q=q[0]
args[name]=q
args=[]
nrequired=len(names) - (len(defaults or []))
for name_index in range(len(names)):
name=names[name_index]
try:
v=query[name]
args.append(v)
except:
if name_index < nrequired:
self.badRequestError(name)
if args: result=apply(function,(),args)
if args: result=apply(function,tuple(args))
else: result=function()
if result and result is not response: response.setBody(result)
return response
def str_field(v):
if type(v) is types.InstanceType and v.__class__ is newcgi.MiniFieldStorage:
v=v.value
return v
class Request:
class CGIModulePublisher(ModulePublisher):
def __init__(self,
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
environ=os.environ):
def __init__(self,environ,form):
self.environ=environ
self.stdin=stdin
self.stdout=stdout
self.stderr=stderr
b=string.strip(self.environ['SCRIPT_NAME'])
if b[-1]=='/': b=b[:-1]
p = string.rfind(b,'/')
if p >= 0: self.base=b[:p+1]
else: self.base=''
self.form=form
self.other={}
def __setitem__(self,key,value): self.other[key]=value
def __getitem__(self,key):
try:
v= self.environ[key]
if self.special_names.has_key(key) or key[:5] == 'HTTP_':
return v
except: pass
try: return self.other[key]
except: pass
if key=='REQUEST': return self
try:
v=self.form[key]
if type(v) is types.ListType:
v=map(str_field, v)
if len(v) == 1: v=v[0]
else: v=str_field(v)
return v
except: pass
if not self.__dict__.has_key('cookies'):
cookies=self.cookies={}
if self.environ.has_key('HTTP_COOKIE'):
for cookie in string.split(self.environ['HTTP_COOKIE'],';'):
try:
[k,v]=map(string.strip,string.split(cookie,'='))
cookies[k]=v
except: pass
if key=='cookies': return self.cookies
try: return self.cookies[key]
except: raise AttributeError, key
__getattr__=__getitem__
special_names = {
'SERVER_SOFTWARE' : 1,
......@@ -194,22 +229,29 @@ class CGIModulePublisher(ModulePublisher):
'CONTENT_TYPE' : 1,
'CONTENT_LENGTH' : 1,
}
def get_data(self):
query=newcgi.parse(fp=self.stdin, environ=self.environ) or {}
environ=self.environ
for key in environ.keys():
if self.special_names.has_key(key) or key[:5] == 'HTTP_':
query[key]=[environ[key]]
class CGIModulePublisher(ModulePublisher):
for cookie in string.split(self.env('HTTP_COOKIE'),';'):
try:
[key,value]=map(string.strip, string.split(cookie,'='))
if key and not query.has_key(key): query[key]=value
except: pass
def __init__(self,
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
environ=os.environ):
self.environ=environ
fp=None
try:
if environ['REQUEST_METHOD'] != 'GET': fp=stdin
except: pass
form=newcgi.FieldStorage(fp=fp,environ=environ,keep_blank_values=1)
self.request=Request(environ,form)
self.stdin=stdin
self.stdout=stdout
self.stderr=stderr
b=string.strip(self.environ['SCRIPT_NAME'])
if b[-1]=='/': b=b[:-1]
p = string.rfind(b,'/')
if p >= 0: self.base=b[:p+1]
else: self.base=''
return query
def publish_module(module_name, published='web_objects',
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
environ=os.environ):
......
......@@ -3,7 +3,7 @@
__doc__='''CGI Response Output formatter
$Id: Response.py,v 1.2 1996/07/01 11:51:54 jfulton Exp $'''
$Id: Response.py,v 1.3 1996/07/03 18:25:50 jfulton Exp $'''
# Copyright
#
# Copyright 1996 Digital Creations, L.C., 910 Princess Anne
......@@ -55,6 +55,9 @@ $Id: Response.py,v 1.2 1996/07/01 11:51:54 jfulton Exp $'''
# (540) 371-6909
#
# $Log: Response.py,v $
# Revision 1.3 1996/07/03 18:25:50 jfulton
# Added support for file upload via newcgi module.
#
# Revision 1.2 1996/07/01 11:51:54 jfulton
# Updated code to:
#
......@@ -69,10 +72,28 @@ $Id: Response.py,v 1.2 1996/07/01 11:51:54 jfulton Exp $'''
#
#
#
__version__='$Revision: 1.2 $'[11:-2]
__version__='$Revision: 1.3 $'[11:-2]
import string, types, sys, regex
status_reasons={
200: 'OK',
201: 'Created',
202: 'Accepted',
204: 'No Content',
301: 'Moved Permanently',
302: 'Moved Temporarily',
304: 'Not Modified',
400: 'Bad Request',
401: 'Unauthorized',
403: 'Forbidden',
404: 'Not Found',
500: 'Internal Error',
501: 'Not Implemented',
502: 'Bad Gateway',
503: 'Service Unavailable',
}
status_codes={
'ok': 200,
'created':201,
......@@ -146,7 +167,7 @@ class Response:
self.stdout=stdout
self.stderr=stderr
def setStatus(self,status):
def setStatus(self, status, reason=None):
'''\
Sets the HTTP status code of the response; the argument may
either be an integer or a string from { OK, Created, Accepted,
......@@ -160,7 +181,10 @@ class Response:
try: status=status_codes[status]
except: status=500
self.status=status
self.setHeader('status',status)
if reason is None:
try: reason=status_reasons[status]
except: reason='Unknown'
self.setHeader('Status', "%d %s" % (status,str(reason)))
def setHeader(self, name, value):
'''\
......@@ -323,10 +347,13 @@ class Response:
if not headers.has_key('content-length'):
self.setHeader('content-length',len(body))
if not headers.has_key('content-type') and self.status == 200:
self.setStatus('nocontent')
headersl=map(lambda k,d=headers: "%s: %s" % (k,d[k]), headers.keys())
if self.cookies:
headersl=headersl+self._cookie_list()
if body: headersl[len(headersl):]=['',body]
headersl[len(headersl):]=['',body]
return string.joinfields(headersl,'\n')
......@@ -335,6 +362,8 @@ class Response:
if end_of_header_re.search(self.body) >= 0:
try: del self.headers['content-length']
except: pass
if not self.headers.has_key('content-type'):
self.setHeader('content-type', 'text/html')
self.insertBase()
body=self.body
self.body=''
......
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