comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:4385a7d0efd1
1 """
2 Copyright (c) 2004, CherryPy Team (team@cherrypy.org)
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13 * Neither the name of the CherryPy Team nor the names of its contributors
14 may be used to endorse or promote products derived from this software
15 without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 """
28
29 """
30 WSGI interface for CherryPy
31 """
32
33 import StringIO, Cookie, time
34 from cherrypy import cpg, _cphttptools, _cpserver
35
36 def init(*a, **kw):
37 kw['initOnly'] = 1
38 _cpserver.start(*a, **kw)
39
40 def wsgiApp(environ, start_response):
41 cpg.request.method = environ['REQUEST_METHOD']
42 # Rebuild first line of the request
43 pathInfo = environ['PATH_INFO']
44 qString = environ.get('QUERY_STRING')
45 if qString:
46 pathInfo += '?' + qString
47 firstLine = '%s %s %s' % (
48 environ['REQUEST_METHOD'],
49 pathInfo or '/',
50 environ['SERVER_PROTOCOL']
51 )
52 _cphttptools.parseFirstLine(firstLine)
53
54 # Initialize variables
55 now = time.time()
56 year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now)
57 date = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (_cphttptools.weekdayname[wd], day, _cphttptools.monthname[month], year, hh, mm, ss)
58 cpg.request.headerMap = {}
59 cpg.request.simpleCookie = Cookie.SimpleCookie()
60 cpg.response.simpleCookie = Cookie.SimpleCookie()
61
62 # Rebuild headerMap
63 for cgiName, headerName in [
64 ('HTTP_HOST', 'Host'),
65 ('HTTP_USER_AGENT', 'User-Agent'),
66 ('HTTP_CGI_AUTHORIZATION', 'Authorization'),
67 ('CONTENT_LENGTH', 'Content-Length'),
68 ('CONTENT_TYPE', 'Content-Type'),
69 ('HTTP_COOKIE', 'Cookie'),
70 ('REMOTE_HOST', 'Remote-Host'),
71 ('REMOTE_ADDR', 'Remote-Addr'),
72 ('HTTP_REFERER', 'Referer'),
73 ('HTTP_ACCEPT_ENCODING', 'Accept-Encoding'),
74 ]:
75 if cgiName in environ:
76 _cphttptools.insertIntoHeaderMap(headerName, environ[cgiName])
77
78 # TODO: handle POST
79
80 # set up stuff similar to initRequest
81 cpg.response.headerMap = {
82 "protocolVersion": cpg.configOption.protocolVersion,
83 "Status": "200 OK",
84 "Content-Type": "text/html",
85 "Server": "CherryPy/" + cpg.__version__,
86 "Date": date,
87 "Set-Cookie": [],
88 "Content-Length": 0
89 }
90 cpg.request.base = "http://" + cpg.request.headerMap['Host']
91 cpg.request.browserUrl = cpg.request.base + cpg.request.browserUrl
92 cpg.request.isStatic = False
93 cpg.request.parsePostData = True
94 cpg.request.rfile = environ["wsgi.input"]
95 cpg.request.objectPath = None
96 if 'Cookie' in cpg.request.headerMap:
97 cpg.request.simpleCookie.load(cpg.request.headerMap['Cookie'])
98
99 cpg.response.simpleCookie = Cookie.SimpleCookie()
100 cpg.response.sendResponse = 1
101
102 if cpg.request.method == 'POST' and cpg.request.parsePostData:
103 _cphttptools.parsePostData(cpg.request.rfile)
104
105 # Execute request
106 wfile = StringIO.StringIO()
107 cpg.response.wfile = wfile
108 _cphttptools.handleRequest(wfile)
109 response = wfile.getvalue()
110
111
112 # Extract header from response
113 headerLines = []
114 i = 0
115 while 1:
116 j = response.find('\n', i)
117 line = response[i:j]
118 if line[-1] == '\r':
119 line = line[:-1]
120 headerLines.append(line)
121 i = j+1
122 if not line:
123 break
124 response = response[i:]
125
126 status = headerLines[0]
127 # Remove "HTTP/1.0" at the beginning of status
128 i = status.find(' ')
129 status = status[i+1:]
130
131 responseHeaders = []
132 for line in headerLines[1:]:
133 i = line.find(':')
134 header = line[:i]
135 value = line[i+1:].lstrip()
136 responseHeaders.append((header,value))
137
138 start_response(status, responseHeaders)
139
140 return response
141
142 if __name__ == '__main__':
143 from cherrypy import cpg, wsgiapp
144 class Root:
145 def index(self, name = "world"):
146 count = cpg.request.sessionMap.get('count', 0) + 1
147 cpg.request.sessionMap['count'] = count
148 return """
149 <html><body>
150 Hello, %s, count is %s:
151 <form action="/post" method="post">
152 Post some data: <input name=myData type=text"> <input type=submit>
153 </form>
154 """ % (name, count)
155 index.exposed = True
156 def post(self, myData):
157 return "myData: " + myData
158 post.exposed = True
159 cpg.root = Root()
160
161 import sys
162 # This uses the WSGI HTTP server from PEAK.wsgiref
163 # sys.path.append(r"C:\Tmp\PEAK\src")
164 from wsgiref.simple_server import WSGIServer, WSGIRequestHandler
165 # Read the CherryPy config file and initialize some variables
166 wsgiapp.init(configMap = {'socketPort': 8000, 'sessionStorageType': 'ram'})
167 server_address = ("", 8000)
168 httpd = WSGIServer(server_address, WSGIRequestHandler)
169 httpd.set_app(wsgiapp.wsgiApp)
170 sa = httpd.socket.getsockname()
171 #print "Serving HTTP on", sa[0], "port", sa[1], "..."
172 httpd.serve_forever()
173