Mercurial > traipse_dev
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 |