mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
PEP8 fixes
This commit is contained in:
parent
1c9b8460b1
commit
20cd49595a
@ -1,4 +1,4 @@
|
|||||||
# -*- coding: utf-8 -
|
# -*- coding: utf-8 -
|
||||||
#
|
#
|
||||||
# This file is part of gunicorn released under the MIT license.
|
# This file is part of gunicorn released under the MIT license.
|
||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
|
|||||||
@ -13,6 +13,7 @@ from gunicorn.config import Config
|
|||||||
from gunicorn import debug
|
from gunicorn import debug
|
||||||
from gunicorn.six import execfile_
|
from gunicorn.six import execfile_
|
||||||
|
|
||||||
|
|
||||||
class Application(object):
|
class Application(object):
|
||||||
"""\
|
"""\
|
||||||
An application interface for configuring and loading
|
An application interface for configuring and loading
|
||||||
@ -129,4 +130,3 @@ class Application(object):
|
|||||||
sys.stderr.write("\nError: %s\n\n" % e)
|
sys.stderr.write("\nError: %s\n\n" % e)
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|||||||
@ -46,6 +46,7 @@ def make_wsgi_application():
|
|||||||
return get_internal_wsgi_application()
|
return get_internal_wsgi_application()
|
||||||
return WSGIHandler()
|
return WSGIHandler()
|
||||||
|
|
||||||
|
|
||||||
def reload_django_settings():
|
def reload_django_settings():
|
||||||
mod = util.import_module(os.environ['DJANGO_SETTINGS_MODULE'])
|
mod = util.import_module(os.environ['DJANGO_SETTINGS_MODULE'])
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ def reload_django_settings():
|
|||||||
if setting == setting.upper():
|
if setting == setting.upper():
|
||||||
setting_value = getattr(mod, setting)
|
setting_value = getattr(mod, setting)
|
||||||
if setting in tuple_settings and type(setting_value) == str:
|
if setting in tuple_settings and type(setting_value) == str:
|
||||||
setting_value = (setting_value,) # In case the user forgot the comma.
|
setting_value = (setting_value,) # In case the user forgot the comma.
|
||||||
setattr(settings, setting, setting_value)
|
setattr(settings, setting, setting_value)
|
||||||
|
|
||||||
# Expand entries in INSTALLED_APPS like "django.contrib.*" to a list
|
# Expand entries in INSTALLED_APPS like "django.contrib.*" to a list
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import sys
|
|||||||
from gunicorn.app.base import Application
|
from gunicorn.app.base import Application
|
||||||
from gunicorn import util
|
from gunicorn import util
|
||||||
|
|
||||||
|
|
||||||
def is_setting_mod(path):
|
def is_setting_mod(path):
|
||||||
return (os.path.isfile(os.path.join(path, "settings.py")) or
|
return (os.path.isfile(os.path.join(path, "settings.py")) or
|
||||||
os.path.isfile(os.path.join(path, "settings.pyc")))
|
os.path.isfile(os.path.join(path, "settings.pyc")))
|
||||||
@ -34,7 +35,7 @@ def find_settings_module(path):
|
|||||||
project_path = path
|
project_path = path
|
||||||
elif os.path.isfile(path):
|
elif os.path.isfile(path):
|
||||||
project_path = os.path.dirname(path)
|
project_path = os.path.dirname(path)
|
||||||
settings_name, _ = os.path.splitext(os.path.basename(path))
|
settings_name, _ = os.path.splitext(os.path.basename(path))
|
||||||
|
|
||||||
return project_path, settings_name
|
return project_path, settings_name
|
||||||
|
|
||||||
@ -91,7 +92,6 @@ class DjangoApplication(Application):
|
|||||||
settings_name))
|
settings_name))
|
||||||
self.cfg.set("pythonpath", pythonpath)
|
self.cfg.set("pythonpath", pythonpath)
|
||||||
|
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
# set settings
|
# set settings
|
||||||
make_default_env(self.cfg)
|
make_default_env(self.cfg)
|
||||||
@ -114,7 +114,6 @@ class DjangoApplicationCommand(Application):
|
|||||||
|
|
||||||
self.do_load_config()
|
self.do_load_config()
|
||||||
|
|
||||||
|
|
||||||
def init(self, *args):
|
def init(self, *args):
|
||||||
if 'settings' in self.options:
|
if 'settings' in self.options:
|
||||||
self.options['django_settings'] = self.options.pop('settings')
|
self.options['django_settings'] = self.options.pop('settings')
|
||||||
@ -133,6 +132,7 @@ class DjangoApplicationCommand(Application):
|
|||||||
mod = util.import_module("gunicorn.app.django_wsgi")
|
mod = util.import_module("gunicorn.app.django_wsgi")
|
||||||
return mod.make_command_wsgi_application(self.admin_media_path)
|
return mod.make_command_wsgi_application(self.admin_media_path)
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
"""\
|
"""\
|
||||||
The ``gunicorn_django`` command line runner for launching Django
|
The ``gunicorn_django`` command line runner for launching Django
|
||||||
|
|||||||
@ -18,6 +18,7 @@ SERVER = loadwsgi.SERVER
|
|||||||
from gunicorn.app.base import Application
|
from gunicorn.app.base import Application
|
||||||
from gunicorn.config import Config
|
from gunicorn.config import Config
|
||||||
|
|
||||||
|
|
||||||
class PasterBaseApplication(Application):
|
class PasterBaseApplication(Application):
|
||||||
|
|
||||||
def app_config(self):
|
def app_config(self):
|
||||||
@ -60,6 +61,7 @@ class PasterBaseApplication(Application):
|
|||||||
fileConfig(config_file, dict(__file__=config_file,
|
fileConfig(config_file, dict(__file__=config_file,
|
||||||
here=os.path.dirname(config_file)))
|
here=os.path.dirname(config_file)))
|
||||||
|
|
||||||
|
|
||||||
class PasterApplication(PasterBaseApplication):
|
class PasterApplication(PasterBaseApplication):
|
||||||
|
|
||||||
def init(self, parser, opts, args):
|
def init(self, parser, opts, args):
|
||||||
@ -83,6 +85,7 @@ class PasterApplication(PasterBaseApplication):
|
|||||||
def load(self):
|
def load(self):
|
||||||
return loadapp(self.cfgurl, relative_to=self.relpath)
|
return loadapp(self.cfgurl, relative_to=self.relpath)
|
||||||
|
|
||||||
|
|
||||||
class PasterServerApplication(PasterBaseApplication):
|
class PasterServerApplication(PasterBaseApplication):
|
||||||
|
|
||||||
def __init__(self, app, gcfg=None, host="127.0.0.1", port=None, *args, **kwargs):
|
def __init__(self, app, gcfg=None, host="127.0.0.1", port=None, *args, **kwargs):
|
||||||
@ -119,13 +122,12 @@ class PasterServerApplication(PasterBaseApplication):
|
|||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def load_config(self):
|
def load_config(self):
|
||||||
if not hasattr(self, "cfgfname"):
|
if not hasattr(self, "cfgfname"):
|
||||||
return
|
return
|
||||||
|
|
||||||
cfg = self.app_config()
|
cfg = self.app_config()
|
||||||
for k,v in cfg.items():
|
for k, v in cfg.items():
|
||||||
try:
|
try:
|
||||||
self.cfg.set(k.lower(), v)
|
self.cfg.set(k.lower(), v)
|
||||||
except:
|
except:
|
||||||
@ -147,6 +149,7 @@ def run():
|
|||||||
from gunicorn.app.pasterapp import PasterApplication
|
from gunicorn.app.pasterapp import PasterApplication
|
||||||
PasterApplication("%prog [OPTIONS] pasteconfig.ini").run()
|
PasterApplication("%prog [OPTIONS] pasteconfig.ini").run()
|
||||||
|
|
||||||
|
|
||||||
def paste_server(app, gcfg=None, host="127.0.0.1", port=None, *args, **kwargs):
|
def paste_server(app, gcfg=None, host="127.0.0.1", port=None, *args, **kwargs):
|
||||||
"""\
|
"""\
|
||||||
A paster server.
|
A paster server.
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import sys
|
|||||||
from gunicorn import util
|
from gunicorn import util
|
||||||
from gunicorn.app.base import Application
|
from gunicorn.app.base import Application
|
||||||
|
|
||||||
|
|
||||||
class WSGIApplication(Application):
|
class WSGIApplication(Application):
|
||||||
|
|
||||||
def init(self, parser, opts, args):
|
def init(self, parser, opts, args):
|
||||||
@ -23,6 +24,7 @@ class WSGIApplication(Application):
|
|||||||
def load(self):
|
def load(self):
|
||||||
return util.import_app(self.app_uri)
|
return util.import_app(self.app_uri)
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
"""\
|
"""\
|
||||||
The ``gunicorn`` command line runner for launcing Gunicorn with
|
The ``gunicorn`` command line runner for launcing Gunicorn with
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import sys
|
|||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
from gunicorn.errors import HaltServer
|
from gunicorn.errors import HaltServer
|
||||||
from gunicorn.pidfile import Pidfile
|
from gunicorn.pidfile import Pidfile
|
||||||
from gunicorn.sock import create_sockets
|
from gunicorn.sock import create_sockets
|
||||||
@ -21,6 +20,7 @@ from gunicorn import util
|
|||||||
|
|
||||||
from gunicorn import __version__, SERVER_SOFTWARE
|
from gunicorn import __version__, SERVER_SOFTWARE
|
||||||
|
|
||||||
|
|
||||||
class Arbiter(object):
|
class Arbiter(object):
|
||||||
"""
|
"""
|
||||||
Arbiter maintain the workers processes alive. It launches or
|
Arbiter maintain the workers processes alive. It launches or
|
||||||
@ -82,6 +82,7 @@ class Arbiter(object):
|
|||||||
|
|
||||||
def _get_num_workers(self):
|
def _get_num_workers(self):
|
||||||
return self._num_workers
|
return self._num_workers
|
||||||
|
|
||||||
def _set_num_workers(self, value):
|
def _set_num_workers(self, value):
|
||||||
old_value = self._num_workers
|
old_value = self._num_workers
|
||||||
self._num_workers = value
|
self._num_workers = value
|
||||||
@ -106,8 +107,6 @@ class Arbiter(object):
|
|||||||
|
|
||||||
if self.cfg.debug:
|
if self.cfg.debug:
|
||||||
self.log.debug("Current configuration:")
|
self.log.debug("Current configuration:")
|
||||||
|
|
||||||
|
|
||||||
for config, value in sorted(self.cfg.settings.items(),
|
for config, value in sorted(self.cfg.settings.items(),
|
||||||
key=lambda setting: setting[1]):
|
key=lambda setting: setting[1]):
|
||||||
self.log.debug(" %s: %s", config, value.value)
|
self.log.debug(" %s: %s", config, value.value)
|
||||||
@ -322,7 +321,6 @@ class Arbiter(object):
|
|||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
def stop(self, graceful=True):
|
def stop(self, graceful=True):
|
||||||
"""\
|
"""\
|
||||||
Stop workers
|
Stop workers
|
||||||
@ -367,7 +365,7 @@ class Arbiter(object):
|
|||||||
|
|
||||||
# close all file descriptors except bound sockets
|
# close all file descriptors except bound sockets
|
||||||
util.closerange(3, fds[0])
|
util.closerange(3, fds[0])
|
||||||
util.closerange(fds[-1]+1, util.get_maxfd())
|
util.closerange(fds[-1] + 1, util.get_maxfd())
|
||||||
|
|
||||||
os.execvpe(self.START_CTX[0], self.START_CTX['args'], os.environ)
|
os.execvpe(self.START_CTX[0], self.START_CTX['args'], os.environ)
|
||||||
|
|
||||||
@ -470,7 +468,7 @@ class Arbiter(object):
|
|||||||
def spawn_worker(self):
|
def spawn_worker(self):
|
||||||
self.worker_age += 1
|
self.worker_age += 1
|
||||||
worker = self.worker_class(self.worker_age, self.pid, self.LISTENERS,
|
worker = self.worker_class(self.worker_age, self.pid, self.LISTENERS,
|
||||||
self.app, self.timeout/2.0,
|
self.app, self.timeout / 2.0,
|
||||||
self.cfg, self.log)
|
self.cfg, self.log)
|
||||||
self.cfg.pre_fork(self, worker)
|
self.cfg.pre_fork(self, worker)
|
||||||
pid = os.fork()
|
pid = os.fork()
|
||||||
|
|||||||
@ -19,11 +19,13 @@ from gunicorn.six import string_types, integer_types, bytes_to_str
|
|||||||
|
|
||||||
KNOWN_SETTINGS = []
|
KNOWN_SETTINGS = []
|
||||||
|
|
||||||
|
|
||||||
def wrap_method(func):
|
def wrap_method(func):
|
||||||
def _wrapped(instance, *args, **kwargs):
|
def _wrapped(instance, *args, **kwargs):
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
return _wrapped
|
return _wrapped
|
||||||
|
|
||||||
|
|
||||||
def make_settings(ignore=None):
|
def make_settings(ignore=None):
|
||||||
settings = {}
|
settings = {}
|
||||||
ignore = ignore or ()
|
ignore = ignore or ()
|
||||||
@ -34,6 +36,7 @@ def make_settings(ignore=None):
|
|||||||
settings[setting.name] = setting.copy()
|
settings[setting.name] = setting.copy()
|
||||||
return settings
|
return settings
|
||||||
|
|
||||||
|
|
||||||
class Config(object):
|
class Config(object):
|
||||||
|
|
||||||
def __init__(self, usage=None):
|
def __init__(self, usage=None):
|
||||||
@ -63,10 +66,10 @@ class Config(object):
|
|||||||
parser = optparse.OptionParser(**kwargs)
|
parser = optparse.OptionParser(**kwargs)
|
||||||
|
|
||||||
keys = list(self.settings)
|
keys = list(self.settings)
|
||||||
|
|
||||||
def sorter(k):
|
def sorter(k):
|
||||||
return (self.settings[k].section, self.settings[k].order)
|
return (self.settings[k].section, self.settings[k].order)
|
||||||
|
|
||||||
|
|
||||||
keys = sorted(self.settings, key=self.settings.__getitem__)
|
keys = sorted(self.settings, key=self.settings.__getitem__)
|
||||||
for k in keys:
|
for k in keys:
|
||||||
self.settings[k].add_option(parser)
|
self.settings[k].add_option(parser)
|
||||||
@ -151,6 +154,7 @@ class SettingMeta(type):
|
|||||||
setattr(cls, "desc", desc)
|
setattr(cls, "desc", desc)
|
||||||
setattr(cls, "short", desc.splitlines()[0])
|
setattr(cls, "short", desc.splitlines()[0])
|
||||||
|
|
||||||
|
|
||||||
class Setting(object):
|
class Setting(object):
|
||||||
name = None
|
name = None
|
||||||
value = None
|
value = None
|
||||||
@ -201,6 +205,7 @@ class Setting(object):
|
|||||||
|
|
||||||
Setting = SettingMeta('Setting', (Setting,), {})
|
Setting = SettingMeta('Setting', (Setting,), {})
|
||||||
|
|
||||||
|
|
||||||
def validate_bool(val):
|
def validate_bool(val):
|
||||||
if isinstance(val, bool):
|
if isinstance(val, bool):
|
||||||
return val
|
return val
|
||||||
@ -213,11 +218,13 @@ def validate_bool(val):
|
|||||||
else:
|
else:
|
||||||
raise ValueError("Invalid boolean: %s" % val)
|
raise ValueError("Invalid boolean: %s" % val)
|
||||||
|
|
||||||
|
|
||||||
def validate_dict(val):
|
def validate_dict(val):
|
||||||
if not isinstance(val, dict):
|
if not isinstance(val, dict):
|
||||||
raise TypeError("Value is not a dictionary: %s " % val)
|
raise TypeError("Value is not a dictionary: %s " % val)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
def validate_pos_int(val):
|
def validate_pos_int(val):
|
||||||
if not isinstance(val, integer_types):
|
if not isinstance(val, integer_types):
|
||||||
val = int(val, 0)
|
val = int(val, 0)
|
||||||
@ -228,6 +235,7 @@ def validate_pos_int(val):
|
|||||||
raise ValueError("Value must be positive: %s" % val)
|
raise ValueError("Value must be positive: %s" % val)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
def validate_string(val):
|
def validate_string(val):
|
||||||
if val is None:
|
if val is None:
|
||||||
return None
|
return None
|
||||||
@ -235,6 +243,7 @@ def validate_string(val):
|
|||||||
raise TypeError("Not a string: %s" % val)
|
raise TypeError("Not a string: %s" % val)
|
||||||
return val.strip()
|
return val.strip()
|
||||||
|
|
||||||
|
|
||||||
def validate_list_string(val):
|
def validate_list_string(val):
|
||||||
if not val:
|
if not val:
|
||||||
return []
|
return []
|
||||||
@ -245,6 +254,7 @@ def validate_list_string(val):
|
|||||||
|
|
||||||
return [validate_string(v) for v in val]
|
return [validate_string(v) for v in val]
|
||||||
|
|
||||||
|
|
||||||
def validate_string_to_list(val):
|
def validate_string_to_list(val):
|
||||||
val = validate_string(val)
|
val = validate_string(val)
|
||||||
|
|
||||||
@ -253,6 +263,7 @@ def validate_string_to_list(val):
|
|||||||
|
|
||||||
return [v.strip() for v in val.split(",") if v]
|
return [v.strip() for v in val.split(",") if v]
|
||||||
|
|
||||||
|
|
||||||
def validate_class(val):
|
def validate_class(val):
|
||||||
if inspect.isfunction(val) or inspect.ismethod(val):
|
if inspect.isfunction(val) or inspect.ismethod(val):
|
||||||
val = val()
|
val = val()
|
||||||
@ -260,6 +271,7 @@ def validate_class(val):
|
|||||||
return val
|
return val
|
||||||
return validate_string(val)
|
return validate_string(val)
|
||||||
|
|
||||||
|
|
||||||
def validate_callable(arity):
|
def validate_callable(arity):
|
||||||
def _validate_callable(val):
|
def _validate_callable(val):
|
||||||
if isinstance(val, string_types):
|
if isinstance(val, string_types):
|
||||||
@ -297,6 +309,7 @@ def validate_user(val):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
raise ConfigError("No such user: '%s'" % val)
|
raise ConfigError("No such user: '%s'" % val)
|
||||||
|
|
||||||
|
|
||||||
def validate_group(val):
|
def validate_group(val):
|
||||||
if val is None:
|
if val is None:
|
||||||
return os.getegid()
|
return os.getegid()
|
||||||
@ -311,6 +324,7 @@ def validate_group(val):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
raise ConfigError("No such group: '%s'" % val)
|
raise ConfigError("No such group: '%s'" % val)
|
||||||
|
|
||||||
|
|
||||||
def validate_post_request(val):
|
def validate_post_request(val):
|
||||||
val = validate_callable(-1)(val)
|
val = validate_callable(-1)(val)
|
||||||
|
|
||||||
@ -325,7 +339,6 @@ def validate_post_request(val):
|
|||||||
raise TypeError("Value must have an arity of: 4")
|
raise TypeError("Value must have an arity of: 4")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigFile(Setting):
|
class ConfigFile(Setting):
|
||||||
name = "config"
|
name = "config"
|
||||||
section = "Config File"
|
section = "Config File"
|
||||||
@ -340,6 +353,7 @@ class ConfigFile(Setting):
|
|||||||
application specific configuration.
|
application specific configuration.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Bind(Setting):
|
class Bind(Setting):
|
||||||
name = "bind"
|
name = "bind"
|
||||||
action = "append"
|
action = "append"
|
||||||
@ -367,6 +381,7 @@ class Bind(Setting):
|
|||||||
and ipv4 interfaces.
|
and ipv4 interfaces.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Backlog(Setting):
|
class Backlog(Setting):
|
||||||
name = "backlog"
|
name = "backlog"
|
||||||
section = "Server Socket"
|
section = "Server Socket"
|
||||||
@ -386,6 +401,7 @@ class Backlog(Setting):
|
|||||||
Must be a positive integer. Generally set in the 64-2048 range.
|
Must be a positive integer. Generally set in the 64-2048 range.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Workers(Setting):
|
class Workers(Setting):
|
||||||
name = "workers"
|
name = "workers"
|
||||||
section = "Worker Processes"
|
section = "Worker Processes"
|
||||||
@ -402,6 +418,7 @@ class Workers(Setting):
|
|||||||
application's work load.
|
application's work load.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class WorkerClass(Setting):
|
class WorkerClass(Setting):
|
||||||
name = "worker_class"
|
name = "worker_class"
|
||||||
section = "Worker Processes"
|
section = "Worker Processes"
|
||||||
@ -430,6 +447,7 @@ class WorkerClass(Setting):
|
|||||||
can also load the gevent class with ``egg:gunicorn#gevent``
|
can also load the gevent class with ``egg:gunicorn#gevent``
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class WorkerConnections(Setting):
|
class WorkerConnections(Setting):
|
||||||
name = "worker_connections"
|
name = "worker_connections"
|
||||||
section = "Worker Processes"
|
section = "Worker Processes"
|
||||||
@ -444,6 +462,7 @@ class WorkerConnections(Setting):
|
|||||||
This setting only affects the Eventlet and Gevent worker types.
|
This setting only affects the Eventlet and Gevent worker types.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class MaxRequests(Setting):
|
class MaxRequests(Setting):
|
||||||
name = "max_requests"
|
name = "max_requests"
|
||||||
section = "Worker Processes"
|
section = "Worker Processes"
|
||||||
@ -463,6 +482,7 @@ class MaxRequests(Setting):
|
|||||||
restarts are disabled.
|
restarts are disabled.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Timeout(Setting):
|
class Timeout(Setting):
|
||||||
name = "timeout"
|
name = "timeout"
|
||||||
section = "Worker Processes"
|
section = "Worker Processes"
|
||||||
@ -480,6 +500,7 @@ class Timeout(Setting):
|
|||||||
is not tied to the length of time required to handle a single request.
|
is not tied to the length of time required to handle a single request.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class GracefulTimeout(Setting):
|
class GracefulTimeout(Setting):
|
||||||
name = "graceful_timeout"
|
name = "graceful_timeout"
|
||||||
section = "Worker Processes"
|
section = "Worker Processes"
|
||||||
@ -496,6 +517,7 @@ class GracefulTimeout(Setting):
|
|||||||
be force killed.
|
be force killed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Keepalive(Setting):
|
class Keepalive(Setting):
|
||||||
name = "keepalive"
|
name = "keepalive"
|
||||||
section = "Worker Processes"
|
section = "Worker Processes"
|
||||||
@ -510,6 +532,7 @@ class Keepalive(Setting):
|
|||||||
Generally set in the 1-5 seconds range.
|
Generally set in the 1-5 seconds range.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class LimitRequestLine(Setting):
|
class LimitRequestLine(Setting):
|
||||||
name = "limit_request_line"
|
name = "limit_request_line"
|
||||||
section = "Security"
|
section = "Security"
|
||||||
@ -533,6 +556,7 @@ class LimitRequestLine(Setting):
|
|||||||
This parameter can be used to prevent any DDOS attack.
|
This parameter can be used to prevent any DDOS attack.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class LimitRequestFields(Setting):
|
class LimitRequestFields(Setting):
|
||||||
name = "limit_request_fields"
|
name = "limit_request_fields"
|
||||||
section = "Security"
|
section = "Security"
|
||||||
@ -541,7 +565,7 @@ class LimitRequestFields(Setting):
|
|||||||
validator = validate_pos_int
|
validator = validate_pos_int
|
||||||
type = "int"
|
type = "int"
|
||||||
default = 100
|
default = 100
|
||||||
desc= """\
|
desc = """\
|
||||||
Limit the number of HTTP headers fields in a request.
|
Limit the number of HTTP headers fields in a request.
|
||||||
|
|
||||||
This parameter is used to limit the number of headers in a request to
|
This parameter is used to limit the number of headers in a request to
|
||||||
@ -550,6 +574,7 @@ class LimitRequestFields(Setting):
|
|||||||
32768.
|
32768.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class LimitRequestFieldSize(Setting):
|
class LimitRequestFieldSize(Setting):
|
||||||
name = "limit_request_field_size"
|
name = "limit_request_field_size"
|
||||||
section = "Security"
|
section = "Security"
|
||||||
@ -558,13 +583,14 @@ class LimitRequestFieldSize(Setting):
|
|||||||
validator = validate_pos_int
|
validator = validate_pos_int
|
||||||
type = "int"
|
type = "int"
|
||||||
default = 8190
|
default = 8190
|
||||||
desc= """\
|
desc = """\
|
||||||
Limit the allowed size of an HTTP request header field.
|
Limit the allowed size of an HTTP request header field.
|
||||||
|
|
||||||
Value is a number from 0 (unlimited) to 8190. to set the limit
|
Value is a number from 0 (unlimited) to 8190. to set the limit
|
||||||
on the allowed size of an HTTP request header field.
|
on the allowed size of an HTTP request header field.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Debug(Setting):
|
class Debug(Setting):
|
||||||
name = "debug"
|
name = "debug"
|
||||||
section = "Debugging"
|
section = "Debugging"
|
||||||
@ -579,6 +605,7 @@ class Debug(Setting):
|
|||||||
handling that's sent to clients.
|
handling that's sent to clients.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Spew(Setting):
|
class Spew(Setting):
|
||||||
name = "spew"
|
name = "spew"
|
||||||
section = "Debugging"
|
section = "Debugging"
|
||||||
@ -592,10 +619,11 @@ class Spew(Setting):
|
|||||||
This is the nuclear option.
|
This is the nuclear option.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ConfigCheck(Setting):
|
class ConfigCheck(Setting):
|
||||||
name = "check_config"
|
name = "check_config"
|
||||||
section = "Debugging"
|
section = "Debugging"
|
||||||
cli = ["--check-config",]
|
cli = ["--check-config", ]
|
||||||
validator = validate_bool
|
validator = validate_bool
|
||||||
action = "store_true"
|
action = "store_true"
|
||||||
default = False
|
default = False
|
||||||
@ -603,6 +631,7 @@ class ConfigCheck(Setting):
|
|||||||
Check the configuration..
|
Check the configuration..
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class PreloadApp(Setting):
|
class PreloadApp(Setting):
|
||||||
name = "preload_app"
|
name = "preload_app"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -619,6 +648,7 @@ class PreloadApp(Setting):
|
|||||||
restarting workers.
|
restarting workers.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Daemon(Setting):
|
class Daemon(Setting):
|
||||||
name = "daemon"
|
name = "daemon"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -633,6 +663,7 @@ class Daemon(Setting):
|
|||||||
background.
|
background.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Pidfile(Setting):
|
class Pidfile(Setting):
|
||||||
name = "pidfile"
|
name = "pidfile"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -646,6 +677,7 @@ class Pidfile(Setting):
|
|||||||
If not set, no PID file will be written.
|
If not set, no PID file will be written.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class User(Setting):
|
class User(Setting):
|
||||||
name = "user"
|
name = "user"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -661,6 +693,7 @@ class User(Setting):
|
|||||||
the worker process user.
|
the worker process user.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Group(Setting):
|
class Group(Setting):
|
||||||
name = "group"
|
name = "group"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -676,6 +709,7 @@ class Group(Setting):
|
|||||||
the worker processes group.
|
the worker processes group.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Umask(Setting):
|
class Umask(Setting):
|
||||||
name = "umask"
|
name = "umask"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -694,6 +728,7 @@ class Umask(Setting):
|
|||||||
"0xFF", "0022" are valid for decimal, hex, and octal representations)
|
"0xFF", "0022" are valid for decimal, hex, and octal representations)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class TmpUploadDir(Setting):
|
class TmpUploadDir(Setting):
|
||||||
name = "tmp_upload_dir"
|
name = "tmp_upload_dir"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -710,6 +745,7 @@ class TmpUploadDir(Setting):
|
|||||||
temporary directory.
|
temporary directory.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class SecureSchemeHeader(Setting):
|
class SecureSchemeHeader(Setting):
|
||||||
name = "secure_scheme_headers"
|
name = "secure_scheme_headers"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -734,6 +770,8 @@ class SecureSchemeHeader(Setting):
|
|||||||
It is important that your front-end proxy configuration ensures that
|
It is important that your front-end proxy configuration ensures that
|
||||||
the headers defined here can not be passed directly from the client.
|
the headers defined here can not be passed directly from the client.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class XForwardedFor(Setting):
|
class XForwardedFor(Setting):
|
||||||
name = "x_forwarded_for_header"
|
name = "x_forwarded_for_header"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -745,6 +783,7 @@ class XForwardedFor(Setting):
|
|||||||
address of the client connection to gunicorn via a proxy.
|
address of the client connection to gunicorn via a proxy.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ForwardedAllowIPS(Setting):
|
class ForwardedAllowIPS(Setting):
|
||||||
name = "forwarded_allow_ips"
|
name = "forwarded_allow_ips"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -760,6 +799,7 @@ class ForwardedAllowIPS(Setting):
|
|||||||
you still trust the environment)
|
you still trust the environment)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class AccessLog(Setting):
|
class AccessLog(Setting):
|
||||||
name = "accesslog"
|
name = "accesslog"
|
||||||
section = "Logging"
|
section = "Logging"
|
||||||
@ -773,6 +813,7 @@ class AccessLog(Setting):
|
|||||||
"-" means log to stderr.
|
"-" means log to stderr.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class AccessLogFormat(Setting):
|
class AccessLogFormat(Setting):
|
||||||
name = "access_log_format"
|
name = "access_log_format"
|
||||||
section = "Logging"
|
section = "Logging"
|
||||||
@ -804,6 +845,7 @@ class AccessLogFormat(Setting):
|
|||||||
{Header}o: response header
|
{Header}o: response header
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ErrorLog(Setting):
|
class ErrorLog(Setting):
|
||||||
name = "errorlog"
|
name = "errorlog"
|
||||||
section = "Logging"
|
section = "Logging"
|
||||||
@ -817,6 +859,7 @@ class ErrorLog(Setting):
|
|||||||
"-" means log to stderr.
|
"-" means log to stderr.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Loglevel(Setting):
|
class Loglevel(Setting):
|
||||||
name = "loglevel"
|
name = "loglevel"
|
||||||
section = "Logging"
|
section = "Logging"
|
||||||
@ -836,6 +879,7 @@ class Loglevel(Setting):
|
|||||||
* critical
|
* critical
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class LoggerClass(Setting):
|
class LoggerClass(Setting):
|
||||||
name = "logger_class"
|
name = "logger_class"
|
||||||
section = "Logging"
|
section = "Logging"
|
||||||
@ -869,6 +913,7 @@ Gunicorn uses the standard Python logging module's Configuration
|
|||||||
file format.
|
file format.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Procname(Setting):
|
class Procname(Setting):
|
||||||
name = "proc_name"
|
name = "proc_name"
|
||||||
section = "Process Naming"
|
section = "Process Naming"
|
||||||
@ -887,6 +932,7 @@ class Procname(Setting):
|
|||||||
It defaults to 'gunicorn'.
|
It defaults to 'gunicorn'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class DefaultProcName(Setting):
|
class DefaultProcName(Setting):
|
||||||
name = "default_proc_name"
|
name = "default_proc_name"
|
||||||
section = "Process Naming"
|
section = "Process Naming"
|
||||||
@ -911,6 +957,7 @@ class DjangoSettings(Setting):
|
|||||||
DJANGO_SETTINGS_MODULE environment variable will be used.
|
DJANGO_SETTINGS_MODULE environment variable will be used.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class PythonPath(Setting):
|
class PythonPath(Setting):
|
||||||
name = "pythonpath"
|
name = "pythonpath"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -925,11 +972,13 @@ class PythonPath(Setting):
|
|||||||
'/home/djangoprojects/myproject'.
|
'/home/djangoprojects/myproject'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class OnStarting(Setting):
|
class OnStarting(Setting):
|
||||||
name = "on_starting"
|
name = "on_starting"
|
||||||
section = "Server Hooks"
|
section = "Server Hooks"
|
||||||
validator = validate_callable(1)
|
validator = validate_callable(1)
|
||||||
type = "callable"
|
type = "callable"
|
||||||
|
|
||||||
def on_starting(server):
|
def on_starting(server):
|
||||||
pass
|
pass
|
||||||
default = staticmethod(on_starting)
|
default = staticmethod(on_starting)
|
||||||
@ -939,11 +988,13 @@ class OnStarting(Setting):
|
|||||||
The callable needs to accept a single instance variable for the Arbiter.
|
The callable needs to accept a single instance variable for the Arbiter.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class OnReload(Setting):
|
class OnReload(Setting):
|
||||||
name = "on_reload"
|
name = "on_reload"
|
||||||
section = "Server Hooks"
|
section = "Server Hooks"
|
||||||
validator = validate_callable(1)
|
validator = validate_callable(1)
|
||||||
type = "callable"
|
type = "callable"
|
||||||
|
|
||||||
def on_reload(server):
|
def on_reload(server):
|
||||||
pass
|
pass
|
||||||
default = staticmethod(on_reload)
|
default = staticmethod(on_reload)
|
||||||
@ -953,11 +1004,13 @@ class OnReload(Setting):
|
|||||||
The callable needs to accept a single instance variable for the Arbiter.
|
The callable needs to accept a single instance variable for the Arbiter.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class WhenReady(Setting):
|
class WhenReady(Setting):
|
||||||
name = "when_ready"
|
name = "when_ready"
|
||||||
section = "Server Hooks"
|
section = "Server Hooks"
|
||||||
validator = validate_callable(1)
|
validator = validate_callable(1)
|
||||||
type = "callable"
|
type = "callable"
|
||||||
|
|
||||||
def when_ready(server):
|
def when_ready(server):
|
||||||
pass
|
pass
|
||||||
default = staticmethod(when_ready)
|
default = staticmethod(when_ready)
|
||||||
@ -967,11 +1020,13 @@ class WhenReady(Setting):
|
|||||||
The callable needs to accept a single instance variable for the Arbiter.
|
The callable needs to accept a single instance variable for the Arbiter.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Prefork(Setting):
|
class Prefork(Setting):
|
||||||
name = "pre_fork"
|
name = "pre_fork"
|
||||||
section = "Server Hooks"
|
section = "Server Hooks"
|
||||||
validator = validate_callable(2)
|
validator = validate_callable(2)
|
||||||
type = "callable"
|
type = "callable"
|
||||||
|
|
||||||
def pre_fork(server, worker):
|
def pre_fork(server, worker):
|
||||||
pass
|
pass
|
||||||
default = staticmethod(pre_fork)
|
default = staticmethod(pre_fork)
|
||||||
@ -982,11 +1037,13 @@ class Prefork(Setting):
|
|||||||
new Worker.
|
new Worker.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Postfork(Setting):
|
class Postfork(Setting):
|
||||||
name = "post_fork"
|
name = "post_fork"
|
||||||
section = "Server Hooks"
|
section = "Server Hooks"
|
||||||
validator = validate_callable(2)
|
validator = validate_callable(2)
|
||||||
type = "callable"
|
type = "callable"
|
||||||
|
|
||||||
def post_fork(server, worker):
|
def post_fork(server, worker):
|
||||||
pass
|
pass
|
||||||
default = staticmethod(post_fork)
|
default = staticmethod(post_fork)
|
||||||
@ -997,11 +1054,13 @@ class Postfork(Setting):
|
|||||||
new Worker.
|
new Worker.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class PreExec(Setting):
|
class PreExec(Setting):
|
||||||
name = "pre_exec"
|
name = "pre_exec"
|
||||||
section = "Server Hooks"
|
section = "Server Hooks"
|
||||||
validator = validate_callable(1)
|
validator = validate_callable(1)
|
||||||
type = "callable"
|
type = "callable"
|
||||||
|
|
||||||
def pre_exec(server):
|
def pre_exec(server):
|
||||||
pass
|
pass
|
||||||
default = staticmethod(pre_exec)
|
default = staticmethod(pre_exec)
|
||||||
@ -1011,11 +1070,13 @@ class PreExec(Setting):
|
|||||||
The callable needs to accept a single instance variable for the Arbiter.
|
The callable needs to accept a single instance variable for the Arbiter.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class PreRequest(Setting):
|
class PreRequest(Setting):
|
||||||
name = "pre_request"
|
name = "pre_request"
|
||||||
section = "Server Hooks"
|
section = "Server Hooks"
|
||||||
validator = validate_callable(2)
|
validator = validate_callable(2)
|
||||||
type = "callable"
|
type = "callable"
|
||||||
|
|
||||||
def pre_request(worker, req):
|
def pre_request(worker, req):
|
||||||
worker.log.debug("%s %s" % (req.method, req.path))
|
worker.log.debug("%s %s" % (req.method, req.path))
|
||||||
default = staticmethod(pre_request)
|
default = staticmethod(pre_request)
|
||||||
@ -1026,11 +1087,13 @@ class PreRequest(Setting):
|
|||||||
the Request.
|
the Request.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class PostRequest(Setting):
|
class PostRequest(Setting):
|
||||||
name = "post_request"
|
name = "post_request"
|
||||||
section = "Server Hooks"
|
section = "Server Hooks"
|
||||||
validator = validate_post_request
|
validator = validate_post_request
|
||||||
type = "callable"
|
type = "callable"
|
||||||
|
|
||||||
def post_request(worker, req, environ, resp):
|
def post_request(worker, req, environ, resp):
|
||||||
pass
|
pass
|
||||||
default = staticmethod(post_request)
|
default = staticmethod(post_request)
|
||||||
@ -1041,11 +1104,13 @@ class PostRequest(Setting):
|
|||||||
the Request.
|
the Request.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class WorkerExit(Setting):
|
class WorkerExit(Setting):
|
||||||
name = "worker_exit"
|
name = "worker_exit"
|
||||||
section = "Server Hooks"
|
section = "Server Hooks"
|
||||||
validator = validate_callable(2)
|
validator = validate_callable(2)
|
||||||
type = "callable"
|
type = "callable"
|
||||||
|
|
||||||
def worker_exit(server, worker):
|
def worker_exit(server, worker):
|
||||||
pass
|
pass
|
||||||
default = staticmethod(worker_exit)
|
default = staticmethod(worker_exit)
|
||||||
@ -1056,11 +1121,13 @@ class WorkerExit(Setting):
|
|||||||
the just-exited Worker.
|
the just-exited Worker.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class NumWorkersChanged(Setting):
|
class NumWorkersChanged(Setting):
|
||||||
name = "nworkers_changed"
|
name = "nworkers_changed"
|
||||||
section = "Server Hooks"
|
section = "Server Hooks"
|
||||||
validator = validate_callable(3)
|
validator = validate_callable(3)
|
||||||
type = "callable"
|
type = "callable"
|
||||||
|
|
||||||
def nworkers_changed(server, new_value, old_value):
|
def nworkers_changed(server, new_value, old_value):
|
||||||
pass
|
pass
|
||||||
default = staticmethod(nworkers_changed)
|
default = staticmethod(nworkers_changed)
|
||||||
@ -1074,6 +1141,7 @@ class NumWorkersChanged(Setting):
|
|||||||
None.
|
None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ProxyProtocol(Setting):
|
class ProxyProtocol(Setting):
|
||||||
name = "proxy_protocol"
|
name = "proxy_protocol"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -1099,6 +1167,7 @@ class ProxyProtocol(Setting):
|
|||||||
key = /etc/ssl/certs/stunnel.key
|
key = /etc/ssl/certs/stunnel.key
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ProxyAllowFrom(Setting):
|
class ProxyAllowFrom(Setting):
|
||||||
name = "proxy_allow_ips"
|
name = "proxy_allow_ips"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -1109,6 +1178,7 @@ class ProxyAllowFrom(Setting):
|
|||||||
Front-end's IPs from which allowed accept proxy requests (comma separate).
|
Front-end's IPs from which allowed accept proxy requests (comma separate).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class KeyFile(Setting):
|
class KeyFile(Setting):
|
||||||
name = "keyfile"
|
name = "keyfile"
|
||||||
section = "Ssl"
|
section = "Ssl"
|
||||||
@ -1120,6 +1190,7 @@ class KeyFile(Setting):
|
|||||||
SSL key file
|
SSL key file
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class CertFile(Setting):
|
class CertFile(Setting):
|
||||||
name = "certfile"
|
name = "certfile"
|
||||||
section = "Ssl"
|
section = "Ssl"
|
||||||
|
|||||||
@ -16,7 +16,6 @@ __all__ = ['spew', 'unspew']
|
|||||||
_token_spliter = re.compile('\W+')
|
_token_spliter = re.compile('\W+')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Spew(object):
|
class Spew(object):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
@ -69,5 +68,3 @@ def unspew():
|
|||||||
"""Remove the trace hook installed by spew.
|
"""Remove the trace hook installed by spew.
|
||||||
"""
|
"""
|
||||||
sys.settrace(None)
|
sys.settrace(None)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -12,5 +12,6 @@ class HaltServer(BaseException):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "<HaltServer %r %d>" % (self.reason, self.exit_status)
|
return "<HaltServer %r %d>" % (self.reason, self.exit_status)
|
||||||
|
|
||||||
|
|
||||||
class ConfigError(BaseException):
|
class ConfigError(BaseException):
|
||||||
""" Exception raised on config error """
|
""" Exception raised on config error """
|
||||||
|
|||||||
@ -17,11 +17,11 @@ from gunicorn import util
|
|||||||
from gunicorn.six import string_types
|
from gunicorn.six import string_types
|
||||||
|
|
||||||
CONFIG_DEFAULTS = dict(
|
CONFIG_DEFAULTS = dict(
|
||||||
version = 1,
|
version=1,
|
||||||
disable_existing_loggers = False,
|
disable_existing_loggers=False,
|
||||||
|
|
||||||
loggers = {
|
loggers={
|
||||||
"root": { "level": "INFO", "handlers": ["console"] },
|
"root": {"level": "INFO", "handlers": ["console"]},
|
||||||
"gunicorn.error": {
|
"gunicorn.error": {
|
||||||
"level": "INFO",
|
"level": "INFO",
|
||||||
"handlers": ["console"],
|
"handlers": ["console"],
|
||||||
@ -29,14 +29,14 @@ CONFIG_DEFAULTS = dict(
|
|||||||
"qualname": "gunicorn.error"
|
"qualname": "gunicorn.error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handlers = {
|
handlers={
|
||||||
"console": {
|
"console": {
|
||||||
"class": "logging.StreamHandler",
|
"class": "logging.StreamHandler",
|
||||||
"formatter": "generic",
|
"formatter": "generic",
|
||||||
"stream": "sys.stdout"
|
"stream": "sys.stdout"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
formatters = {
|
formatters={
|
||||||
"generic": {
|
"generic": {
|
||||||
"format": "%(asctime)s [%(process)d] [%(levelname)s] %(message)s",
|
"format": "%(asctime)s [%(process)d] [%(levelname)s] %(message)s",
|
||||||
"datefmt": "%Y-%m-%d %H:%M:%S",
|
"datefmt": "%Y-%m-%d %H:%M:%S",
|
||||||
@ -45,12 +45,14 @@ CONFIG_DEFAULTS = dict(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def loggers():
|
def loggers():
|
||||||
""" get list of all loggers """
|
""" get list of all loggers """
|
||||||
root = logging.root
|
root = logging.root
|
||||||
existing = root.manager.loggerDict.keys()
|
existing = root.manager.loggerDict.keys()
|
||||||
return [logging.getLogger(name) for name in existing]
|
return [logging.getLogger(name) for name in existing]
|
||||||
|
|
||||||
|
|
||||||
class LazyWriter(object):
|
class LazyWriter(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -100,6 +102,7 @@ class LazyWriter(object):
|
|||||||
def isatty(self):
|
def isatty(self):
|
||||||
return bool(self.fileobj and self.fileobj.isatty())
|
return bool(self.fileobj and self.fileobj.isatty())
|
||||||
|
|
||||||
|
|
||||||
class SafeAtoms(dict):
|
class SafeAtoms(dict):
|
||||||
|
|
||||||
def __init__(self, atoms):
|
def __init__(self, atoms):
|
||||||
@ -149,7 +152,6 @@ class Logger(object):
|
|||||||
self.error_log.setLevel(loglevel)
|
self.error_log.setLevel(loglevel)
|
||||||
self.access_log.setLevel(logging.INFO)
|
self.access_log.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
if cfg.errorlog != "-":
|
if cfg.errorlog != "-":
|
||||||
# if an error log file is set redirect stdout & stderr to
|
# if an error log file is set redirect stdout & stderr to
|
||||||
# this log file.
|
# this log file.
|
||||||
@ -170,7 +172,6 @@ class Logger(object):
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError("Error: log config '%s' not found" % cfg.logconfig)
|
raise RuntimeError("Error: log config '%s' not found" % cfg.logconfig)
|
||||||
|
|
||||||
|
|
||||||
def critical(self, msg, *args, **kwargs):
|
def critical(self, msg, *args, **kwargs):
|
||||||
self.error_log.critical(msg, *args, **kwargs)
|
self.error_log.critical(msg, *args, **kwargs)
|
||||||
|
|
||||||
@ -206,7 +207,7 @@ class Logger(object):
|
|||||||
atoms = {
|
atoms = {
|
||||||
'h': environ.get('REMOTE_ADDR', '-'),
|
'h': environ.get('REMOTE_ADDR', '-'),
|
||||||
'l': '-',
|
'l': '-',
|
||||||
'u': '-', # would be cool to get username from basic auth header
|
'u': '-', # would be cool to get username from basic auth header
|
||||||
't': self.now(),
|
't': self.now(),
|
||||||
'r': "%s %s %s" % (environ['REQUEST_METHOD'],
|
'r': "%s %s %s" % (environ['REQUEST_METHOD'],
|
||||||
environ['RAW_URI'], environ["SERVER_PROTOCOL"]),
|
environ['RAW_URI'], environ["SERVER_PROTOCOL"]),
|
||||||
@ -225,10 +226,10 @@ class Logger(object):
|
|||||||
else:
|
else:
|
||||||
req_headers = req
|
req_headers = req
|
||||||
|
|
||||||
atoms.update(dict([("{%s}i" % k.lower(),v) for k, v in req_headers]))
|
atoms.update(dict([("{%s}i" % k.lower(), v) for k, v in req_headers]))
|
||||||
|
|
||||||
# add response headers
|
# add response headers
|
||||||
atoms.update(dict([("{%s}o" % k.lower(),v) for k, v in resp.headers]))
|
atoms.update(dict([("{%s}o" % k.lower(), v) for k, v in resp.headers]))
|
||||||
|
|
||||||
# wrap atoms:
|
# wrap atoms:
|
||||||
# - make sure atoms will be test case insensitively
|
# - make sure atoms will be test case insensitively
|
||||||
@ -247,7 +248,6 @@ class Logger(object):
|
|||||||
return '[%02d/%s/%04d:%02d:%02d:%02d]' % (now.day, month,
|
return '[%02d/%s/%04d:%02d:%02d:%02d]' % (now.day, month,
|
||||||
now.year, now.hour, now.minute, now.second)
|
now.year, now.hour, now.minute, now.second)
|
||||||
|
|
||||||
|
|
||||||
def reopen_files(self):
|
def reopen_files(self):
|
||||||
if self.cfg.errorlog != "-":
|
if self.cfg.errorlog != "-":
|
||||||
# Close stderr & stdout if they are redirected to error log file
|
# Close stderr & stdout if they are redirected to error log file
|
||||||
@ -276,7 +276,6 @@ class Logger(object):
|
|||||||
finally:
|
finally:
|
||||||
handler.release()
|
handler.release()
|
||||||
|
|
||||||
|
|
||||||
def _get_gunicorn_handler(self, log):
|
def _get_gunicorn_handler(self, log):
|
||||||
for h in log.handlers:
|
for h in log.handlers:
|
||||||
if getattr(h, "_gunicorn", False) == True:
|
if getattr(h, "_gunicorn", False) == True:
|
||||||
@ -297,4 +296,3 @@ class Logger(object):
|
|||||||
h.setFormatter(fmt)
|
h.setFormatter(fmt)
|
||||||
h._gunicorn = True
|
h._gunicorn = True
|
||||||
log.addHandler(h)
|
log.addHandler(h)
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
# -*- coding: utf-8 -
|
# -*- coding: utf-8 -
|
||||||
#
|
#
|
||||||
# This file is part of gunicorn released under the MIT license.
|
# This file is part of gunicorn released under the MIT license.
|
||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
|
|
||||||
from gunicorn.http.message import Message, Request
|
from gunicorn.http.message import Message, Request
|
||||||
from gunicorn.http.parser import RequestParser
|
from gunicorn.http.parser import RequestParser
|
||||||
|
|
||||||
__all__ = [Message, Request, RequestParser]
|
__all__ = [Message, Request, RequestParser]
|
||||||
|
|||||||
@ -28,6 +28,7 @@ if sys.version_info < (2, 6) or \
|
|||||||
_libc = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True)
|
_libc = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True)
|
||||||
_sendfile = _libc.sendfile
|
_sendfile = _libc.sendfile
|
||||||
|
|
||||||
|
|
||||||
def sendfile(fdout, fdin, offset, nbytes):
|
def sendfile(fdout, fdin, offset, nbytes):
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
_sendfile.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_uint64,
|
_sendfile.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_uint64,
|
||||||
|
|||||||
@ -3,12 +3,11 @@
|
|||||||
# This file is part of gunicorn released under the MIT license.
|
# This file is part of gunicorn released under the MIT license.
|
||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from gunicorn.http.errors import (NoMoreData, ChunkMissingTerminator,
|
from gunicorn.http.errors import (NoMoreData, ChunkMissingTerminator,
|
||||||
InvalidChunkSize)
|
InvalidChunkSize)
|
||||||
from gunicorn import six
|
from gunicorn import six
|
||||||
|
|
||||||
|
|
||||||
class ChunkedReader(object):
|
class ChunkedReader(object):
|
||||||
def __init__(self, req, unreader):
|
def __init__(self, req, unreader):
|
||||||
self.req = req
|
self.req = req
|
||||||
@ -51,7 +50,7 @@ class ChunkedReader(object):
|
|||||||
unreader.unread(buf.getvalue()[2:])
|
unreader.unread(buf.getvalue()[2:])
|
||||||
return b""
|
return b""
|
||||||
self.req.trailers = self.req.parse_headers(buf.getvalue()[:idx])
|
self.req.trailers = self.req.parse_headers(buf.getvalue()[:idx])
|
||||||
unreader.unread(buf.getvalue()[idx+4:])
|
unreader.unread(buf.getvalue()[idx + 4:])
|
||||||
|
|
||||||
def parse_chunked(self, unreader):
|
def parse_chunked(self, unreader):
|
||||||
(size, rest) = self.parse_chunk_size(unreader)
|
(size, rest) = self.parse_chunk_size(unreader)
|
||||||
@ -82,7 +81,7 @@ class ChunkedReader(object):
|
|||||||
idx = buf.getvalue().find(b"\r\n")
|
idx = buf.getvalue().find(b"\r\n")
|
||||||
|
|
||||||
data = buf.getvalue()
|
data = buf.getvalue()
|
||||||
line, rest_chunk = data[:idx], data[idx+2:]
|
line, rest_chunk = data[:idx], data[idx + 2:]
|
||||||
|
|
||||||
chunk_size = line.split(b";", 1)[0].strip()
|
chunk_size = line.split(b";", 1)[0].strip()
|
||||||
try:
|
try:
|
||||||
@ -104,6 +103,7 @@ class ChunkedReader(object):
|
|||||||
raise NoMoreData()
|
raise NoMoreData()
|
||||||
buf.write(data)
|
buf.write(data)
|
||||||
|
|
||||||
|
|
||||||
class LengthReader(object):
|
class LengthReader(object):
|
||||||
def __init__(self, unreader, length):
|
def __init__(self, unreader, length):
|
||||||
self.unreader = unreader
|
self.unreader = unreader
|
||||||
@ -119,7 +119,6 @@ class LengthReader(object):
|
|||||||
if size == 0:
|
if size == 0:
|
||||||
return b""
|
return b""
|
||||||
|
|
||||||
|
|
||||||
buf = six.BytesIO()
|
buf = six.BytesIO()
|
||||||
data = self.unreader.read()
|
data = self.unreader.read()
|
||||||
while data:
|
while data:
|
||||||
@ -134,6 +133,7 @@ class LengthReader(object):
|
|||||||
self.length -= size
|
self.length -= size
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class EOFReader(object):
|
class EOFReader(object):
|
||||||
def __init__(self, unreader):
|
def __init__(self, unreader):
|
||||||
self.unreader = unreader
|
self.unreader = unreader
|
||||||
@ -171,6 +171,7 @@ class EOFReader(object):
|
|||||||
self.buf.write(rest)
|
self.buf.write(rest)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class Body(object):
|
class Body(object):
|
||||||
def __init__(self, reader):
|
def __init__(self, reader):
|
||||||
self.reader = reader
|
self.reader = reader
|
||||||
@ -233,8 +234,8 @@ class Body(object):
|
|||||||
|
|
||||||
idx = line.find(b"\n")
|
idx = line.find(b"\n")
|
||||||
if idx >= 0:
|
if idx >= 0:
|
||||||
ret = line[:idx+1]
|
ret = line[:idx + 1]
|
||||||
self.buf.write(line[idx+1:])
|
self.buf.write(line[idx + 1:])
|
||||||
self.buf.write(extra_buf_data)
|
self.buf.write(extra_buf_data)
|
||||||
return ret
|
return ret
|
||||||
self.buf.write(extra_buf_data)
|
self.buf.write(extra_buf_data)
|
||||||
@ -249,6 +250,6 @@ class Body(object):
|
|||||||
ret.append(data)
|
ret.append(data)
|
||||||
data = b""
|
data = b""
|
||||||
else:
|
else:
|
||||||
line, data = data[:pos+1], data[pos+1:]
|
line, data = data[:pos + 1], data[pos + 1:]
|
||||||
ret.append(line)
|
ret.append(line)
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
@ -3,9 +3,11 @@
|
|||||||
# This file is part of gunicorn released under the MIT license.
|
# This file is part of gunicorn released under the MIT license.
|
||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
|
|
||||||
|
|
||||||
class ParseException(Exception):
|
class ParseException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class NoMoreData(IOError):
|
class NoMoreData(IOError):
|
||||||
def __init__(self, buf=None):
|
def __init__(self, buf=None):
|
||||||
self.buf = buf
|
self.buf = buf
|
||||||
@ -13,6 +15,7 @@ class NoMoreData(IOError):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "No more data after: %r" % self.buf
|
return "No more data after: %r" % self.buf
|
||||||
|
|
||||||
|
|
||||||
class InvalidRequestLine(ParseException):
|
class InvalidRequestLine(ParseException):
|
||||||
def __init__(self, req):
|
def __init__(self, req):
|
||||||
self.req = req
|
self.req = req
|
||||||
@ -21,6 +24,7 @@ class InvalidRequestLine(ParseException):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Invalid HTTP request line: %r" % self.req
|
return "Invalid HTTP request line: %r" % self.req
|
||||||
|
|
||||||
|
|
||||||
class InvalidRequestMethod(ParseException):
|
class InvalidRequestMethod(ParseException):
|
||||||
def __init__(self, method):
|
def __init__(self, method):
|
||||||
self.method = method
|
self.method = method
|
||||||
@ -28,6 +32,7 @@ class InvalidRequestMethod(ParseException):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Invalid HTTP method: %r" % self.method
|
return "Invalid HTTP method: %r" % self.method
|
||||||
|
|
||||||
|
|
||||||
class InvalidHTTPVersion(ParseException):
|
class InvalidHTTPVersion(ParseException):
|
||||||
def __init__(self, version):
|
def __init__(self, version):
|
||||||
self.version = version
|
self.version = version
|
||||||
@ -35,6 +40,7 @@ class InvalidHTTPVersion(ParseException):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Invalid HTTP Version: %s" % self.version
|
return "Invalid HTTP Version: %s" % self.version
|
||||||
|
|
||||||
|
|
||||||
class InvalidHeader(ParseException):
|
class InvalidHeader(ParseException):
|
||||||
def __init__(self, hdr, req=None):
|
def __init__(self, hdr, req=None):
|
||||||
self.hdr = hdr
|
self.hdr = hdr
|
||||||
@ -43,6 +49,7 @@ class InvalidHeader(ParseException):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Invalid HTTP Header: %s" % self.hdr
|
return "Invalid HTTP Header: %s" % self.hdr
|
||||||
|
|
||||||
|
|
||||||
class InvalidHeaderName(ParseException):
|
class InvalidHeaderName(ParseException):
|
||||||
def __init__(self, hdr):
|
def __init__(self, hdr):
|
||||||
self.hdr = hdr
|
self.hdr = hdr
|
||||||
@ -50,6 +57,7 @@ class InvalidHeaderName(ParseException):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Invalid HTTP header name: %s" % self.hdr
|
return "Invalid HTTP header name: %s" % self.hdr
|
||||||
|
|
||||||
|
|
||||||
class InvalidChunkSize(IOError):
|
class InvalidChunkSize(IOError):
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
self.data = data
|
self.data = data
|
||||||
@ -57,6 +65,7 @@ class InvalidChunkSize(IOError):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Invalid chunk size: %r" % self.data
|
return "Invalid chunk size: %r" % self.data
|
||||||
|
|
||||||
|
|
||||||
class ChunkMissingTerminator(IOError):
|
class ChunkMissingTerminator(IOError):
|
||||||
def __init__(self, term):
|
def __init__(self, term):
|
||||||
self.term = term
|
self.term = term
|
||||||
@ -73,6 +82,7 @@ class LimitRequestLine(ParseException):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Request Line is too large (%s > %s)" % (self.size, self.max_size)
|
return "Request Line is too large (%s > %s)" % (self.size, self.max_size)
|
||||||
|
|
||||||
|
|
||||||
class LimitRequestHeaders(ParseException):
|
class LimitRequestHeaders(ParseException):
|
||||||
def __init__(self, msg):
|
def __init__(self, msg):
|
||||||
self.msg = msg
|
self.msg = msg
|
||||||
|
|||||||
@ -19,6 +19,7 @@ MAX_REQUEST_LINE = 8190
|
|||||||
MAX_HEADERS = 32768
|
MAX_HEADERS = 32768
|
||||||
MAX_HEADERFIELD_SIZE = 8190
|
MAX_HEADERFIELD_SIZE = 8190
|
||||||
|
|
||||||
|
|
||||||
class Message(object):
|
class Message(object):
|
||||||
def __init__(self, cfg, unreader):
|
def __init__(self, cfg, unreader):
|
||||||
self.cfg = cfg
|
self.cfg = cfg
|
||||||
@ -150,7 +151,6 @@ class Request(Message):
|
|||||||
self.proxy_protocol_info = None
|
self.proxy_protocol_info = None
|
||||||
super(Request, self).__init__(cfg, unreader)
|
super(Request, self).__init__(cfg, unreader)
|
||||||
|
|
||||||
|
|
||||||
def get_data(self, unreader, buf, stop=False):
|
def get_data(self, unreader, buf, stop=False):
|
||||||
data = unreader.read()
|
data = unreader.read()
|
||||||
if not data:
|
if not data:
|
||||||
@ -200,7 +200,7 @@ class Request(Message):
|
|||||||
|
|
||||||
self.headers = self.parse_headers(data[:idx])
|
self.headers = self.parse_headers(data[:idx])
|
||||||
|
|
||||||
ret = data[idx+4:]
|
ret = data[idx + 4:]
|
||||||
buf = BytesIO()
|
buf = BytesIO()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -220,8 +220,8 @@ class Request(Message):
|
|||||||
if len(data) - 2 > limit > 0:
|
if len(data) - 2 > limit > 0:
|
||||||
raise LimitRequestLine(len(data), limit)
|
raise LimitRequestLine(len(data), limit)
|
||||||
|
|
||||||
return (data[:idx], # request line,
|
return (data[:idx], # request line,
|
||||||
data[idx + 2:]) # residue in the buffer, skip \r\n
|
data[idx + 2:]) # residue in the buffer, skip \r\n
|
||||||
|
|
||||||
def proxy_protocol(self, line):
|
def proxy_protocol(self, line):
|
||||||
"""\
|
"""\
|
||||||
@ -337,5 +337,3 @@ class Request(Message):
|
|||||||
super(Request, self).set_body_reader()
|
super(Request, self).set_body_reader()
|
||||||
if isinstance(self.body.reader, EOFReader):
|
if isinstance(self.body.reader, EOFReader):
|
||||||
self.body = Body(LengthReader(self.unreader, 0))
|
self.body = Body(LengthReader(self.unreader, 0))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
from gunicorn.http.message import Request
|
from gunicorn.http.message import Request
|
||||||
from gunicorn.http.unreader import SocketUnreader, IterUnreader
|
from gunicorn.http.unreader import SocketUnreader, IterUnreader
|
||||||
|
|
||||||
|
|
||||||
class Parser(object):
|
class Parser(object):
|
||||||
def __init__(self, mesg_class, cfg, source):
|
def __init__(self, mesg_class, cfg, source):
|
||||||
self.mesg_class = mesg_class
|
self.mesg_class = mesg_class
|
||||||
@ -33,7 +34,6 @@ class Parser(object):
|
|||||||
while data:
|
while data:
|
||||||
data = self.mesg.body.read(8192)
|
data = self.mesg.body.read(8192)
|
||||||
|
|
||||||
|
|
||||||
# Parse the next request
|
# Parse the next request
|
||||||
self.req_count += 1
|
self.req_count += 1
|
||||||
self.mesg = self.mesg_class(self.cfg, self.unreader, self.req_count)
|
self.mesg = self.mesg_class(self.cfg, self.unreader, self.req_count)
|
||||||
@ -43,7 +43,7 @@ class Parser(object):
|
|||||||
|
|
||||||
next = __next__
|
next = __next__
|
||||||
|
|
||||||
|
|
||||||
class RequestParser(Parser):
|
class RequestParser(Parser):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(RequestParser, self).__init__(Request, *args, **kwargs)
|
super(RequestParser, self).__init__(Request, *args, **kwargs)
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ from gunicorn import six
|
|||||||
# Classes that can undo reading data from
|
# Classes that can undo reading data from
|
||||||
# a given type of data source.
|
# a given type of data source.
|
||||||
|
|
||||||
|
|
||||||
class Unreader(object):
|
class Unreader(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.buf = six.BytesIO()
|
self.buf = six.BytesIO()
|
||||||
@ -34,7 +35,7 @@ class Unreader(object):
|
|||||||
self.buf = six.BytesIO()
|
self.buf = six.BytesIO()
|
||||||
return ret
|
return ret
|
||||||
if size is None:
|
if size is None:
|
||||||
d = self.chunk()
|
d = self.chunk()
|
||||||
return d
|
return d
|
||||||
|
|
||||||
while self.buf.tell() < size:
|
while self.buf.tell() < size:
|
||||||
@ -53,6 +54,7 @@ class Unreader(object):
|
|||||||
self.buf.seek(0, os.SEEK_END)
|
self.buf.seek(0, os.SEEK_END)
|
||||||
self.buf.write(data)
|
self.buf.write(data)
|
||||||
|
|
||||||
|
|
||||||
class SocketUnreader(Unreader):
|
class SocketUnreader(Unreader):
|
||||||
def __init__(self, sock, max_chunk=8192):
|
def __init__(self, sock, max_chunk=8192):
|
||||||
super(SocketUnreader, self).__init__()
|
super(SocketUnreader, self).__init__()
|
||||||
@ -62,6 +64,7 @@ class SocketUnreader(Unreader):
|
|||||||
def chunk(self):
|
def chunk(self):
|
||||||
return self.sock.recv(self.mxchunk)
|
return self.sock.recv(self.mxchunk)
|
||||||
|
|
||||||
|
|
||||||
class IterUnreader(Unreader):
|
class IterUnreader(Unreader):
|
||||||
def __init__(self, iterable):
|
def __init__(self, iterable):
|
||||||
super(IterUnreader, self).__init__()
|
super(IterUnreader, self).__init__()
|
||||||
|
|||||||
@ -26,6 +26,7 @@ NORMALIZE_SPACE = re.compile(r'(?:\r\n)?[ \t]+')
|
|||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class FileWrapper:
|
class FileWrapper:
|
||||||
|
|
||||||
def __init__(self, filelike, blksize=8192):
|
def __init__(self, filelike, blksize=8192):
|
||||||
@ -58,6 +59,7 @@ def default_environ(req, sock, cfg):
|
|||||||
"SERVER_PROTOCOL": "HTTP/%s" % ".".join([str(v) for v in req.version])
|
"SERVER_PROTOCOL": "HTTP/%s" % ".".join([str(v) for v in req.version])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def proxy_environ(req):
|
def proxy_environ(req):
|
||||||
info = req.proxy_protocol_info
|
info = req.proxy_protocol_info
|
||||||
|
|
||||||
@ -72,6 +74,7 @@ def proxy_environ(req):
|
|||||||
"PROXY_PORT": str(info["proxy_port"]),
|
"PROXY_PORT": str(info["proxy_port"]),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def create(req, sock, client, server, cfg):
|
def create(req, sock, client, server, cfg):
|
||||||
resp = Response(req, sock)
|
resp = Response(req, sock)
|
||||||
|
|
||||||
@ -127,7 +130,7 @@ def create(req, sock, client, server, cfg):
|
|||||||
|
|
||||||
# find host and port on ipv6 address
|
# find host and port on ipv6 address
|
||||||
if '[' in forward and ']' in forward:
|
if '[' in forward and ']' in forward:
|
||||||
host = forward.split(']')[0][1:].lower()
|
host = forward.split(']')[0][1:].lower()
|
||||||
elif ":" in forward and forward.count(":") == 1:
|
elif ":" in forward and forward.count(":") == 1:
|
||||||
host = forward.split(":")[0].lower()
|
host = forward.split(":")[0].lower()
|
||||||
else:
|
else:
|
||||||
@ -147,7 +150,7 @@ def create(req, sock, client, server, cfg):
|
|||||||
environ['REMOTE_PORT'] = str(remote[1])
|
environ['REMOTE_PORT'] = str(remote[1])
|
||||||
|
|
||||||
if isinstance(server, string_types):
|
if isinstance(server, string_types):
|
||||||
server = server.split(":")
|
server = server.split(":")
|
||||||
if len(server) == 1:
|
if len(server) == 1:
|
||||||
if url_scheme == "http":
|
if url_scheme == "http":
|
||||||
server.append("80")
|
server.append("80")
|
||||||
@ -168,6 +171,7 @@ def create(req, sock, client, server, cfg):
|
|||||||
|
|
||||||
return resp, environ
|
return resp, environ
|
||||||
|
|
||||||
|
|
||||||
class Response(object):
|
class Response(object):
|
||||||
|
|
||||||
def __init__(self, req, sock):
|
def __init__(self, req, sock):
|
||||||
@ -229,14 +233,13 @@ class Response(object):
|
|||||||
continue
|
continue
|
||||||
self.headers.append((name.strip(), value))
|
self.headers.append((name.strip(), value))
|
||||||
|
|
||||||
|
|
||||||
def is_chunked(self):
|
def is_chunked(self):
|
||||||
# Only use chunked responses when the client is
|
# Only use chunked responses when the client is
|
||||||
# speaking HTTP/1.1 or newer and there was
|
# speaking HTTP/1.1 or newer and there was
|
||||||
# no Content-Length header set.
|
# no Content-Length header set.
|
||||||
if self.response_length is not None:
|
if self.response_length is not None:
|
||||||
return False
|
return False
|
||||||
elif self.req.version <= (1,0):
|
elif self.req.version <= (1, 0):
|
||||||
return False
|
return False
|
||||||
elif self.status.startswith("304") or self.status.startswith("204"):
|
elif self.status.startswith("304") or self.status.startswith("204"):
|
||||||
# Do not use chunked responses when the response is guaranteed to
|
# Do not use chunked responses when the response is guaranteed to
|
||||||
@ -268,7 +271,7 @@ class Response(object):
|
|||||||
if self.headers_sent:
|
if self.headers_sent:
|
||||||
return
|
return
|
||||||
tosend = self.default_headers()
|
tosend = self.default_headers()
|
||||||
tosend.extend(["%s: %s\r\n" % (k,v) for k, v in self.headers])
|
tosend.extend(["%s: %s\r\n" % (k, v) for k, v in self.headers])
|
||||||
|
|
||||||
header_str = "%s\r\n" % "".join(tosend)
|
header_str = "%s\r\n" % "".join(tosend)
|
||||||
util.write(self.sock, util.to_bytestring(header_str))
|
util.write(self.sock, util.to_bytestring(header_str))
|
||||||
@ -315,9 +318,9 @@ class Response(object):
|
|||||||
nbytes -= BLKSIZE
|
nbytes -= BLKSIZE
|
||||||
else:
|
else:
|
||||||
sent = 0
|
sent = 0
|
||||||
sent += sendfile(sockno, fileno, offset+sent, nbytes-sent)
|
sent += sendfile(sockno, fileno, offset + sent, nbytes - sent)
|
||||||
while sent != nbytes:
|
while sent != nbytes:
|
||||||
sent += sendfile(sockno, fileno, offset+sent, nbytes-sent)
|
sent += sendfile(sockno, fileno, offset + sent, nbytes - sent)
|
||||||
|
|
||||||
def write_file(self, respiter):
|
def write_file(self, respiter):
|
||||||
if sendfile is not None and \
|
if sendfile is not None and \
|
||||||
|
|||||||
@ -45,6 +45,7 @@ def make_options():
|
|||||||
g_settings = make_settings(ignore=("version"))
|
g_settings = make_settings(ignore=("version"))
|
||||||
|
|
||||||
keys = g_settings.keys()
|
keys = g_settings.keys()
|
||||||
|
|
||||||
def sorter(k):
|
def sorter(k):
|
||||||
return (g_settings[k].section, g_settings[k].order)
|
return (g_settings[k].section, g_settings[k].order)
|
||||||
|
|
||||||
|
|||||||
@ -55,7 +55,7 @@ class Pidfile(object):
|
|||||||
""" delete pidfile"""
|
""" delete pidfile"""
|
||||||
try:
|
try:
|
||||||
with open(self.fname, "r") as f:
|
with open(self.fname, "r") as f:
|
||||||
pid1 = int(f.read() or 0)
|
pid1 = int(f.read() or 0)
|
||||||
|
|
||||||
if pid1 == self.pid:
|
if pid1 == self.pid:
|
||||||
os.unlink(self.fname)
|
os.unlink(self.fname)
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import time
|
|||||||
from gunicorn import util
|
from gunicorn import util
|
||||||
from gunicorn.six import string_types
|
from gunicorn.six import string_types
|
||||||
|
|
||||||
|
|
||||||
class BaseSocket(object):
|
class BaseSocket(object):
|
||||||
|
|
||||||
def __init__(self, address, conf, log, fd=None):
|
def __init__(self, address, conf, log, fd=None):
|
||||||
@ -50,6 +51,7 @@ class BaseSocket(object):
|
|||||||
time.sleep(0.3)
|
time.sleep(0.3)
|
||||||
del self.sock
|
del self.sock
|
||||||
|
|
||||||
|
|
||||||
class TCPSocket(BaseSocket):
|
class TCPSocket(BaseSocket):
|
||||||
|
|
||||||
FAMILY = socket.AF_INET
|
FAMILY = socket.AF_INET
|
||||||
@ -60,13 +62,14 @@ class TCPSocket(BaseSocket):
|
|||||||
else:
|
else:
|
||||||
scheme = "http"
|
scheme = "http"
|
||||||
|
|
||||||
addr = self.sock.getsockname()
|
addr = self.sock.getsockname()
|
||||||
return "%s://%s:%d" % (scheme, addr[0], addr[1])
|
return "%s://%s:%d" % (scheme, addr[0], addr[1])
|
||||||
|
|
||||||
def set_options(self, sock, bound=False):
|
def set_options(self, sock, bound=False):
|
||||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||||
return super(TCPSocket, self).set_options(sock, bound=bound)
|
return super(TCPSocket, self).set_options(sock, bound=bound)
|
||||||
|
|
||||||
|
|
||||||
class TCP6Socket(TCPSocket):
|
class TCP6Socket(TCPSocket):
|
||||||
|
|
||||||
FAMILY = socket.AF_INET6
|
FAMILY = socket.AF_INET6
|
||||||
@ -75,6 +78,7 @@ class TCP6Socket(TCPSocket):
|
|||||||
(host, port, fl, sc) = self.sock.getsockname()
|
(host, port, fl, sc) = self.sock.getsockname()
|
||||||
return "http://[%s]:%d" % (host, port)
|
return "http://[%s]:%d" % (host, port)
|
||||||
|
|
||||||
|
|
||||||
class UnixSocket(BaseSocket):
|
class UnixSocket(BaseSocket):
|
||||||
|
|
||||||
FAMILY = socket.AF_UNIX
|
FAMILY = socket.AF_UNIX
|
||||||
@ -100,6 +104,7 @@ class UnixSocket(BaseSocket):
|
|||||||
super(UnixSocket, self).close()
|
super(UnixSocket, self).close()
|
||||||
os.unlink(self.cfg_addr)
|
os.unlink(self.cfg_addr)
|
||||||
|
|
||||||
|
|
||||||
def _sock_type(addr):
|
def _sock_type(addr):
|
||||||
if isinstance(addr, tuple):
|
if isinstance(addr, tuple):
|
||||||
if util.is_ipv6(addr[0]):
|
if util.is_ipv6(addr[0]):
|
||||||
@ -112,6 +117,7 @@ def _sock_type(addr):
|
|||||||
raise TypeError("Unable to create socket from: %r" % addr)
|
raise TypeError("Unable to create socket from: %r" % addr)
|
||||||
return sock_type
|
return sock_type
|
||||||
|
|
||||||
|
|
||||||
def create_sockets(conf, log):
|
def create_sockets(conf, log):
|
||||||
"""
|
"""
|
||||||
Create a new socket for the given address. If the
|
Create a new socket for the given address. If the
|
||||||
@ -158,7 +164,7 @@ def create_sockets(conf, log):
|
|||||||
sock = None
|
sock = None
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
try:
|
try:
|
||||||
sock = sock_type(addr, conf, log)
|
sock = sock_type(addr, conf, log)
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
if e.args[0] == errno.EADDRINUSE:
|
if e.args[0] == errno.EADDRINUSE:
|
||||||
log.error("Connection in use: %s", str(addr))
|
log.error("Connection in use: %s", str(addr))
|
||||||
|
|||||||
@ -24,14 +24,16 @@ import sys
|
|||||||
import textwrap
|
import textwrap
|
||||||
import time
|
import time
|
||||||
import inspect
|
import inspect
|
||||||
|
import errno
|
||||||
|
import warnings
|
||||||
|
|
||||||
from gunicorn.six import text_type, string_types
|
from gunicorn.six import text_type, string_types
|
||||||
|
|
||||||
MAXFD = 1024
|
MAXFD = 1024
|
||||||
if (hasattr(os, "devnull")):
|
if (hasattr(os, "devnull")):
|
||||||
REDIRECT_TO = os.devnull
|
REDIRECT_TO = os.devnull
|
||||||
else:
|
else:
|
||||||
REDIRECT_TO = "/dev/null"
|
REDIRECT_TO = "/dev/null"
|
||||||
|
|
||||||
timeout_default = object()
|
timeout_default = object()
|
||||||
|
|
||||||
@ -83,7 +85,6 @@ except ImportError:
|
|||||||
"package")
|
"package")
|
||||||
return "%s.%s" % (package[:dot], name)
|
return "%s.%s" % (package[:dot], name)
|
||||||
|
|
||||||
|
|
||||||
def import_module(name, package=None):
|
def import_module(name, package=None):
|
||||||
"""Import a module.
|
"""Import a module.
|
||||||
|
|
||||||
@ -104,6 +105,7 @@ relative import to an absolute import.
|
|||||||
__import__(name)
|
__import__(name)
|
||||||
return sys.modules[name]
|
return sys.modules[name]
|
||||||
|
|
||||||
|
|
||||||
def load_class(uri, default="sync", section="gunicorn.workers"):
|
def load_class(uri, default="sync", section="gunicorn.workers"):
|
||||||
if inspect.isclass(uri):
|
if inspect.isclass(uri):
|
||||||
return uri
|
return uri
|
||||||
@ -111,7 +113,7 @@ def load_class(uri, default="sync", section="gunicorn.workers"):
|
|||||||
# uses entry points
|
# uses entry points
|
||||||
entry_str = uri.split("egg:")[1]
|
entry_str = uri.split("egg:")[1]
|
||||||
try:
|
try:
|
||||||
dist, name = entry_str.rsplit("#",1)
|
dist, name = entry_str.rsplit("#", 1)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
dist = entry_str
|
dist = entry_str
|
||||||
name = default
|
name = default
|
||||||
@ -135,7 +137,8 @@ def load_class(uri, default="sync", section="gunicorn.workers"):
|
|||||||
mod = getattr(mod, comp)
|
mod = getattr(mod, comp)
|
||||||
return getattr(mod, klass)
|
return getattr(mod, klass)
|
||||||
|
|
||||||
def set_owner_process(uid,gid):
|
|
||||||
|
def set_owner_process(uid, gid):
|
||||||
""" set user and group of workers processes """
|
""" set user and group of workers processes """
|
||||||
if gid:
|
if gid:
|
||||||
try:
|
try:
|
||||||
@ -150,6 +153,7 @@ def set_owner_process(uid,gid):
|
|||||||
if uid:
|
if uid:
|
||||||
os.setuid(uid)
|
os.setuid(uid)
|
||||||
|
|
||||||
|
|
||||||
def chown(path, uid, gid):
|
def chown(path, uid, gid):
|
||||||
try:
|
try:
|
||||||
os.chown(path, uid, gid)
|
os.chown(path, uid, gid)
|
||||||
@ -198,6 +202,7 @@ if sys.platform.startswith("win"):
|
|||||||
else:
|
else:
|
||||||
_unlink = os.unlink
|
_unlink = os.unlink
|
||||||
|
|
||||||
|
|
||||||
def unlink(filename):
|
def unlink(filename):
|
||||||
try:
|
try:
|
||||||
_unlink(filename)
|
_unlink(filename)
|
||||||
@ -210,10 +215,11 @@ def unlink(filename):
|
|||||||
def is_ipv6(addr):
|
def is_ipv6(addr):
|
||||||
try:
|
try:
|
||||||
socket.inet_pton(socket.AF_INET6, addr)
|
socket.inet_pton(socket.AF_INET6, addr)
|
||||||
except socket.error: # not a valid address
|
except socket.error: # not a valid address
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def parse_address(netloc, default_port=8000):
|
def parse_address(netloc, default_port=8000):
|
||||||
if netloc.startswith("unix:"):
|
if netloc.startswith("unix:"):
|
||||||
return netloc.split("unix:")[1]
|
return netloc.split("unix:")[1]
|
||||||
@ -239,21 +245,25 @@ def parse_address(netloc, default_port=8000):
|
|||||||
port = default_port
|
port = default_port
|
||||||
return (host, port)
|
return (host, port)
|
||||||
|
|
||||||
|
|
||||||
def get_maxfd():
|
def get_maxfd():
|
||||||
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
|
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
|
||||||
if (maxfd == resource.RLIM_INFINITY):
|
if (maxfd == resource.RLIM_INFINITY):
|
||||||
maxfd = MAXFD
|
maxfd = MAXFD
|
||||||
return maxfd
|
return maxfd
|
||||||
|
|
||||||
|
|
||||||
def close_on_exec(fd):
|
def close_on_exec(fd):
|
||||||
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||||
flags |= fcntl.FD_CLOEXEC
|
flags |= fcntl.FD_CLOEXEC
|
||||||
fcntl.fcntl(fd, fcntl.F_SETFD, flags)
|
fcntl.fcntl(fd, fcntl.F_SETFD, flags)
|
||||||
|
|
||||||
|
|
||||||
def set_non_blocking(fd):
|
def set_non_blocking(fd):
|
||||||
flags = fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK
|
flags = fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK
|
||||||
fcntl.fcntl(fd, fcntl.F_SETFL, flags)
|
fcntl.fcntl(fd, fcntl.F_SETFL, flags)
|
||||||
|
|
||||||
|
|
||||||
def close(sock):
|
def close(sock):
|
||||||
try:
|
try:
|
||||||
sock.close()
|
sock.close()
|
||||||
@ -268,9 +278,10 @@ except ImportError:
|
|||||||
for fd in range(fd_low, fd_high):
|
for fd in range(fd_low, fd_high):
|
||||||
try:
|
try:
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
except OSError: # ERROR, fd wasn't open to begin with (ignored)
|
except OSError: # ERROR, fd wasn't open to begin with (ignored)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def write_chunk(sock, data):
|
def write_chunk(sock, data):
|
||||||
if isinstance(data, text_type):
|
if isinstance(data, text_type):
|
||||||
data = data.encode('utf-8')
|
data = data.encode('utf-8')
|
||||||
@ -278,11 +289,13 @@ def write_chunk(sock, data):
|
|||||||
chunk = b"".join([chunk_size.encode('utf-8'), data, b"\r\n"])
|
chunk = b"".join([chunk_size.encode('utf-8'), data, b"\r\n"])
|
||||||
sock.sendall(chunk)
|
sock.sendall(chunk)
|
||||||
|
|
||||||
|
|
||||||
def write(sock, data, chunked=False):
|
def write(sock, data, chunked=False):
|
||||||
if chunked:
|
if chunked:
|
||||||
return write_chunk(sock, data)
|
return write_chunk(sock, data)
|
||||||
sock.sendall(data)
|
sock.sendall(data)
|
||||||
|
|
||||||
|
|
||||||
def write_nonblock(sock, data, chunked=False):
|
def write_nonblock(sock, data, chunked=False):
|
||||||
timeout = sock.gettimeout()
|
timeout = sock.gettimeout()
|
||||||
if timeout != 0.0:
|
if timeout != 0.0:
|
||||||
@ -294,10 +307,12 @@ def write_nonblock(sock, data, chunked=False):
|
|||||||
else:
|
else:
|
||||||
return write(sock, data, chunked)
|
return write(sock, data, chunked)
|
||||||
|
|
||||||
|
|
||||||
def writelines(sock, lines, chunked=False):
|
def writelines(sock, lines, chunked=False):
|
||||||
for line in list(lines):
|
for line in list(lines):
|
||||||
write(sock, line, chunked)
|
write(sock, line, chunked)
|
||||||
|
|
||||||
|
|
||||||
def write_error(sock, status_int, reason, mesg):
|
def write_error(sock, status_int, reason, mesg):
|
||||||
html = textwrap.dedent("""\
|
html = textwrap.dedent("""\
|
||||||
<html>
|
<html>
|
||||||
@ -321,8 +336,10 @@ def write_error(sock, status_int, reason, mesg):
|
|||||||
""") % (str(status_int), reason, len(html), html)
|
""") % (str(status_int), reason, len(html), html)
|
||||||
write_nonblock(sock, http.encode('latin1'))
|
write_nonblock(sock, http.encode('latin1'))
|
||||||
|
|
||||||
|
|
||||||
def normalize_name(name):
|
def normalize_name(name):
|
||||||
return "-".join([w.lower().capitalize() for w in name.split("-")])
|
return "-".join([w.lower().capitalize() for w in name.split("-")])
|
||||||
|
|
||||||
|
|
||||||
def import_app(module):
|
def import_app(module):
|
||||||
parts = module.split(":", 1)
|
parts = module.split(":", 1)
|
||||||
@ -336,7 +353,7 @@ def import_app(module):
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
if module.endswith(".py") and os.path.exists(module):
|
if module.endswith(".py") and os.path.exists(module):
|
||||||
raise ImportError("Failed to find application, did "
|
raise ImportError("Failed to find application, did "
|
||||||
"you mean '%s:%s'?" % (module.rsplit(".",1)[0], obj))
|
"you mean '%s:%s'?" % (module.rsplit(".", 1)[0], obj))
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@ -348,6 +365,7 @@ def import_app(module):
|
|||||||
raise TypeError("Application object must be callable.")
|
raise TypeError("Application object must be callable.")
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
def http_date(timestamp=None):
|
def http_date(timestamp=None):
|
||||||
"""Return the current date and time formatted for a message header."""
|
"""Return the current date and time formatted for a message header."""
|
||||||
if timestamp is None:
|
if timestamp is None:
|
||||||
@ -359,9 +377,11 @@ def http_date(timestamp=None):
|
|||||||
hh, mm, ss)
|
hh, mm, ss)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def is_hoppish(header):
|
def is_hoppish(header):
|
||||||
return header.lower().strip() in hop_headers
|
return header.lower().strip() in hop_headers
|
||||||
|
|
||||||
|
|
||||||
def daemonize():
|
def daemonize():
|
||||||
"""\
|
"""\
|
||||||
Standard daemonization of a process.
|
Standard daemonization of a process.
|
||||||
@ -383,6 +403,7 @@ def daemonize():
|
|||||||
os.dup2(0, 1)
|
os.dup2(0, 1)
|
||||||
os.dup2(0, 2)
|
os.dup2(0, 2)
|
||||||
|
|
||||||
|
|
||||||
def seed():
|
def seed():
|
||||||
try:
|
try:
|
||||||
random.seed(os.urandom(64))
|
random.seed(os.urandom(64))
|
||||||
@ -397,6 +418,7 @@ def check_is_writeable(path):
|
|||||||
raise RuntimeError("Error: '%s' isn't writable [%r]" % (path, e))
|
raise RuntimeError("Error: '%s' isn't writable [%r]" % (path, e))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
def to_bytestring(value):
|
def to_bytestring(value):
|
||||||
"""Converts a string argument to a byte string"""
|
"""Converts a string argument to a byte string"""
|
||||||
if isinstance(value, bytes):
|
if isinstance(value, bytes):
|
||||||
|
|||||||
@ -16,6 +16,7 @@ from gunicorn import six
|
|||||||
|
|
||||||
ALREADY_HANDLED = object()
|
ALREADY_HANDLED = object()
|
||||||
|
|
||||||
|
|
||||||
class AsyncWorker(base.Worker):
|
class AsyncWorker(base.Worker):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@ -47,9 +48,9 @@ class AsyncWorker(base.Worker):
|
|||||||
except StopIteration as e:
|
except StopIteration as e:
|
||||||
self.log.debug("Closing connection. %s", e)
|
self.log.debug("Closing connection. %s", e)
|
||||||
except ssl.SSLError:
|
except ssl.SSLError:
|
||||||
raise # pass to next try-except level
|
raise # pass to next try-except level
|
||||||
except socket.error:
|
except socket.error:
|
||||||
raise # pass to next try-except level
|
raise # pass to next try-except level
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.handle_error(req, client, addr, e)
|
self.handle_error(req, client, addr, e)
|
||||||
except ssl.SSLError as e:
|
except ssl.SSLError as e:
|
||||||
@ -100,7 +101,7 @@ class AsyncWorker(base.Worker):
|
|||||||
self.log.access(resp, req, environ, request_time)
|
self.log.access(resp, req, environ, request_time)
|
||||||
finally:
|
finally:
|
||||||
if hasattr(respiter, "close"):
|
if hasattr(respiter, "close"):
|
||||||
respiter.close()
|
respiter.close()
|
||||||
if resp.should_close():
|
if resp.should_close():
|
||||||
raise StopIteration()
|
raise StopIteration()
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@ -19,6 +19,7 @@ from gunicorn.http.errors import InvalidProxyLine, ForbiddenProxyRequest
|
|||||||
from gunicorn.http.wsgi import default_environ, Response
|
from gunicorn.http.wsgi import default_environ, Response
|
||||||
from gunicorn.six import MAXSIZE
|
from gunicorn.six import MAXSIZE
|
||||||
|
|
||||||
|
|
||||||
class Worker(object):
|
class Worker(object):
|
||||||
|
|
||||||
SIGNALS = [getattr(signal, "SIG%s" % x) \
|
SIGNALS = [getattr(signal, "SIG%s" % x) \
|
||||||
@ -129,7 +130,7 @@ class Worker(object):
|
|||||||
|
|
||||||
def handle_error(self, req, client, addr, exc):
|
def handle_error(self, req, client, addr, exc):
|
||||||
request_start = datetime.now()
|
request_start = datetime.now()
|
||||||
addr = addr or ('', -1) # unix socket case
|
addr = addr or ('', -1) # unix socket case
|
||||||
if isinstance(exc, (InvalidRequestLine, InvalidRequestMethod,
|
if isinstance(exc, (InvalidRequestLine, InvalidRequestMethod,
|
||||||
InvalidHTTPVersion, InvalidHeader, InvalidHeaderName,
|
InvalidHTTPVersion, InvalidHeader, InvalidHeaderName,
|
||||||
LimitRequestLine, LimitRequestHeaders,
|
LimitRequestLine, LimitRequestHeaders,
|
||||||
@ -147,7 +148,7 @@ class Worker(object):
|
|||||||
elif isinstance(exc, (InvalidHeaderName, InvalidHeader,)):
|
elif isinstance(exc, (InvalidHeaderName, InvalidHeader,)):
|
||||||
mesg = "<p>%s</p>" % str(exc)
|
mesg = "<p>%s</p>" % str(exc)
|
||||||
if not req and hasattr(exc, "req"):
|
if not req and hasattr(exc, "req"):
|
||||||
req = exc.req # for access log
|
req = exc.req # for access log
|
||||||
elif isinstance(exc, LimitRequestLine):
|
elif isinstance(exc, LimitRequestLine):
|
||||||
mesg = "<p>%s</p>" % str(exc)
|
mesg = "<p>%s</p>" % str(exc)
|
||||||
elif isinstance(exc, LimitRequestHeaders):
|
elif isinstance(exc, LimitRequestHeaders):
|
||||||
|
|||||||
@ -15,12 +15,13 @@ from eventlet.greenio import GreenSocket
|
|||||||
|
|
||||||
from gunicorn.workers.async import AsyncWorker
|
from gunicorn.workers.async import AsyncWorker
|
||||||
|
|
||||||
|
|
||||||
class EventletWorker(AsyncWorker):
|
class EventletWorker(AsyncWorker):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup(cls):
|
def setup(cls):
|
||||||
import eventlet
|
import eventlet
|
||||||
if eventlet.version_info < (0,9,7):
|
if eventlet.version_info < (0, 9, 7):
|
||||||
raise RuntimeError("You need eventlet >= 0.9.7")
|
raise RuntimeError("You need eventlet >= 0.9.7")
|
||||||
eventlet.monkey_patch(os=False)
|
eventlet.monkey_patch(os=False)
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,7 @@ BASE_WSGI_ENV = {
|
|||||||
'wsgi.run_once': False
|
'wsgi.run_once': False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class GeventWorker(AsyncWorker):
|
class GeventWorker(AsyncWorker):
|
||||||
|
|
||||||
server_class = None
|
server_class = None
|
||||||
@ -52,7 +53,6 @@ class GeventWorker(AsyncWorker):
|
|||||||
def timeout_ctx(self):
|
def timeout_ctx(self):
|
||||||
return gevent.Timeout(self.cfg.keepalive, False)
|
return gevent.Timeout(self.cfg.keepalive, False)
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
servers = []
|
servers = []
|
||||||
ssl_args = {}
|
ssl_args = {}
|
||||||
@ -80,7 +80,7 @@ class GeventWorker(AsyncWorker):
|
|||||||
while self.alive:
|
while self.alive:
|
||||||
self.notify()
|
self.notify()
|
||||||
|
|
||||||
if pid == os.getpid() and self.ppid != os.getppid():
|
if pid == os.getpid() and self.ppid != os.getppid():
|
||||||
self.log.info("Parent changed, shutting down: %s", self)
|
self.log.info("Parent changed, shutting down: %s", self)
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -137,12 +137,12 @@ class GeventResponse(object):
|
|||||||
headers = None
|
headers = None
|
||||||
response_length = None
|
response_length = None
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, status, headers, clength):
|
def __init__(self, status, headers, clength):
|
||||||
self.status = status
|
self.status = status
|
||||||
self.headers = headers
|
self.headers = headers
|
||||||
self.response_length = clength
|
self.response_length = clength
|
||||||
|
|
||||||
|
|
||||||
class PyWSGIHandler(pywsgi.WSGIHandler):
|
class PyWSGIHandler(pywsgi.WSGIHandler):
|
||||||
|
|
||||||
def log_request(self):
|
def log_request(self):
|
||||||
@ -160,9 +160,11 @@ class PyWSGIHandler(pywsgi.WSGIHandler):
|
|||||||
env['RAW_URI'] = self.path
|
env['RAW_URI'] = self.path
|
||||||
return env
|
return env
|
||||||
|
|
||||||
|
|
||||||
class PyWSGIServer(pywsgi.WSGIServer):
|
class PyWSGIServer(pywsgi.WSGIServer):
|
||||||
base_env = BASE_WSGI_ENV
|
base_env = BASE_WSGI_ENV
|
||||||
|
|
||||||
|
|
||||||
class GeventPyWSGIWorker(GeventWorker):
|
class GeventPyWSGIWorker(GeventWorker):
|
||||||
"The Gevent StreamServer based workers."
|
"The Gevent StreamServer based workers."
|
||||||
server_class = PyWSGIServer
|
server_class = PyWSGIServer
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import gunicorn.util as util
|
|||||||
import gunicorn.workers.base as base
|
import gunicorn.workers.base as base
|
||||||
from gunicorn import six
|
from gunicorn import six
|
||||||
|
|
||||||
|
|
||||||
class SyncWorker(base.Worker):
|
class SyncWorker(base.Worker):
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import tempfile
|
|||||||
|
|
||||||
from gunicorn import util
|
from gunicorn import util
|
||||||
|
|
||||||
|
|
||||||
class WorkerTmp(object):
|
class WorkerTmp(object):
|
||||||
|
|
||||||
def __init__(self, cfg):
|
def __init__(self, cfg):
|
||||||
@ -30,7 +31,7 @@ class WorkerTmp(object):
|
|||||||
|
|
||||||
def notify(self):
|
def notify(self):
|
||||||
try:
|
try:
|
||||||
self.spinner = (self.spinner+1) % 2
|
self.spinner = (self.spinner + 1) % 2
|
||||||
os.fchmod(self._tmp.fileno(), self.spinner)
|
os.fchmod(self._tmp.fileno(), self.spinner)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# python < 2.6
|
# python < 2.6
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user