Commits

Anonymous committed 3ee7214

Re-organized server code to comply to CherryPyAPI in trunk

Comments (0)

Files changed (3)

 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.
 """
 
-import cpg, sys, threading, SocketServer, _cphttptools, BaseHTTPServer, socket, Cookie, Queue, _cputil
+import cpg, sys, threading, SocketServer, _cphttptools, BaseHTTPServer, socket, Queue, _cputil
 
 def start():
     """ Prepare the HTTP server and then run it """
         if _reverseDNS: return BaseHTTPServer.BaseHTTPRequestHandler.address_string(self)
         else: return self.client_address[0]
 
-    def cook_headers(self):
-        """Process the headers in self.headers into the request.headerMap"""
-        cpg.request.headerMap = {}
-        cpg.request.simpleCookie = Cookie.SimpleCookie()
-        cpg.response.simpleCookie = Cookie.SimpleCookie()
-
-        # Build headerMap
-        for item in self.headers.items():
-            # Warning: if there is more than one header entry for cookies (AFAIK, only Konqueror does that)
-            # only the last one will remain in headerMap (but they will be correctly stored in request.simpleCookie)
-            _cphttptools.insertIntoHeaderMap(item[0],item[1])
-
-        # Handle cookies differently because on Konqueror, multiple cookies come on different lines with the same key
-        cookieList = self.headers.getallmatchingheaders('cookie')
-        for cookie in cookieList:
-            cpg.request.simpleCookie.load(cookie)
-
-        if not cpg.request.headerMap.has_key('Remote-Addr'):
-            try:
-                cpg.request.headerMap['Remote-Addr'] = self.client_address[0]
-                cpg.request.headerMap['Remote-Host'] = self.address_string()
-            except: pass
-
-        # Set peer_certificate (in SSL mode) so the web app can examinate the client certificate
-        try: cpg.request.peerCertificate = self.request.get_peer_certificate()
-        except: pass
-
-        _cputil.getSpecialFunction('_cpLogMessage')("%s - %s" % (cpg.request.headerMap.get('Remote-Addr', ''), self.raw_requestline[:-2]), "HTTP")
-
     def do_GET(self):
         """Serve a GET request."""
         cpg.request.method = 'GET'
-        _cphttptools.parseFirstLine(self.raw_requestline)
-        self.cook_headers()
-        # TODO _cphttptools.applyFilterList('afterRequestHeader')
-        # TODO _cphttptools.applyFilterList('afterRequestBody')
-        _cphttptools.doRequest(self.wfile)
+        _cphttptools.doRequest(self.raw_requestline, self.headers, self.rfile, self.wfile)
 
     def do_HEAD(self): # Head is not implemented
         """Serve a HEAD request."""
         cpg.request.method = 'HEAD'
-        _cphttptools.parseFirstLine(self.raw_requestline)
-        self.cook_headers()
-        _cphttptools.doRequest(self.wfile)
+        _cphttptools.doRequest(self.raw_requestline, self.headers, self.rfile, self.wfile)
 
     def do_POST(self):
         """Serve a POST request."""
         cpg.request.method = 'POST'
-        _cphttptools.parseFirstLine(self.raw_requestline)
-        self.cook_headers()
-        cpg.request.parsePostData = 1
-        cpg.request.rfile = self.rfile
-        # TODO _cphttptools.applyFilterList('afterRequestHeader')
-        if cpg.request.parsePostData:
-            _cphttptools.parsePostData(self.rfile)
-        # TODO _cphttptools.applyFilterList('afterRequestBody')
-        _cphttptools.doRequest(self.wfile)
+        _cphttptools.doRequest(self.raw_requestline, self.headers, self.rfile, self.wfile)
 
     def setup(self):
         """ We have to override this to handle SSL
 """
 
 import cpg, urllib, sys, time, traceback, types, StringIO, cgi, os
-import mimetypes, sha, random, string, _cputil, cperror
+import mimetypes, sha, random, string, _cputil, cperror, Cookie
 
 """
 Common Service Code for CherryPy
         cpg.request.queryString = cpg.request.path[i+1:]
         cpg.request.path = cpg.request.path[:i]
 
+def cookHeaders(headers, requestLine):
+    """Process the headers into the request.headerMap"""
+    cpg.request.headerMap = {}
+    cpg.request.simpleCookie = Cookie.SimpleCookie()
+
+    # Build headerMap
+    for item in headers.items():
+        # Warning: if there is more than one header entry for cookies (AFAIK, only Konqueror does that)
+        # only the last one will remain in headerMap (but they will be correctly stored in request.simpleCookie)
+        insertIntoHeaderMap(item[0],item[1])
+
+    # Handle cookies differently because on Konqueror, multiple cookies come on different lines with the same key
+    cookieList = headers.getallmatchingheaders('cookie')
+    for cookie in cookieList:
+        cpg.request.simpleCookie.load(cookie)
+
+    if not cpg.request.headerMap.has_key('Remote-Addr'):
+        try:
+            cpg.request.headerMap['Remote-Addr'] = self.client_address[0]
+            cpg.request.headerMap['Remote-Host'] = self.address_string()
+        except: pass
+
+    # Set peer_certificate (in SSL mode) so the web app can examinate the client certificate
+    try: cpg.request.peerCertificate = self.request.get_peer_certificate()
+    except: pass
+
+    _cputil.getSpecialFunction('_cpLogMessage')("%s - %s" % (cpg.request.headerMap.get('Remote-Addr', ''), requestLine[:-2]), "HTTP")
+
+
 def parsePostData(rfile):
     # Read request body and put it in data
     len = int(cpg.request.headerMap.get("Content-Length","0"))
     normalizedKey = '-'.join([s.capitalize() for s in key.split('-')])
     cpg.request.headerMap[normalizedKey] = value
 
-def doRequest(wfile):
+def initRequest(requestLine, headers, rfile, wfile):
+    parseFirstLine(requestLine)
+    cookHeaders(headers, requestLine)
+
+    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 = rfile
+
+    applyFilterList('afterRequestHeader')
+
+    if cpg.request.method == 'POST' and cpg.request.parsePostData:
+        parsePostData(rfile)
+
+    applyFilterList('afterRequestBody')
+
+def doRequest(requestLine, headers, rfile, wfile):
+    initRequest(requestLine, headers, rfile, wfile)
+
+    # Prepare response 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" % (weekdayname[wd], day, monthname[month], year, hh, mm, ss)
+    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.response.simpleCookie = Cookie.SimpleCookie()
+    cpg.response.wfile = wfile
+    cpg.response.sendResponse = 1
+
     try:
         handleRequest(wfile)
     except:
     wfile.write(cpg.response.body)
 
 def handleRequest(wfile):
+    # Clean up expired sessions if needed:
     now = time.time()
-    year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now)
-    date = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (weekdayname[wd], day, monthname[month], year, hh, mm, ss)
-    cpg.response.headerMap={"Status": "200 OK", "protocolVersion": cpg.configOption.protocolVersion, "Content-Type": "text/html", "Server": "CherryPy/" + cpg.__version__, "Date": date, "Set-Cookie": [], "Content-Length": 0}
-
-    # Two variables used for streaming
-    cpg.response.wfile = wfile
-    cpg.response.sendResponse = 1
-
-    if cpg.configOption.sslKeyFile:
-        cpg.request.base = "https://" + cpg.request.headerMap['Host']
-    else:
-        cpg.request.base = "http://" + cpg.request.headerMap['Host']
-    cpg.request.browserUrl = cpg.request.base + cpg.request.browserUrl
-    cpg.request.isStatic = 0
-
-    # TODO: Temp hack ... These filters shouldn't be here and remi
-    # needs to rewrite this code ...
-    applyFilterList('afterRequestHeader')
-    applyFilterList('afterRequestBody')
-
-    # Clean up expired sessions if needed:
     if cpg.configOption.sessionStorageType and cpg.configOption.sessionCleanUpDelay and cpg._lastSessionCleanUpTime + cpg.configOption.sessionCleanUpDelay * 60 <= now:
         cpg._lastSessionCleanUpTime = now
         _cputil.getSpecialFunction('_cpCleanUpOldSessions')()
         wfile.write('\r\n')
         return
          
-    cpg.request.objectPath = '/'.join(objectPathList)
+    cpg.request.objectPath = '/' + '/'.join(objectPathList)
     cpg.response.body = func(*(virtualPathList + cpg.request.paramList), **(cpg.request.paramMap))
 
     if cpg.response.sendResponse:

test/testObjectMapping.py

     def index(self):
         return "index for dir1"
     index.exposed = True
+    def myMethod(self):
+        return "myMethod from dir1, object Path is:" + repr(cpg.request.objectPath)
+    myMethod.exposed = True
     def default(self, *params):
         return "default for dir1, param is:" + repr(params)
     default.exposed = True
 
 testList = [
     ("/", "cpg.response.body == 'world'"),
+    ("/dir1/myMethod", '''cpg.response.body == "myMethod from dir1, object Path is:'/root/dir1/myMethod'"'''),
     ("/this/method/does/not/exist", '''cpg.response.body == "default:('this', 'method', 'does', 'not', 'exist')"'''),
     ("/other", "cpg.response.body == 'other'"),
     ("/notExposed", '''cpg.response.body == "default:('notExposed',)"'''),
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.