################################################## # SPYCE - Python-based HTML Scripting # Copyright (c) 2002 Rimon Barr. # # Refer to spyce.py # CVS: ################################################## # spyceLRWP.py by Jim Madsen # Adapted from the work of Rimon Barr & Robin Dunn # Some further modifications by: # Rimon Barr ################################################## ''' 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('Page Error') req.out.write('\n') req.out.write('') req.out.write('

404 Error

') req.out.write('

') req.out.write('

Page Not Available On This Server

') req.out.write('\n\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()