Robert Brewer avatar Robert Brewer committed 992e64b

Lots of mixedCase to lower_with_underscores.

Comments (0)

Files changed (14)

             setattr(newfunc, key, getattr(func, key))
     return newfunc
 
-def decorateAll(obj, decorator):
+def decorate_all(obj, decorator):
     """
     Recursively decorate all exposed functions of obj and all of its children,
     grandchildren, etc. If you used to use aspects, you might want to look
         value = getattr(obj, key)
         if callable(value) and getattr(value, "exposed", False):
             setattr(obj, key, decorate(value, decorator))
-        decorateAll(value, decorator)
+        decorate_all(value, decorator)
 
 
 class ExposeItems:
         cherrypy.response.finalize()
         return cherrypy.response
 
+
+def drop_privileges(new_user='nobody', new_group='nogroup'):
+    """Drop privileges. UNIX only."""
+    # Special thanks to Gavin Baker: http://antonym.org/node/100.
+    
+    import pwd, grp
+    
+    def names():
+        return pwd.getpwuid(os.getuid())[0], grp.getgrgid(os.getgid())[0]
+    name, group = names()
+    cherrypy.log('Started as %r/%r' % (name, group), "PRIV")
+    
+    if os.getuid() != 0:
+        # We're not root so, like, whatever dude.
+        cherrypy.log("Already running as %r" % name, "PRIV")
+        return
+    
+    # Try setting the new uid/gid (from new_user/new_group).
+    try:
+        os.setgid(grp.getgrnam(new_group)[2])
+    except OSError, e:
+        cherrypy.log('Could not set effective group id: %r' % e, "PRIV")
+    
+    try:
+        os.setuid(pwd.getpwnam(new_user)[2])
+    except OSError, e:
+        cherrypy.log('Could not set effective user id: %r' % e, "PRIV")
+    
+    # Ensure a very convervative umask
+    old_umask = os.umask(077)
+    cherrypy.log('Old umask: %o, new umask: 077' % old_umask, "PRIV")
+    cherrypy.log('Running as %r/%r' % names(), "PRIV")
+
             # Pop any params included in the path
             path, pm = path.split("?", 1)
             request.query_string = pm
-            request.params = _http.parseQueryString(pm)
+            request.params = _http.parse_query_string(pm)
         
         # Note that urljoin will "do the right thing" whether url is:
         #  1. a URL relative to root (e.g. "/dummy")
     import cherrypy
     
     try:
-        code, reason, message = _http.validStatus(status)
+        code, reason, message = _http.valid_status(status)
     except ValueError, x:
         raise cherrypy.HTTPError(500, x.args[0])
     
         response = request.run(req.method, req.uri, req.args or "",
                                req.protocol, headers, rfile)
         
-        sendResponse(req, response.status, response.header_list, response.body)
+        send_response(req, response.status, response.header_list, response.body)
         request.close()
     except:
         tb = format_exc()
         cherrypy.log(tb)
         s, h, b = bare_error()
-        sendResponse(req, s, h, b)
+        send_response(req, s, h, b)
     return apache.OK
 
-def sendResponse(req, status, headers, body):
+def send_response(req, status, headers, body):
     # Set response status
     req.status = int(status[:3])
     
             self.hooks.run('on_end_resource')
     
     def process_headers(self):
-        self.params = http.parseQueryString(self.query_string)
+        self.params = http.parse_query_string(self.query_string)
         
         # Process the headers into self.headers
         headers = self.headers
             # request body was a content-type other than form params.
             self.body = forms.file
         else:
-            self.params.update(http.paramsFromCGIForm(forms))
+            self.params.update(http.params_from_CGI_form(forms))
     
     def handle_error(self, exc):
         response = cherrypy.response
                     # had a trailing slash (otherwise, do a redirect).
                     if path[-1:] != '/':
                         atoms = request.browser_url.split("?", 1)
-                        newUrl = atoms.pop(0) + '/'
+                        new_url = atoms.pop(0) + '/'
                         if atoms:
-                            newUrl += "?" + atoms[0]
-                        raise cherrypy.HTTPRedirect(newUrl)
+                            new_url += "?" + atoms[0]
+                        raise cherrypy.HTTPRedirect(new_url)
                 return candidate, names[i:-1]
         
         # We didn't find anything
             request.handler = cherrypy.NotFound()
 
 
-def fileGenerator(input, chunkSize=65536):
+def file_generator(input, chunkSize=65536):
     """Yield the given input (a file object) in chunks (default 64k)."""
     chunk = input.read(chunkSize)
     while chunk:
             raise cherrypy.TimeoutError()
         # Convert the given value to an iterable object.
         if isinstance(value, types.FileType):
-            value = fileGenerator(value)
+            value = file_generator(value)
         elif isinstance(value, types.GeneratorType):
             value = flattener(value)
         elif isinstance(value, basestring):
             raise cherrypy.TimeoutError()
         
         try:
-            code, reason, _ = http.validStatus(self.status)
+            code, reason, _ = http.valid_status(self.status)
         except ValueError, x:
             raise cherrypy.HTTPError(500, x.args[0])
         
     """Log engine configuration parameters."""
     cherrypy.log("Server parameters:", 'CONFIG')
     
-    serverVars = [
+    server_vars = [
                   'environment',
                   'log_to_screen',
                   'log_file',
                   'server.thread_pool',
                  ]
     
-    for var in serverVars:
+    for var in server_vars:
         cherrypy.log("  %s: %s" % (var, get(var)), 'CONFIG')
 
 
         mod = __import__(modulePath, globals(), locals(), [''])
     return mod
 
-def attributes(fullAttributeName):
+def attributes(full_attribute_name):
     """Load a module and retrieve an attribute of that module."""
     
     # Parse out the path, module, and attribute
-    lastDot = fullAttributeName.rfind(u".")
-    attrName = fullAttributeName[lastDot + 1:]
-    modPath = fullAttributeName[:lastDot]
+    last_dot = full_attribute_name.rfind(u".")
+    attr_name = full_attribute_name[last_dot + 1:]
+    mod_path = full_attribute_name[:last_dot]
     
-    aMod = modules(modPath)
+    mod = modules(mod_path)
     # Let an AttributeError propagate outward.
     try:
-        attr = getattr(aMod, attrName)
+        attr = getattr(mod, attr_name)
     except AttributeError:
         raise AttributeError("'%s' object has no attribute '%s'"
-                             % (modPath, attrName))
+                             % (mod_path, attr_name))
     
     # Return a reference to the attribute.
     return attr
     
     def __init__(self):
         self.clear()
-        t = threading.Thread(target=self.expireCache, name='expireCache')
-        self.expirationThread = t
+        t = threading.Thread(target=self.expire_cache, name='expire_cache')
+        self.expiration_thread = t
         t.setDaemon(True)
         t.start()
     
         """Reset the cache to its initial, empty state."""
         self.cache = {}
         self.expirations = {}
-        self.totPuts = 0
-        self.totGets = 0
-        self.totHits = 0
-        self.totExpires = 0
-        self.totNonModified = 0
+        self.tot_puts = 0
+        self.tot_gets = 0
+        self.tot_hist = 0
+        self.tot_expires = 0
+        self.tot_non_modified = 0
         self.cursize = 0
     
     def _key(self):
         return cherrypy.request.config.get("tools.caching.key", cherrypy.request.browser_url)
     key = property(_key)
     
-    def expireCache(self):
-        # expireCache runs in a separate thread which the servers are
+    def expire_cache(self):
+        # expire_cache runs in a separate thread which the servers are
         # not aware of. It's possible that "time" will be set to None
         # arbitrarily, so we check "while time" to avoid exceptions.
         # See tickets #99 and #180 for more information.
         while time:
             now = time.time()
-            for expirationTime, objects in self.expirations.items():
-                if expirationTime <= now:
-                    for objSize, objKey in objects:
+            for expiration_time, objects in self.expirations.items():
+                if expiration_time <= now:
+                    for obj_size, obj_key in objects:
                         try:
-                            del self.cache[objKey]
-                            self.totExpires += 1
-                            self.cursize -= objSize
+                            del self.cache[obj_key]
+                            self.tot_expires += 1
+                            self.cursize -= obj_size
                         except KeyError:
                             # the key may have been deleted elsewhere
                             pass
-                    del self.expirations[expirationTime]
+                    del self.expirations[expiration_time]
             time.sleep(0.1)
     
     def get(self):
         """Return the object if in the cache, else None."""
-        self.totGets += 1
-        cacheItem = self.cache.get(self.key, None)
-        if cacheItem:
-            self.totHits += 1
-            return cacheItem
+        self.tot_gets += 1
+        cache_item = self.cache.get(self.key, None)
+        if cache_item:
+            self.tot_hist += 1
+            return cache_item
         else:
             return None
     
         
         if len(self.cache) < conf("tools.caching.maxobjects", 1000):
             # Size check no longer includes header length
-            objSize = len(obj[2])
-            maxobjsize = conf("tools.caching.maxobjsize", 100000)
+            obj_size = len(obj[2])
+            maxobj_size = conf("tools.caching.maxobj_size", 100000)
             
-            totalSize = self.cursize + objSize
+            total_size = self.cursize + obj_size
             maxsize = conf("tools.caching.maxsize", 10000000)
             
             # checks if there's space for the object
-            if (objSize < maxobjsize and totalSize < maxsize):
+            if (obj_size < maxobj_size and total_size < maxsize):
                 # add to the expirations list and cache
-                expirationTime = time.time() + conf("tools.caching.delay", 600)
-                objKey = self.key
-                bucket = self.expirations.setdefault(expirationTime, [])
-                bucket.append((objSize, objKey))
-                self.cache[objKey] = obj
-                self.totPuts += 1
-                self.cursize = totalSize
+                expiration_time = time.time() + conf("tools.caching.delay", 600)
+                obj_key = self.key
+                bucket = self.expirations.setdefault(expiration_time, [])
+                bucket.append((obj_size, obj_key))
+                self.cache[obj_key] = obj
+                self.tot_puts += 1
+                self.cursize = total_size
 
 
 def init(cache_class=None):
     if cherrypy.request.method in invalid:
         cherrypy.request.cached = c = False
     else:
-        cacheData = cherrypy._cache.get()
-        cherrypy.request.cached = c = bool(cacheData)
+        cache_data = cherrypy._cache.get()
+        cherrypy.request.cached = c = bool(cache_data)
     
     if c:
         response = cherrypy.response
-        s, response.headers, b, create_time = cacheData
+        s, response.headers, b, create_time = cache_data
         
         # Add the required Age header
         response.headers["Age"] = str(int(time.time() - create_time))
             cptools.validate_since()
         except cherrypy.HTTPError, x:
             if x.status == 304:
-                cherrypy._cache.totNonModified += 1
+                cherrypy._cache.tot_non_modified += 1
             raise
         
         # serve it & get out from the request
     if etag:
         cherrypy.response.ETag = etag
         
-        status, reason, msg = _http.validStatus(cherrypy.response.status)
+        status, reason, msg = _http.valid_status(cherrypy.response.status)
         
         conditions = cherrypy.request.headers.elements('If-Match') or []
         conditions = [str(x) for x in conditions]
     """Validate the current Last-Modified against If-Modified-Since headers."""
     lastmod = cherrypy.response.headers.get('Last-Modified')
     if lastmod:
-        status, reason, msg = _http.validStatus(cherrypy.response.status)
+        status, reason, msg = _http.valid_status(cherrypy.response.status)
         
         since = cherrypy.request.headers.get('If-Unmodified-Since')
         if since and since != lastmod:
         decode_params("ISO-8859-1")
 
 def decode_params(encoding):
-    decodedParams = {}
+    decoded_params = {}
     for key, value in cherrypy.request.params.items():
         if hasattr(value, 'file'):
             # This is a file being uploaded: skip it
-            decodedParams[key] = value
+            decoded_params[key] = value
         elif isinstance(value, list):
             # value is a list: decode each element
-            decodedParams[key] = [v.decode(encoding) for v in value]
+            decoded_params[key] = [v.decode(encoding) for v in value]
         else:
             # value is a regular string: decode it
-            decodedParams[key] = value.decode(encoding)
+            decoded_params[key] = value.decode(encoding)
     
     # Decode all or nothing, so we can try again on error.
-    cherrypy.request.params = decodedParams
+    cherrypy.request.params = decoded_params
 
 
 # Encoding
 # to a public caning.
 
 from BaseHTTPServer import BaseHTTPRequestHandler
-responseCodes = BaseHTTPRequestHandler.responses.copy()
+response_codes = BaseHTTPRequestHandler.responses.copy()
 
 # From http://www.cherrypy.org/ticket/361
-responseCodes[500] = ('Internal error',
+response_codes[500] = ('Internal error',
                       'The server encountered an unexpected condition '
                       'which prevented it from fulfilling the request.')
-responseCodes[503] = ('Service Unavailable',
+response_codes[503] = ('Service Unavailable',
                       'The server is currently unable to handle the '
                       'request due to a temporary overloading or '
                       'maintenance of the server.')
     """Return a protocol tuple from the given 'HTTP/x.y' string."""
     return int(protocol_str[5]), int(protocol_str[7])
 
-def getRanges(headervalue, content_length):
+def get_ranges(headervalue, content_length):
     """Return a list of (start, stop) indices from a Range header, or None.
     
     Each (start, stop) tuple will be composed of two ints, which are suitable
         decodedvalue += atom
     return decodedvalue
 
-def validStatus(status):
+def valid_status(status):
     """Return legal HTTP status Code, Reason-phrase and Message.
     
     The status arg must be an int, or a str that begins with an int.
         raise ValueError("Illegal response status from server "
                          "(%s is out of range)." % repr(code))
     
-    if code not in responseCodes:
+    if code not in response_codes:
         # code is unknown but not illegal
-        defaultReason, message = "", ""
+        default_reason, message = "", ""
     else:
-        defaultReason, message = responseCodes[code]
+        default_reason, message = response_codes[code]
     
     if reason is None:
-        reason = defaultReason
+        reason = default_reason
     
     return code, reason, message
 
 
 image_map_pattern = re.compile(r"[0-9]+,[0-9]+")
 
-def parseQueryString(query_string, keep_blank_values=True):
-    """Build a paramMap dictionary from a query_string."""
+def parse_query_string(query_string, keep_blank_values=True):
+    """Build a params dictionary from a query_string."""
     if image_map_pattern.match(query_string):
         # Server-side image map. Map the coords to 'x' and 'y'
         # (like CGI::Request does).
                 pm[key] = val[0]
     return pm
 
-def paramsFromCGIForm(form):
-    paramMap = {}
+def params_from_CGI_form(form):
+    params = {}
     for key in form.keys():
-        valueList = form[key]
-        if isinstance(valueList, list):
-            paramMap[key] = []
-            for item in valueList:
+        value_list = form[key]
+        if isinstance(value_list, list):
+            params[key] = []
+            for item in value_list:
                 if item.filename is not None:
                     value = item # It's a file upload
                 else:
                     value = item.value # It's a regular field
-                paramMap[key].append(value)
+                params[key].append(value)
         else:
-            if valueList.filename is not None:
-                value = valueList # It's a file upload
+            if value_list.filename is not None:
+                value = value_list # It's a file upload
             else:
-                value = valueList.value # It's a regular field
-            paramMap[key] = value
-    return paramMap
+                value = value_list.value # It's a regular field
+            params[key] = value
+    return params
 
 
 class CaseInsensitiveDict(dict):
     # HTTP/1.0 didn't have Range/Accept-Ranges headers, or the 206 code
     if cherrypy.request.protocol >= (1, 1):
         response.headers["Accept-Ranges"] = "bytes"
-        r = http.getRanges(cherrypy.request.headers.get('Range'), c_len)
+        r = http.get_ranges(cherrypy.request.headers.get('Range'), c_len)
         if r == []:
             response.headers['Content-Range'] = "bytes */%s" % c_len
             message = "Invalid Range (first-byte-pos greater than Content-Length)"
                 response.headers['Content-Type'] = ct
 ##                del response.headers['Content-Length']
                 
-                def fileRanges():
+                def file_ranges():
                     for start, stop in r:
                         yield "--" + boundary
                         yield "\nContent-type: %s" % content_type
                         yield "\n"
                     # Final boundary
                     yield "--" + boundary
-                response.body = fileRanges()
+                response.body = file_ranges()
         else:
             response.headers['Content-Length'] = c_len
             response.body = bodyfile
     """
     # the tidy tool, by its very nature it's not generator friendly, 
     # so we just collapse the body and work with it.
-    originalBody = cherrypy.response.collapse_body()
+    orig_body = cherrypy.response.collapse_body()
     
     fct = cherrypy.response.headers.get('Content-Type', '')
     ct = fct.split(';')[0]
         encoding = fct[i + 8:]
     
     if ct == 'text/html':
-        pageFile = os.path.join(temp_dir, 'page.html')
-        open(pageFile, 'wb').write(originalBody)
+        page_file = os.path.join(temp_dir, 'page.html')
+        open(page_file, 'wb').write(orig_body)
         
-        outFile = os.path.join(temp_dir, 'tidy.out')
-        errFile = os.path.join(temp_dir, 'tidy.err')
-        tidyEncoding = encoding.replace('-', '')
-        if tidyEncoding:
-            tidyEncoding = '-' + tidyEncoding
+        out_file = os.path.join(temp_dir, 'tidy.out')
+        err_file = os.path.join(temp_dir, 'tidy.err')
+        tidy_enc = encoding.replace('-', '')
+        if tidy_enc:
+            tidy_enc = '-' + tidy_enc
         
         strict_xml = (" -xml", "")[bool(strict_xml)]
         os.system('"%s" %s%s -f %s -o %s %s' %
-                  (tidy_path, tidyEncoding, strict_xml,
-                   errFile, outFile, pageFile))
-        errs = open(errFile, 'rb').read()
+                  (tidy_path, tidy_enc, strict_xml,
+                   err_file, out_file, page_file))
+        errs = open(err_file, 'rb').read()
         
         new_errs = []
         for err in errs.splitlines():
             if (err.find('Warning') != -1 or err.find('Error') != -1):
                 ignore = 0
-                for errIgn in errors_to_ignore or []:
-                    if err.find(errIgn) != -1:
+                for err_ign in errors_to_ignore or []:
+                    if err.find(err_ign) != -1:
                         ignore = 1
                         break
                 if not ignore:
         
         if new_errs:
             cherrypy.response.body = wrong_content('<br />'.join(new_errs),
-                                                   original_body)
+                                                   orig_body)
         elif strict_xml:
             # The HTML is OK, but is it valid XML?
             # Use elementtree to parse XML
             from elementtree.ElementTree import parse
-            tagList = ['nbsp', 'quot']
-            for tag in tagList:
-                originalBody = originalBody.replace('&' + tag + ';', tag.upper())
+            tag_list = ['nbsp', 'quot']
+            for tag in tag_list:
+                orig_body = orig_body.replace('&' + tag + ';', tag.upper())
             
             if encoding:
                 enctag = '<?xml version="1.0" encoding="%s"?>' % encoding
-                originalBody = enctag + originalBody
+                orig_body = enctag + orig_body
             
-            f = StringIO.StringIO(originalBody)
+            f = StringIO.StringIO(orig_body)
             try:
                 tree = parse(f)
             except:
                 # Wrong XML
-                bodyFile = StringIO.StringIO()
-                traceback.print_exc(file = bodyFile)
-                bodyFile = '<br />'.join(bodyFile.getvalue())
-                cherrypy.response.body = wrong_content(bodyFile, originalbody, "XML")
+                body_file = StringIO.StringIO()
+                traceback.print_exc(file = body_file)
+                body_file = '<br />'.join(body_file.getvalue())
+                cherrypy.response.body = wrong_content(body_file, orig_body, "XML")
 
 def html_space(text):
     """Escape text, replacing space with nbsp and tab with 4 nbsp's."""
 def nsgmls(temp_dir, nsgmls_path, catalog_path, errors_to_ignore=None):
     # the tidy tool, by its very nature it's not generator friendly, 
     # so we just collect the body and work with it.
-    original_body = cherrypy.response.collapse_body()
+    orig_body = cherrypy.response.collapse_body()
     
     fct = cherrypy.response.headers.get('Content-Type', '')
     ct = fct.split(';')[0]
         #   them correctly (for instance, if <a appears in your
         #   Javascript code nsgmls complains about it)
         while True:
-            i = original_body.find('<script')
+            i = orig_body.find('<script')
             if i == -1:
                 break
-            j = original_body.find('</script>', i)
+            j = orig_body.find('</script>', i)
             if j == -1:
                 break
-            original_body = original_body[:i] + original_body[j+9:]
+            orig_body = orig_body[:i] + orig_body[j+9:]
 
         page_file = os.path.join(temp_dir, 'page.html')
-        open(page_file, 'wb').write(original_body)
+        open(page_file, 'wb').write(orig_body)
         
         err_file = os.path.join(temp_dir, 'nsgmls.err')
         command = ('%s -c%s -f%s -s -E10 %s' %
         
         if new_errs:
             cherrypy.response.body = wrong_content('<br />'.join(new_errs),
-                                                   original_body)
+                                                   orig_body)
 

test/test_core.py

         
         def get_ranges(self):
             h = cherrypy.request.headers.get('Range')
-            return repr(http.getRanges(h, 8))
+            return repr(http.get_ranges(h, 8))
         
         def slice_file(self):
             path = os.path.join(os.getcwd(), os.path.dirname(__file__))
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.