##################################################
# SPYCE - Python-based HTML Scripting
# Copyright (c) 2002 Rimon Barr.
#
# Refer to spyce.py
# CVS:
##################################################
# spyceLRWP.py by Jim Madsen <jmadsen@xmission.com>
# Adapted from the work of Rimon Barr & Robin Dunn
# Some further modifications by:
# Rimon Barr <rimon AT acm DOT org>
##################################################
'''
Instructions:
Edit the 'Startup Parameters' section below for your configuration.
Make sure Xitami is already running.
Run spyceLRWP.py - status will display in console window.
(You can rename spyceLRWP.py to the name of your app)
The URL for your app will be: http://server/appname/filename
Example: http://localhost/spyceLRWP/form.spy
Base directory is the default you set for Xitami pages.
To shutdown the connection cleanly, enter Ctrl-C...shutdown will
occur on next request handled. (Send one yourself if necessary)
If you are unfamiliar with LRWP, the Xitami Docs have a good section on it.
Multiple instances of spyceLRWP can be run. Just start spyceLRWP.py multiple
times. Xitami will pool the instances and use them if server load warrants it.
'''
##################################################
# Startup Parameters
LRWPappName = 'spyceLRWP'
LRWPhost = 'localhost'
LRWPport = 5081
##################################################
import os, sys, string
import spyce, spyceUtil
from lrwplib import LRWP
__doc__ = '''Xitami LRWP-based Spyce entry point.'''
##################################################
# Request / Response handlers
class spyceLRWPRequest(spyce.spyceRequest):
def __init__(self, input, env, filename):
spyce.spyceRequest.__init__(self)
self._in = input
self._env = env
if not self._env.has_key('QUERY_STRING'):
self._env['QUERY_STRING']=''
self._headers = {
'Content-Length': self.env('CONTENT_LENGTH'),
'Content-Type': self.env('CONTENT_TYPE'),
'User-Agent': self.env('HTTP_USER_AGENT'),
'Accept': self.env('HTTP_ACCEPT'),
'Accept-Encoding': self.env('HTTP_ACCEPT_ENCODING'),
'Accept-Language': self.env('HTTP_ACCEPT_LANGUAGE'),
'Accept-Charset': self.env('HTTP_ACCEPT_CHARSET'),
'Cookie': self.env('HTTP_COOKIE'),
'Referer': self.env('HTTP_REFERER'),
'Host': self.env('HTTP_HOST'),
'Connection': self.env('HTTP_CONNECTION'),
'Keep-Alive': self.env('HTTP_KEEP_ALIVE'),
}
def env(self, name=None):
return spyceUtil.extractValue(self._env, name)
def getHeader(self, type=None):
return spyceUtil.extractValue(self._headers, type)
def getServerID(self):
return os.getpid()
class spyceLRWPResponse(spyce.spyceResponse):
def __init__(self, out, err):
spyce.spyceResponse.__init__(self)
self.origout = out
self.out = spyceUtil.BufferedOutput(out)
self.err = err
self.headers = []
self.headersSent = 0
self.CT = None
self.returncode = self.RETURN_OK
def write(self, s):
self.out.write(s)
def writeErr(self, s):
self.err.write(s)
def close(self):
self.flush()
self.out.close()
def clear(self):
self.out.clear()
def sendHeaders(self):
if not self.headersSent:
resultText = spyceUtil.extractValue(self.RETURN_CODE, self.returncode)
self.origout.write('Status: %3d "%s"\n' % (self.returncode, resultText))
if not self.CT:
self.setContentType('text/html')
self.origout.write('Content-Type: %s\n' % self.CT)
for h in self.headers:
self.origout.write('%s: %s\n'%h)
self.origout.write('\n')
self.headersSent = 1
def clearHeaders(self):
if self.headersSent:
raise 'headers already sent'
self.headers = []
def setContentType(self, content_type):
if self.headersSent:
raise 'headers already sent'
self.CT = content_type
def setReturnCode(self, code):
if self.headersSent:
raise 'headers already sent'
self.returncode = code
def addHeader(self, type, data, replace=0):
if self.headersSent:
raise 'headers already sent'
if type=='Content-Type':
self.setContentType(data)
else:
if replace:
self.headers = filter(lambda (type, _), t2=type: type!=t2, self.headers)
self.headers.append((type, data))
def flush(self, stopFlag=0):
if stopFlag: return
self.sendHeaders()
self.out.flush()
def unbuffer(self):
self.sendHeaders()
self.out.unbuffer()
def spyceMain(cgiscript, inp, out, err, env):
dir = os.path.dirname(cgiscript)
script = os.path.basename(cgiscript)
os.chdir(dir)
output = out
request = spyceLRWPRequest(inp, env, script)
response = spyceLRWPResponse(output, err)
result = spyce.spyceFileHandler(request, response, script)
response.close()
if output:
output.close()
def doSpyce(inp, out, err, env):
path = env['PATH_TRANSLATED']
if os.path.isfile(path):
print 'Processing - ' + path
result = spyceMain(path, inp, out, err, env)
else:
result = 'pageError'
print 'Invalid Page Requested'
return result
def main():
try:
lrwp = LRWP(LRWPappName, LRWPhost, LRWPport)
lrwp.connect()
print ('\r\n Connected to Xitami -- Listening for ' + LRWPappName + '\r\n')
except:
sys.exit('\r\n Could not make proper connection to Xitami')
while 1:
try:
req = lrwp.acceptRequest()
# Fix environment variables due to the way Xitami reports them under LRWP
req.env['SCRIPT_NAME'] = ('/' + LRWPappName)
req.env['REQUEST_URI'] = ('/' + LRWPappName + req.env['PATH_INFO'])
result = doSpyce(req.inp, spyceUtil.NoCloseOut(req.out), req.out, req.env)
# Error page to keep LRWP from hanging on bad urls
if result == 'pageError':
req.out.write('Content-type: text/html\r\n\r\n')
req.out.write('<HTML><HEAD><TITLE>Page Error</TITLE>')
req.out.write('</HEAD>\n')
req.out.write('<body bgcolor="white">')
req.out.write('<h1>404 Error</h1>')
req.out.write('<p>')
req.out.write('<h2>Page Not Available On This Server</h2>')
req.out.write('\n</BODY></HTML>\n')
req.finish()
# Capture Ctrl-C...shutdown will occur on next request handled
except KeyboardInterrupt:
print '\r\n Closing connection to Xitami \r\n'
lrwp.close()
sys.exit(' Clean Exit')
except:
print 'Unknown Error handling requests'
if __name__=='__main__':
if sys.platform == "win32":
import os, msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
main()
|