Anonymous avatar Anonymous committed ac6f651

- fix for parse_qs #141
- added autoreload for the "dev" server env

Comments (0)

Files changed (3)

 """
 
 import cpg, sys, threading, SocketServer, _cphttptools
-import BaseHTTPServer, socket, Queue, _cputil
+import BaseHTTPServer, socket, Queue, _cputil
+from lib import autoreload
 
 def stop():
     cpg._server.shutdown()
+
+def start():
+    if cpg.config.get("server.env") == "dev":
+        autoreload.main(_start)
+    else:
+        _start()
 
-def start():
+def _start():
     """ Prepare the HTTP server and then run it """
 
     # If sessions are stored in files and we
     cpg.request.paramList = [] # Only used for Xml-Rpc
     cpg.request.filenameMap = {}
     cpg.request.fileTypeMap = {}
-    i = cpg.request.path.find('?')
-    if i != -1:
-        # Parse parameters from URL
-        if cpg.request.path[i+1:]:
-            k = cpg.request.path[i+1:].find('?')
-            if k != -1:
-                j = cpg.request.path[:k].rfind('=')
-                if j != -1:
-                    cpg.request.path = cpg.request.path[:j+1] + \
-                        urllib.quote_plus(cpg.request.path[j+1:])
-            for paramStr in cpg.request.path[i+1:].split('&'):
-                sp = paramStr.split('=')
-                if len(sp) > 2:
-                    j = paramStr.find('=')
-                    sp = (paramStr[:j], paramStr[j+1:])
-                if len(sp) == 2:
-                    key, value = sp
-                    value = urllib.unquote_plus(value)
-                    if cpg.request.paramMap.has_key(key):
-                        # Already has a value: make a list out of it
-                        if type(cpg.request.paramMap[key]) == type([]):
-                            # Already is a list: append the new value to it
-                            cpg.request.paramMap[key].append(value)
-                        else:
-                            # Only had one value so far: start a list
-                            cpg.request.paramMap[key] = [cpg.request.paramMap[key], value]
-                    else:
-                        cpg.request.paramMap[key] = value
-        cpg.request.queryString = cpg.request.path[i+1:]
-        cpg.request.path = cpg.request.path[:i]
+    # From http://www.cherrypy.org/ticket/141/
+    # find the queryString, or set it to "" if not found
+    if "?" in cpg.request.path:
+        cpg.request.path, cpg.request.queryString = cpg.request.path.split("?",1)
+    else:
+        cpg.request.path, cpg.request.queryString = cpg.request.path, ""
+    
+    # build a paramMap dictionary from queryString
+    pm = cpg.request.paramMap = cgi.parse_qs(cpg.request.queryString, True)
+    for key, val in pm.items():
+        if len(val) == 1:
+            pm[key] = val[0]
 
 def cookHeaders(clientAddress, remoteHost, headers, requestLine):
     """Process the headers into the request.headerMap"""

lib/autoreload.py

+# autoreloading launcher
+# stolen a lot from Ian Bicking's WSGIKit (www.wsgikit.org)
+
+import os
+import sys
+import time
+import thread
+from cherrypy import _cputil
+
+RUN_RELOADER = True
+reloadFiles = []
+    
+def reloader_thread():
+    mtimes = {}
+    while RUN_RELOADER:
+        for filename in filter(lambda v: v, map(lambda m: getattr(m, "__file__", None), sys.modules.values())) + reloadFiles:
+            if filename.endswith(".pyc"):
+                filename = filename[:-1]
+            mtime = os.stat(filename).st_mtime
+            if filename not in mtimes:
+                mtimes[filename] = mtime
+                continue
+            if mtime > mtimes[filename]:
+                sys.exit(3) # force reload
+        time.sleep(1)
+
+def restart_with_reloader():
+    while True:
+        args = [sys.executable] + sys.argv
+        if sys.platform == "win32": args = ['"%s"' % arg for arg in args]
+        new_environ = os.environ.copy()
+        new_environ["RUN_MAIN"] = 'true'
+        exit_code = os.spawnve(os.P_WAIT, sys.executable,
+                               args, new_environ)
+        if exit_code != 3:
+            return exit_code
+        
+def main(main_func):
+    if os.environ.get("RUN_MAIN") == "true":
+        
+        thread.start_new_thread(main_func, ())
+
+        try:
+            reloader_thread()
+        except KeyboardInterrupt:
+            pass
+    else:
+        try:
+            sys.exit(restart_with_reloader())
+        except KeyboardInterrupt:
+            _cputil.getSpecialFunction('_cpLogMessage')("<Ctrl-C> hit: shutting down", "HTTP")
+            
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.