Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

root/tags/cherrypy-2.0.0/cherrypy/wsgiapp.py

Revision 144 (checked in by rdelon, 3 years ago)

Handle empty pathInfo in wsgiApp

Line 
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
Note: See TracBrowser for help on using the browser.

Hosted by WebFaction

Log in as guest/cpguest to create tickets