Fix for issue #693

- Remodeled the logic to use imp module to validate the python
	  gunicorn config file
This commit is contained in:
Jeryn Mathew 2014-03-15 12:16:18 +05:30
parent 2e84d68edb
commit e1e5d3638f

View File

@ -288,26 +288,37 @@ _add_doc(u, """Text literal""")
def _check_if_pyc(fname): def _check_if_pyc(fname):
""" Returns True if the extension is .pyc, False if .py and None if otherwise """ """ Returns True if the extension is .pyc, False if .py and None if otherwise """
# Make common lambda from imp import find_module
test = lambda ext: True if fname.rfind(ext) == len(fname) - len(ext) else False from os.path import realpath, dirname, basename, splitext
# Run test
if test(".pyc"): # Normalize the file-path for the find_module()
# TODO: Actually check if file content is .pyc compliant filepath = realpath(fname)
return True dirpath = dirname(filepath)
elif test(".py"): module_name = splitext(basename(filepath))[0]
# TODO: Actually check if file is .py by trying to import
return False # Validate and fetch
else: try:
return None fileobj, fullpath, (_, _, pytype) = find_module(module_name, [ dirpath ])
except ImportError:
raise IOError("Cannot find config file. Path maybe incorrect! : {0}".format(filepath))
return (pytype, fileobj, fullpath)
def _get_codeobj(pyfile): def _get_codeobj(pyfile):
""" Returns the code object, given a python file """ """ Returns the code object, given a python file """
result = _check_if_pyc(pyfile) from imp import PY_COMPILED, PY_SOURCE
if result is True:
result, fileobj, fullpath = _check_if_pyc(pyfile)
# WARNING:
# fp.read() can blowup if the module is extremely large file.
# Lookout for overflow errors.
if result is PY_COMPILED:
# This is a .pyc file. Treat accordingly. # This is a .pyc file. Treat accordingly.
with open(pyfile, "rb") as pycfile: data = fileobj.read()
data = pycfile.read() fileobj.close()
# .pyc format is as follows: # .pyc format is as follows:
# 0 - 4 bytes: Magic number, which changes with each create of .pyc file. # 0 - 4 bytes: Magic number, which changes with each create of .pyc file.
@ -318,13 +329,14 @@ def _get_codeobj(pyfile):
import marshal import marshal
code_obj = marshal.loads(data[8:]) code_obj = marshal.loads(data[8:])
elif result is False: elif result is PY_SOURCE:
# This is a .py file. # This is a .py file.
code_obj = compile(open(pyfile, 'rb').read(), pyfile, 'exec') code_obj = compile(fileobj.read(), fullpath, 'exec')
fileobj.close()
else: else:
# Dunno what this is... # Unsupported extension
raise Exception("Input file is unknown format: {0}".format(pyfile)) raise Exception("Input file is unknown format: {0}".format(fullpath))
# Return code object # Return code object
return code_obj return code_obj