Mercurial > traipse_dev
diff plugins/cherrypy/wsgiapp.py @ 0:4385a7d0efd1 grumpy-goblin
Deleted and repushed it with the 'grumpy-goblin' branch. I forgot a y
author | sirebral |
---|---|
date | Tue, 14 Jul 2009 16:41:58 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/cherrypy/wsgiapp.py Tue Jul 14 16:41:58 2009 -0500 @@ -0,0 +1,173 @@ +""" +Copyright (c) 2004, CherryPy Team (team@cherrypy.org) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the CherryPy Team nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" + +""" +WSGI interface for CherryPy +""" + +import StringIO, Cookie, time +from cherrypy import cpg, _cphttptools, _cpserver + +def init(*a, **kw): + kw['initOnly'] = 1 + _cpserver.start(*a, **kw) + +def wsgiApp(environ, start_response): + cpg.request.method = environ['REQUEST_METHOD'] + # Rebuild first line of the request + pathInfo = environ['PATH_INFO'] + qString = environ.get('QUERY_STRING') + if qString: + pathInfo += '?' + qString + firstLine = '%s %s %s' % ( + environ['REQUEST_METHOD'], + pathInfo or '/', + environ['SERVER_PROTOCOL'] + ) + _cphttptools.parseFirstLine(firstLine) + + # Initialize variables + now = time.time() + year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now) + date = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (_cphttptools.weekdayname[wd], day, _cphttptools.monthname[month], year, hh, mm, ss) + cpg.request.headerMap = {} + cpg.request.simpleCookie = Cookie.SimpleCookie() + cpg.response.simpleCookie = Cookie.SimpleCookie() + + # Rebuild headerMap + for cgiName, headerName in [ + ('HTTP_HOST', 'Host'), + ('HTTP_USER_AGENT', 'User-Agent'), + ('HTTP_CGI_AUTHORIZATION', 'Authorization'), + ('CONTENT_LENGTH', 'Content-Length'), + ('CONTENT_TYPE', 'Content-Type'), + ('HTTP_COOKIE', 'Cookie'), + ('REMOTE_HOST', 'Remote-Host'), + ('REMOTE_ADDR', 'Remote-Addr'), + ('HTTP_REFERER', 'Referer'), + ('HTTP_ACCEPT_ENCODING', 'Accept-Encoding'), + ]: + if cgiName in environ: + _cphttptools.insertIntoHeaderMap(headerName, environ[cgiName]) + + # TODO: handle POST + + # set up stuff similar to initRequest + cpg.response.headerMap = { + "protocolVersion": cpg.configOption.protocolVersion, + "Status": "200 OK", + "Content-Type": "text/html", + "Server": "CherryPy/" + cpg.__version__, + "Date": date, + "Set-Cookie": [], + "Content-Length": 0 + } + cpg.request.base = "http://" + cpg.request.headerMap['Host'] + cpg.request.browserUrl = cpg.request.base + cpg.request.browserUrl + cpg.request.isStatic = False + cpg.request.parsePostData = True + cpg.request.rfile = environ["wsgi.input"] + cpg.request.objectPath = None + if 'Cookie' in cpg.request.headerMap: + cpg.request.simpleCookie.load(cpg.request.headerMap['Cookie']) + + cpg.response.simpleCookie = Cookie.SimpleCookie() + cpg.response.sendResponse = 1 + + if cpg.request.method == 'POST' and cpg.request.parsePostData: + _cphttptools.parsePostData(cpg.request.rfile) + + # Execute request + wfile = StringIO.StringIO() + cpg.response.wfile = wfile + _cphttptools.handleRequest(wfile) + response = wfile.getvalue() + + + # Extract header from response + headerLines = [] + i = 0 + while 1: + j = response.find('\n', i) + line = response[i:j] + if line[-1] == '\r': + line = line[:-1] + headerLines.append(line) + i = j+1 + if not line: + break + response = response[i:] + + status = headerLines[0] + # Remove "HTTP/1.0" at the beginning of status + i = status.find(' ') + status = status[i+1:] + + responseHeaders = [] + for line in headerLines[1:]: + i = line.find(':') + header = line[:i] + value = line[i+1:].lstrip() + responseHeaders.append((header,value)) + + start_response(status, responseHeaders) + + return response + +if __name__ == '__main__': + from cherrypy import cpg, wsgiapp + class Root: + def index(self, name = "world"): + count = cpg.request.sessionMap.get('count', 0) + 1 + cpg.request.sessionMap['count'] = count + return """ + <html><body> + Hello, %s, count is %s: + <form action="/post" method="post"> + Post some data: <input name=myData type=text"> <input type=submit> + </form> + """ % (name, count) + index.exposed = True + def post(self, myData): + return "myData: " + myData + post.exposed = True + cpg.root = Root() + + import sys + # This uses the WSGI HTTP server from PEAK.wsgiref + # sys.path.append(r"C:\Tmp\PEAK\src") + from wsgiref.simple_server import WSGIServer, WSGIRequestHandler + # Read the CherryPy config file and initialize some variables + wsgiapp.init(configMap = {'socketPort': 8000, 'sessionStorageType': 'ram'}) + server_address = ("", 8000) + httpd = WSGIServer(server_address, WSGIRequestHandler) + httpd.set_app(wsgiapp.wsgiApp) + sa = httpd.socket.getsockname() + #print "Serving HTTP on", sa[0], "port", sa[1], "..." + httpd.serve_forever() +