fix whitespaces

This commit is contained in:
benoitc 2012-02-19 11:27:46 +01:00
parent 8bf793d2e5
commit f168a21dae
28 changed files with 319 additions and 319 deletions

View File

@ -1,6 +1,6 @@
# -*- 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.
import errno import errno
@ -20,7 +20,7 @@ class Application(object):
An application interface for configuring and loading An application interface for configuring and loading
the various necessities for any given web framework. the various necessities for any given web framework.
""" """
def __init__(self, usage=None): def __init__(self, usage=None):
self.usage = usage self.usage = usage
self.cfg = None self.cfg = None
@ -35,23 +35,23 @@ class Application(object):
sys.stderr.write("\nError: %s\n" % str(e)) sys.stderr.write("\nError: %s\n" % str(e))
sys.stderr.flush() sys.stderr.flush()
sys.exit(1) sys.exit(1)
def load_config(self): def load_config(self):
# init configuration # init configuration
self.cfg = Config(self.usage) self.cfg = Config(self.usage)
# parse console args # parse console args
parser = self.cfg.parser() parser = self.cfg.parser()
opts, args = parser.parse_args() opts, args = parser.parse_args()
# optional settings from apps # optional settings from apps
cfg = self.init(parser, opts, args) cfg = self.init(parser, opts, args)
# Load up the any app specific configuration # Load up the any app specific configuration
if cfg and cfg is not None: if cfg and cfg is not None:
for k, v in cfg.items(): for k, v in cfg.items():
self.cfg.set(k.lower(), v) self.cfg.set(k.lower(), v)
# Load up the config file if its found. # Load up the config file if its found.
if opts.config and os.path.exists(opts.config): if opts.config and os.path.exists(opts.config):
cfg = { cfg = {
@ -67,7 +67,7 @@ class Application(object):
print "Failed to read config file: %s" % opts.config print "Failed to read config file: %s" % opts.config
traceback.print_exc() traceback.print_exc()
sys.exit(1) sys.exit(1)
for k, v in cfg.items(): for k, v in cfg.items():
# Ignore unknown names # Ignore unknown names
if k not in self.cfg.settings: if k not in self.cfg.settings:
@ -77,17 +77,17 @@ class Application(object):
except: except:
sys.stderr.write("Invalid value for %s: %s\n\n" % (k, v)) sys.stderr.write("Invalid value for %s: %s\n\n" % (k, v))
raise raise
# Lastly, update the configuration with any command line # Lastly, update the configuration with any command line
# settings. # settings.
for k, v in opts.__dict__.items(): for k, v in opts.__dict__.items():
if v is None: if v is None:
continue continue
self.cfg.set(k.lower(), v) self.cfg.set(k.lower(), v)
def init(self, parser, opts, args): def init(self, parser, opts, args):
raise NotImplementedError raise NotImplementedError
def load(self): def load(self):
raise NotImplementedError raise NotImplementedError
@ -95,12 +95,12 @@ class Application(object):
self.do_load_config() self.do_load_config()
if self.cfg.spew: if self.cfg.spew:
debug.spew() debug.spew()
def wsgi(self): def wsgi(self):
if self.callable is None: if self.callable is None:
self.callable = self.load() self.callable = self.load()
return self.callable return self.callable
def run(self): def run(self):
if self.cfg.spew: if self.cfg.spew:
debug.spew() debug.spew()
@ -111,11 +111,11 @@ class Application(object):
os.setpgrp() os.setpgrp()
except OSError, e: except OSError, e:
if e[0] != errno.EPERM: if e[0] != errno.EPERM:
raise raise
try: try:
Arbiter(self).run() Arbiter(self).run()
except RuntimeError, e: except RuntimeError, e:
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)

View File

@ -1,6 +1,6 @@
# -*- 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.
import imp import imp
@ -17,7 +17,7 @@ from gunicorn.app.base import Application
ENVIRONMENT_VARIABLE = 'DJANGO_SETTINGS_MODULE' ENVIRONMENT_VARIABLE = 'DJANGO_SETTINGS_MODULE'
class DjangoApplication(Application): class DjangoApplication(Application):
def init(self, parser, opts, args): def init(self, parser, opts, args):
self.global_settings_path = None self.global_settings_path = None
self.project_path = None self.project_path = None
@ -25,7 +25,7 @@ class DjangoApplication(Application):
self.global_settings_path = args[0] self.global_settings_path = args[0]
if not os.path.exists(os.path.abspath(args[0])): if not os.path.exists(os.path.abspath(args[0])):
self.no_settings(args[0]) self.no_settings(args[0])
def get_settings_modname(self): def get_settings_modname(self):
from django.conf import ENVIRONMENT_VARIABLE from django.conf import ENVIRONMENT_VARIABLE
@ -69,7 +69,7 @@ class DjangoApplication(Application):
os.pardir))) os.pardir)))
return settings_modname return settings_modname
def setup_environ(self, settings_modname): def setup_environ(self, settings_modname):
from django.core.management import setup_environ from django.core.management import setup_environ
@ -82,7 +82,7 @@ class DjangoApplication(Application):
path = os.path.dirname(os.path.abspath( path = os.path.dirname(os.path.abspath(
os.path.normpath(settings_mod.__file__))) os.path.normpath(settings_mod.__file__)))
sys.path.append(path) sys.path.append(path)
for part in parts[1:]: for part in parts[1:]:
settings_mod = getattr(settings_mod, part) settings_mod = getattr(settings_mod, part)
setup_environ(settings_mod) setup_environ(settings_mod)
except ImportError: except ImportError:
@ -101,9 +101,9 @@ class DjangoApplication(Application):
from django.conf import settings from django.conf import settings
from django.utils import translation from django.utils import translation
translation.activate(settings.LANGUAGE_CODE) translation.activate(settings.LANGUAGE_CODE)
def validate(self): def validate(self):
""" Validate models. This also ensures that all models are """ Validate models. This also ensures that all models are
imported in case of import-time side effects.""" imported in case of import-time side effects."""
from django.core.management.base import CommandError from django.core.management.base import CommandError
from django.core.management.validation import get_validation_errors from django.core.management.validation import get_validation_errors
@ -123,14 +123,14 @@ class DjangoApplication(Application):
def load(self): def load(self):
from django.core.handlers.wsgi import WSGIHandler from django.core.handlers.wsgi import WSGIHandler
self.setup_environ(self.get_settings_modname()) self.setup_environ(self.get_settings_modname())
self.validate() self.validate()
self.activate_translation() self.activate_translation()
return WSGIHandler() return WSGIHandler()
class DjangoApplicationCommand(DjangoApplication): class DjangoApplicationCommand(DjangoApplication):
def __init__(self, options, admin_media_path): def __init__(self, options, admin_media_path):
self.usage = None self.usage = None
self.cfg = None self.cfg = None
@ -139,16 +139,16 @@ class DjangoApplicationCommand(DjangoApplication):
self.admin_media_path = admin_media_path self.admin_media_path = admin_media_path
self.callable = None self.callable = None
self.project_path = None self.project_path = None
self.do_load_config() self.do_load_config()
for k, v in self.options.items(): for k, v in self.options.items():
if k.lower() in self.cfg.settings and v is not None: if k.lower() in self.cfg.settings and v is not None:
self.cfg.set(k.lower(), v) self.cfg.set(k.lower(), v)
def load_config(self): def load_config(self):
self.cfg = Config() self.cfg = Config()
if self.config_file and os.path.exists(self.config_file): if self.config_file and os.path.exists(self.config_file):
cfg = { cfg = {
"__builtins__": __builtins__, "__builtins__": __builtins__,
@ -164,7 +164,7 @@ class DjangoApplicationCommand(DjangoApplication):
print "Failed to read config file: %s" % self.config_file print "Failed to read config file: %s" % self.config_file
traceback.print_exc() traceback.print_exc()
sys.exit(1) sys.exit(1)
for k, v in cfg.items(): for k, v in cfg.items():
# Ignore unknown names # Ignore unknown names
if k not in self.cfg.settings: if k not in self.cfg.settings:
@ -174,7 +174,7 @@ class DjangoApplicationCommand(DjangoApplication):
except: except:
sys.stderr.write("Invalid value for %s: %s\n\n" % (k, v)) sys.stderr.write("Invalid value for %s: %s\n\n" % (k, v))
raise raise
for k, v in self.options.items(): for k, v in self.options.items():
if k.lower() in self.cfg.settings and v is not None: if k.lower() in self.cfg.settings and v is not None:
self.cfg.set(k.lower(), v) self.cfg.set(k.lower(), v)
@ -191,7 +191,7 @@ class DjangoApplicationCommand(DjangoApplication):
settings_path = os.path.join(project_path, "settings.py") settings_path = os.path.join(project_path, "settings.py")
if not os.path.exists(settings_path): if not os.path.exists(settings_path):
return self.no_settings(settings_path) return self.no_settings(settings_path)
if not settings_modname: if not settings_modname:
project_name = os.path.split(project_path)[-1] project_name = os.path.split(project_path)[-1]
settings_name, ext = os.path.splitext( settings_name, ext = os.path.splitext(
@ -220,7 +220,7 @@ class DjangoApplicationCommand(DjangoApplication):
def reload_django_settings(self, settings_modname): def reload_django_settings(self, settings_modname):
from django.conf import settings from django.conf import settings
from django.utils import importlib from django.utils import importlib
mod = importlib.import_module(settings_modname) mod = importlib.import_module(settings_modname)
# reload module # reload module
@ -283,14 +283,14 @@ class DjangoApplicationCommand(DjangoApplication):
def load(self): def load(self):
from django.core.handlers.wsgi import WSGIHandler from django.core.handlers.wsgi import WSGIHandler
# reload django settings and setup environ # reload django settings and setup environ
self.setup_environ(self.get_settings_modname()) self.setup_environ(self.get_settings_modname())
# validate models and activate translation # validate models and activate translation
self.validate() self.validate()
self.activate_translation() self.activate_translation()
from django.core.servers.basehttp import AdminMediaHandler, WSGIServerException from django.core.servers.basehttp import AdminMediaHandler, WSGIServerException
try: try:
@ -308,7 +308,7 @@ class DjangoApplicationCommand(DjangoApplication):
error_text = str(e) error_text = str(e)
sys.stderr.write(self.style.ERROR("Error: %s" % error_text) + '\n') sys.stderr.write(self.style.ERROR("Error: %s" % error_text) + '\n')
sys.exit(1) sys.exit(1)
def run(): def run():
"""\ """\
The ``gunicorn_django`` command line runner for launching Django The ``gunicorn_django`` command line runner for launching Django

View File

@ -1,6 +1,6 @@
# -*- 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.
import os import os
@ -20,7 +20,7 @@ class PasterBaseApplication(Application):
cx = loadwsgi.loadcontext(SERVER, self.cfgurl, relative_to=self.relpath) cx = loadwsgi.loadcontext(SERVER, self.cfgurl, relative_to=self.relpath)
gc, lc = cx.global_conf.copy(), cx.local_conf.copy() gc, lc = cx.global_conf.copy(), cx.local_conf.copy()
cfg = {} cfg = {}
host, port = lc.pop('host', ''), lc.pop('port', '') host, port = lc.pop('host', ''), lc.pop('port', '')
if host and port: if host and port:
cfg['bind'] = '%s:%s' % (host, port) cfg['bind'] = '%s:%s' % (host, port)
@ -61,11 +61,11 @@ class PasterBaseApplication(Application):
config_file = os.path.abspath(self.cfgfname) config_file = os.path.abspath(self.cfgfname)
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):
if len(args) != 1: if len(args) != 1:
parser.error("No application name specified.") parser.error("No application name specified.")
@ -81,14 +81,14 @@ class PasterApplication(PasterBaseApplication):
sys.path.insert(0, self.relpath) sys.path.insert(0, self.relpath)
pkg_resources.working_set.add_entry(self.relpath) pkg_resources.working_set.add_entry(self.relpath)
return self.app_config() return self.app_config()
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):
self.cfg = Config() self.cfg = Config()
self.app = app self.app = app
@ -127,7 +127,7 @@ class PasterServerApplication(PasterBaseApplication):
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:
@ -153,14 +153,14 @@ def 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.
Then entry point in your paster ini file should looks like this: Then entry point in your paster ini file should looks like this:
[server:main] [server:main]
use = egg:gunicorn#main use = egg:gunicorn#main
host = 127.0.0.1 host = 127.0.0.1
port = 5000 port = 5000
""" """
from gunicorn.app.pasterapp import PasterServerApplication from gunicorn.app.pasterapp import PasterServerApplication
PasterServerApplication(app, gcfg=gcfg, host=host, port=port, *args, **kwargs).run() PasterServerApplication(app, gcfg=gcfg, host=host, port=port, *args, **kwargs).run()

View File

@ -1,6 +1,6 @@
# -*- 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.
import os import os
@ -10,7 +10,7 @@ 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):
if len(args) != 1: if len(args) != 1:
parser.error("No application module specified.") parser.error("No application module specified.")
@ -29,4 +29,4 @@ def run():
generic WSGI applications. generic WSGI applications.
""" """
from gunicorn.app.wsgiapp import WSGIApplication from gunicorn.app.wsgiapp import WSGIApplication
WSGIApplication("%prog [OPTIONS] APP_MODULE").run() WSGIApplication("%prog [OPTIONS] APP_MODULE").run()

View File

@ -1,6 +1,6 @@
# -*- 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 __future__ import with_statement from __future__ import with_statement
@ -34,9 +34,9 @@ class Arbiter(object):
WORKER_BOOT_ERROR = 3 WORKER_BOOT_ERROR = 3
START_CTX = {} START_CTX = {}
LISTENER = None LISTENER = None
WORKERS = {} WORKERS = {}
PIPE = [] PIPE = []
# I love dynamic languages # I love dynamic languages
@ -49,17 +49,17 @@ class Arbiter(object):
(getattr(signal, name), name[3:].lower()) for name in dir(signal) (getattr(signal, name), name[3:].lower()) for name in dir(signal)
if name[:3] == "SIG" and name[3] != "_" if name[:3] == "SIG" and name[3] != "_"
) )
def __init__(self, app): def __init__(self, app):
os.environ["SERVER_SOFTWARE"] = SERVER_SOFTWARE os.environ["SERVER_SOFTWARE"] = SERVER_SOFTWARE
self.setup(app) self.setup(app)
self.pidfile = None self.pidfile = None
self.worker_age = 0 self.worker_age = 0
self.reexec_pid = 0 self.reexec_pid = 0
self.master_name = "Master" self.master_name = "Master"
# get current path, try to use PWD env first # get current path, try to use PWD env first
try: try:
a = os.stat(os.environ['PWD']) a = os.stat(os.environ['PWD'])
@ -70,7 +70,7 @@ class Arbiter(object):
cwd = os.getcwd() cwd = os.getcwd()
except: except:
cwd = os.getcwd() cwd = os.getcwd()
args = sys.argv[:] args = sys.argv[:]
args.insert(0, sys.executable) args.insert(0, sys.executable)
@ -80,27 +80,27 @@ class Arbiter(object):
"cwd": cwd, "cwd": cwd,
0: sys.executable 0: sys.executable
} }
def setup(self, app): def setup(self, app):
self.app = app self.app = app
self.cfg = app.cfg self.cfg = app.cfg
self.log = self.cfg.logger_class(app.cfg) self.log = self.cfg.logger_class(app.cfg)
if 'GUNICORN_FD' in os.environ: if 'GUNICORN_FD' in os.environ:
self.log.reopen_files() self.log.reopen_files()
self.address = self.cfg.address self.address = self.cfg.address
self.num_workers = self.cfg.workers self.num_workers = self.cfg.workers
self.debug = self.cfg.debug self.debug = self.cfg.debug
self.timeout = self.cfg.timeout self.timeout = self.cfg.timeout
self.proc_name = self.cfg.proc_name self.proc_name = self.cfg.proc_name
self.worker_class = self.cfg.worker_class self.worker_class = self.cfg.worker_class
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.iteritems()): for config, value in sorted(self.cfg.settings.iteritems()):
self.log.debug(" %s: %s", config, value.value) self.log.debug(" %s: %s", config, value.value)
if self.cfg.preload_app: if self.cfg.preload_app:
if not self.cfg.debug: if not self.cfg.debug:
self.app.wsgi() self.app.wsgi()
@ -117,7 +117,7 @@ class Arbiter(object):
self.init_signals() self.init_signals()
if not self.LISTENER: if not self.LISTENER:
self.LISTENER = create_socket(self.cfg, self.log) self.LISTENER = create_socket(self.cfg, self.log)
if self.cfg.pidfile is not None: if self.cfg.pidfile is not None:
self.pidfile = Pidfile(self.cfg.pidfile) self.pidfile = Pidfile(self.cfg.pidfile)
self.pidfile.create(self.pid) self.pidfile.create(self.pid)
@ -128,7 +128,7 @@ class Arbiter(object):
self.cfg.settings['worker_class'].get()) self.cfg.settings['worker_class'].get())
self.cfg.when_ready(self) self.cfg.when_ready(self)
def init_signals(self): def init_signals(self):
"""\ """\
Initialize master signal handling. Most of the signals Initialize master signal handling. Most of the signals
@ -152,7 +152,7 @@ class Arbiter(object):
"Main master loop." "Main master loop."
self.start() self.start()
util._setproctitle("master [%s]" % self.proc_name) util._setproctitle("master [%s]" % self.proc_name)
self.manage_workers() self.manage_workers()
while True: while True:
try: try:
@ -163,18 +163,18 @@ class Arbiter(object):
self.murder_workers() self.murder_workers()
self.manage_workers() self.manage_workers()
continue continue
if sig not in self.SIG_NAMES: if sig not in self.SIG_NAMES:
self.log.info("Ignoring unknown signal: %s", sig) self.log.info("Ignoring unknown signal: %s", sig)
continue continue
signame = self.SIG_NAMES.get(sig) signame = self.SIG_NAMES.get(sig)
handler = getattr(self, "handle_%s" % signame, None) handler = getattr(self, "handle_%s" % signame, None)
if not handler: if not handler:
self.log.error("Unhandled signal: %s", signame) self.log.error("Unhandled signal: %s", signame)
continue continue
self.log.info("Handling signal: %s", signame) self.log.info("Handling signal: %s", signame)
handler() handler()
self.wakeup() self.wakeup()
except StopIteration: except StopIteration:
self.halt() self.halt()
@ -185,7 +185,7 @@ class Arbiter(object):
except SystemExit: except SystemExit:
raise raise
except Exception: except Exception:
self.log.info("Unhandled exception in main loop:\n%s", self.log.info("Unhandled exception in main loop:\n%s",
traceback.format_exc()) traceback.format_exc())
self.stop(False) self.stop(False)
if self.pidfile is not None: if self.pidfile is not None:
@ -195,7 +195,7 @@ class Arbiter(object):
def handle_chld(self, sig, frame): def handle_chld(self, sig, frame):
"SIGCHLD handling" "SIGCHLD handling"
self.wakeup() self.wakeup()
def handle_hup(self): def handle_hup(self):
"""\ """\
HUP handling. HUP handling.
@ -205,16 +205,16 @@ class Arbiter(object):
""" """
self.log.info("Hang up: %s", self.master_name) self.log.info("Hang up: %s", self.master_name)
self.reload() self.reload()
def handle_quit(self): def handle_quit(self):
"SIGQUIT handling" "SIGQUIT handling"
raise StopIteration raise StopIteration
def handle_int(self): def handle_int(self):
"SIGINT handling" "SIGINT handling"
self.stop(False) self.stop(False)
raise StopIteration raise StopIteration
def handle_term(self): def handle_term(self):
"SIGTERM handling" "SIGTERM handling"
self.stop(False) self.stop(False)
@ -227,7 +227,7 @@ class Arbiter(object):
""" """
self.num_workers += 1 self.num_workers += 1
self.manage_workers() self.manage_workers()
def handle_ttou(self): def handle_ttou(self):
"""\ """\
SIGTTOU handling. SIGTTOU handling.
@ -245,7 +245,7 @@ class Arbiter(object):
""" """
self.kill_workers(signal.SIGUSR1) self.kill_workers(signal.SIGUSR1)
self.log.reopen_files() self.log.reopen_files()
def handle_usr2(self): def handle_usr2(self):
"""\ """\
SIGUSR2 handling. SIGUSR2 handling.
@ -254,7 +254,7 @@ class Arbiter(object):
deployment with the ability to backout a change. deployment with the ability to backout a change.
""" """
self.reexec() self.reexec()
def handle_winch(self): def handle_winch(self):
"SIGWINCH handling" "SIGWINCH handling"
if os.getppid() == 1 or os.getpgrp() != os.getpid(): if os.getppid() == 1 or os.getpgrp() != os.getpid():
@ -263,7 +263,7 @@ class Arbiter(object):
self.kill_workers(signal.SIGQUIT) self.kill_workers(signal.SIGQUIT)
else: else:
self.log.info("SIGWINCH ignored. Not daemonized") self.log.info("SIGWINCH ignored. Not daemonized")
def wakeup(self): def wakeup(self):
"""\ """\
Wake up the arbiter by writing to the PIPE Wake up the arbiter by writing to the PIPE
@ -273,7 +273,7 @@ class Arbiter(object):
except IOError, e: except IOError, e:
if e.errno not in [errno.EAGAIN, errno.EINTR]: if e.errno not in [errno.EAGAIN, errno.EINTR]:
raise raise
def halt(self, reason=None, exit_status=0): def halt(self, reason=None, exit_status=0):
""" halt arbiter """ """ halt arbiter """
self.stop() self.stop()
@ -283,7 +283,7 @@ class Arbiter(object):
if self.pidfile is not None: if self.pidfile is not None:
self.pidfile.unlink() self.pidfile.unlink()
sys.exit(exit_status) sys.exit(exit_status)
def sleep(self): def sleep(self):
"""\ """\
Sleep until PIPE is readable or we timeout. Sleep until PIPE is readable or we timeout.
@ -303,12 +303,12 @@ class Arbiter(object):
raise raise
except KeyboardInterrupt: except KeyboardInterrupt:
sys.exit() sys.exit()
def stop(self, graceful=True): def stop(self, graceful=True):
"""\ """\
Stop workers Stop workers
:attr graceful: boolean, If True (the default) workers will be :attr graceful: boolean, If True (the default) workers will be
killed gracefully (ie. trying to wait for the current connection) killed gracefully (ie. trying to wait for the current connection)
""" """
@ -357,11 +357,11 @@ class Arbiter(object):
if old_address != self.cfg.address: if old_address != self.cfg.address:
self.LISTENER.close() self.LISTENER.close()
self.LISTENER = create_socket(self.cfg, self.log) self.LISTENER = create_socket(self.cfg, self.log)
self.log.info("Listening at: %s", self.LISTENER) self.log.info("Listening at: %s", self.LISTENER)
# spawn new workers with new app & conf # spawn new workers with new app & conf
self.cfg.on_reload(self) self.cfg.on_reload(self)
# unlink pidfile # unlink pidfile
if self.pidfile is not None: if self.pidfile is not None:
self.pidfile.unlink() self.pidfile.unlink()
@ -370,15 +370,15 @@ class Arbiter(object):
if self.cfg.pidfile is not None: if self.cfg.pidfile is not None:
self.pidfile = Pidfile(self.cfg.pidfile) self.pidfile = Pidfile(self.cfg.pidfile)
self.pidfile.create(self.pid) self.pidfile.create(self.pid)
# set new proc_name # set new proc_name
util._setproctitle("master [%s]" % self.proc_name) util._setproctitle("master [%s]" % self.proc_name)
# manage workers # manage workers
self.log.reopen_files() self.log.reopen_files()
self.manage_workers() self.manage_workers()
def murder_workers(self): def murder_workers(self):
"""\ """\
Kill unused/idle workers Kill unused/idle workers
@ -392,7 +392,7 @@ class Arbiter(object):
self.log.critical("WORKER TIMEOUT (pid:%s)", pid) self.log.critical("WORKER TIMEOUT (pid:%s)", pid)
self.kill_worker(pid, signal.SIGKILL) self.kill_worker(pid, signal.SIGKILL)
def reap_workers(self): def reap_workers(self):
"""\ """\
Reap workers to avoid zombie processes Reap workers to avoid zombie processes
@ -418,7 +418,7 @@ class Arbiter(object):
except OSError, e: except OSError, e:
if e.errno == errno.ECHILD: if e.errno == errno.ECHILD:
pass pass
def manage_workers(self): def manage_workers(self):
"""\ """\
Maintain the number of workers by spawning or killing Maintain the number of workers by spawning or killing
@ -432,7 +432,7 @@ class Arbiter(object):
while len(workers) > self.num_workers: while len(workers) > self.num_workers:
(pid, _) = workers.pop(0) (pid, _) = workers.pop(0)
self.kill_worker(pid, signal.SIGQUIT) self.kill_worker(pid, signal.SIGQUIT)
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.LISTENER, worker = self.worker_class(self.worker_age, self.pid, self.LISTENER,
@ -470,11 +470,11 @@ class Arbiter(object):
def spawn_workers(self): def spawn_workers(self):
"""\ """\
Spawn new workers as needed. Spawn new workers as needed.
This is where a worker process leaves the main loop This is where a worker process leaves the main loop
of the master process. of the master process.
""" """
for i in range(self.num_workers - len(self.WORKERS.keys())): for i in range(self.num_workers - len(self.WORKERS.keys())):
self.spawn_worker() self.spawn_worker()
@ -485,11 +485,11 @@ class Arbiter(object):
""" """
for pid in self.WORKERS.keys(): for pid in self.WORKERS.keys():
self.kill_worker(pid, sig) self.kill_worker(pid, sig)
def kill_worker(self, pid, sig): def kill_worker(self, pid, sig):
"""\ """\
Kill a worker Kill a worker
:attr pid: int, worker pid :attr pid: int, worker pid
:attr sig: `signal.SIG*` value :attr sig: `signal.SIG*` value
""" """
@ -504,4 +504,4 @@ class Arbiter(object):
return return
except (KeyError, OSError): except (KeyError, OSError):
return return
raise raise

View File

@ -1,6 +1,6 @@
# -*- 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.
import copy import copy
@ -34,21 +34,21 @@ def make_settings(ignore=None):
return settings return settings
class Config(object): class Config(object):
def __init__(self, usage=None): def __init__(self, usage=None):
self.settings = make_settings() self.settings = make_settings()
self.usage = usage self.usage = usage
def __getattr__(self, name): def __getattr__(self, name):
if name not in self.settings: if name not in self.settings:
raise AttributeError("No configuration setting for: %s" % name) raise AttributeError("No configuration setting for: %s" % name)
return self.settings[name].get() return self.settings[name].get()
def __setattr__(self, name, value): def __setattr__(self, name, value):
if name != "settings" and name in self.settings: if name != "settings" and name in self.settings:
raise AttributeError("Invalid access!") raise AttributeError("Invalid access!")
super(Config, self).__setattr__(name, value) super(Config, self).__setattr__(name, value)
def set(self, name, value): def set(self, name, value):
if name not in self.settings: if name not in self.settings:
raise AttributeError("No configuration setting for: %s" % name) raise AttributeError("No configuration setting for: %s" % name)
@ -77,7 +77,7 @@ class Config(object):
worker_class.setup() worker_class.setup()
return worker_class return worker_class
@property @property
def workers(self): def workers(self):
return self.settings['workers'].get() return self.settings['workers'].get()
@ -85,15 +85,15 @@ class Config(object):
def address(self): def address(self):
bind = self.settings['bind'].get() bind = self.settings['bind'].get()
return util.parse_address(util.to_bytestring(bind)) return util.parse_address(util.to_bytestring(bind))
@property @property
def uid(self): def uid(self):
return self.settings['user'].get() return self.settings['user'].get()
@property @property
def gid(self): def gid(self):
return self.settings['group'].get() return self.settings['group'].get()
@property @property
def proc_name(self): def proc_name(self):
pn = self.settings['proc_name'].get() pn = self.settings['proc_name'].get()
@ -112,17 +112,17 @@ class Config(object):
logger_class.install() logger_class.install()
return logger_class return logger_class
class SettingMeta(type): class SettingMeta(type):
def __new__(cls, name, bases, attrs): def __new__(cls, name, bases, attrs):
super_new = super(SettingMeta, cls).__new__ super_new = super(SettingMeta, cls).__new__
parents = [b for b in bases if isinstance(b, SettingMeta)] parents = [b for b in bases if isinstance(b, SettingMeta)]
if not parents: if not parents:
return super_new(cls, name, bases, attrs) return super_new(cls, name, bases, attrs)
attrs["order"] = len(KNOWN_SETTINGS) attrs["order"] = len(KNOWN_SETTINGS)
attrs["validator"] = wrap_method(attrs["validator"]) attrs["validator"] = wrap_method(attrs["validator"])
new_class = super_new(cls, name, bases, attrs) new_class = super_new(cls, name, bases, attrs)
new_class.fmt_desc(attrs.get("desc", "")) new_class.fmt_desc(attrs.get("desc", ""))
KNOWN_SETTINGS.append(new_class) KNOWN_SETTINGS.append(new_class)
@ -135,7 +135,7 @@ class SettingMeta(type):
class Setting(object): class Setting(object):
__metaclass__ = SettingMeta __metaclass__ = SettingMeta
name = None name = None
value = None value = None
section = None section = None
@ -147,11 +147,11 @@ class Setting(object):
default = None default = None
short = None short = None
desc = None desc = None
def __init__(self): def __init__(self):
if self.default is not None: if self.default is not None:
self.set(self.default) self.set(self.default)
def add_option(self, parser): def add_option(self, parser):
if not self.cli: if not self.cli:
return return
@ -167,13 +167,13 @@ class Setting(object):
if kwargs["action"] != "store": if kwargs["action"] != "store":
kwargs.pop("type") kwargs.pop("type")
parser.add_option(*args, **kwargs) parser.add_option(*args, **kwargs)
def copy(self): def copy(self):
return copy.copy(self) return copy.copy(self)
def get(self): def get(self):
return self.value return self.value
def set(self, val): def set(self, val):
assert callable(self.validator), "Invalid validator: %s" % self.name assert callable(self.validator), "Invalid validator: %s" % self.name
self.value = self.validator(val) self.value = self.validator(val)
@ -256,7 +256,7 @@ def validate_post_request(val):
def _wrapped(instance, req, environ): def _wrapped(instance, req, environ):
return fun(instance, req) return fun(instance, req)
return _wrapped return _wrapped
if not callable(val): if not callable(val):
raise TypeError("Value isn't a callable: %s" % val) raise TypeError("Value isn't a callable: %s" % val)
@ -279,9 +279,9 @@ class ConfigFile(Setting):
default = None default = None
desc = """\ desc = """\
The path to a Gunicorn config file. The path to a Gunicorn config file.
Only has an effect when specified on the command line or as part of an Only has an effect when specified on the command line or as part of an
application specific configuration. application specific configuration.
""" """
class Bind(Setting): class Bind(Setting):
@ -293,11 +293,11 @@ class Bind(Setting):
default = "127.0.0.1:8000" default = "127.0.0.1:8000"
desc = """\ desc = """\
The socket to bind. The socket to bind.
A string of the form: 'HOST', 'HOST:PORT', 'unix:PATH'. An IP is a valid A string of the form: 'HOST', 'HOST:PORT', 'unix:PATH'. An IP is a valid
HOST. HOST.
""" """
class Backlog(Setting): class Backlog(Setting):
name = "backlog" name = "backlog"
section = "Server Socket" section = "Server Socket"
@ -307,14 +307,14 @@ class Backlog(Setting):
type = "int" type = "int"
default = 2048 default = 2048
desc = """\ desc = """\
The maximum number of pending connections. The maximum number of pending connections.
This refers to the number of clients that can be waiting to be served. This refers to the number of clients that can be waiting to be served.
Exceeding this number results in the client getting an error when Exceeding this number results in the client getting an error when
attempting to connect. It should only affect servers under significant attempting to connect. It should only affect servers under significant
load. load.
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):
@ -327,7 +327,7 @@ class Workers(Setting):
default = 1 default = 1
desc = """\ desc = """\
The number of worker process for handling requests. The number of worker process for handling requests.
A positive integer generally in the 2-4 x $(NUM_CORES) range. You'll A positive integer generally in the 2-4 x $(NUM_CORES) range. You'll
want to vary this a bit to find the best for your particular want to vary this a bit to find the best for your particular
application's work load. application's work load.
@ -342,18 +342,18 @@ class WorkerClass(Setting):
default = "sync" default = "sync"
desc = """\ desc = """\
The type of workers to use. The type of workers to use.
The default class (sync) should handle most 'normal' types of workloads. The default class (sync) should handle most 'normal' types of workloads.
You'll want to read http://gunicorn.org/design.html for information on You'll want to read http://gunicorn.org/design.html for information on
when you might want to choose one of the other worker classes. when you might want to choose one of the other worker classes.
A string referring to one of the following bundled classes: A string referring to one of the following bundled classes:
* ``sync`` * ``sync``
* ``eventlet`` - Requires eventlet >= 0.9.7 * ``eventlet`` - Requires eventlet >= 0.9.7
* ``gevent`` - Requires gevent >= 0.12.2 (?) * ``gevent`` - Requires gevent >= 0.12.2 (?)
* ``tornado`` - Requires tornado >= 0.2 * ``tornado`` - Requires tornado >= 0.2
Optionally, you can provide your own worker by giving gunicorn a Optionally, you can provide your own worker by giving gunicorn a
python path to a subclass of gunicorn.workers.base.Worker. This python path to a subclass of gunicorn.workers.base.Worker. This
alternative syntax will load the gevent class: alternative syntax will load the gevent class:
@ -371,7 +371,7 @@ class WorkerConnections(Setting):
default = 1000 default = 1000
desc = """\ desc = """\
The maximum number of simultaneous clients. The maximum number of simultaneous clients.
This setting only affects the Eventlet and Gevent worker types. This setting only affects the Eventlet and Gevent worker types.
""" """
@ -385,11 +385,11 @@ class MaxRequests(Setting):
default = 0 default = 0
desc = """\ desc = """\
The maximum number of requests a worker will process before restarting. The maximum number of requests a worker will process before restarting.
Any value greater than zero will limit the number of requests a work Any value greater than zero will limit the number of requests a work
will process before automatically restarting. This is a simple method will process before automatically restarting. This is a simple method
to help limit the damage of memory leaks. to help limit the damage of memory leaks.
If this is set to zero (the default) then the automatic worker If this is set to zero (the default) then the automatic worker
restarts are disabled. restarts are disabled.
""" """
@ -404,7 +404,7 @@ class Timeout(Setting):
default = 30 default = 30
desc = """\ desc = """\
Workers silent for more than this many seconds are killed and restarted. Workers silent for more than this many seconds are killed and restarted.
Generally set to thirty seconds. Only set this noticeably higher if Generally set to thirty seconds. Only set this noticeably higher if
you're sure of the repercussions for sync workers. For the non sync you're sure of the repercussions for sync workers. For the non sync
workers it just means that the worker process is still communicating and workers it just means that the worker process is still communicating and
@ -421,8 +421,8 @@ class Keepalive(Setting):
default = 2 default = 2
desc = """\ desc = """\
The number of seconds to wait for requests on a Keep-Alive connection. The number of seconds to wait for requests on a Keep-Alive connection.
Generally set in the 1-5 seconds range. Generally set in the 1-5 seconds range.
""" """
class Debug(Setting): class Debug(Setting):
@ -434,7 +434,7 @@ class Debug(Setting):
default = False default = False
desc = """\ desc = """\
Turn on debugging in the server. Turn on debugging in the server.
This limits the number of worker processes to 1 and changes some error This limits the number of worker processes to 1 and changes some error
handling that's sent to clients. handling that's sent to clients.
""" """
@ -448,8 +448,8 @@ class Spew(Setting):
default = False default = False
desc = """\ desc = """\
Install a trace function that spews every line executed by the server. Install a trace function that spews every line executed by the server.
This is the nuclear option. This is the nuclear option.
""" """
class PreloadApp(Setting): class PreloadApp(Setting):
@ -461,7 +461,7 @@ class PreloadApp(Setting):
default = False default = False
desc = """\ desc = """\
Load application code before the worker processes are forked. Load application code before the worker processes are forked.
By preloading an application you can save some RAM resources as well as By preloading an application you can save some RAM resources as well as
speed up server boot times. Although, if you defer application loading speed up server boot times. Although, if you defer application loading
to each worker process, you can reload your application code easily by to each worker process, you can reload your application code easily by
@ -477,7 +477,7 @@ class Daemon(Setting):
default = False default = False
desc = """\ desc = """\
Daemonize the Gunicorn process. Daemonize the Gunicorn process.
Detaches the server from the controlling terminal and enters the Detaches the server from the controlling terminal and enters the
background. background.
""" """
@ -491,7 +491,7 @@ class Pidfile(Setting):
default = None default = None
desc = """\ desc = """\
A filename to use for the PID file. A filename to use for the PID file.
If not set, no PID file will be written. If not set, no PID file will be written.
""" """
@ -504,7 +504,7 @@ class User(Setting):
default = os.geteuid() default = os.geteuid()
desc = """\ desc = """\
Switch worker processes to run as this user. Switch worker processes to run as this user.
A valid user id (as an integer) or the name of a user that can be A valid user id (as an integer) or the name of a user that can be
retrieved with a call to pwd.getpwnam(value) or None to not change retrieved with a call to pwd.getpwnam(value) or None to not change
the worker process user. the worker process user.
@ -519,7 +519,7 @@ class Group(Setting):
default = os.getegid() default = os.getegid()
desc = """\ desc = """\
Switch worker process to run as this group. Switch worker process to run as this group.
A valid group id (as an integer) or the name of a user that can be A valid group id (as an integer) or the name of a user that can be
retrieved with a call to pwd.getgrnam(value) or None to not change retrieved with a call to pwd.getgrnam(value) or None to not change
the worker processes group. the worker processes group.
@ -535,9 +535,9 @@ class Umask(Setting):
default = 0 default = 0
desc = """\ desc = """\
A bit mask for the file mode on files written by Gunicorn. A bit mask for the file mode on files written by Gunicorn.
Note that this affects unix socket permissions. Note that this affects unix socket permissions.
A valid value for the os.umask(mode) call or a string compatible with A valid value for the os.umask(mode) call or a string compatible with
int(value, 0) (0 means Python guesses the base, so values like "0", int(value, 0) (0 means Python guesses the base, so values like "0",
"0xFF", "0022" are valid for decimal, hex, and octal representations) "0xFF", "0022" are valid for decimal, hex, and octal representations)
@ -551,9 +551,9 @@ class TmpUploadDir(Setting):
default = None default = None
desc = """\ desc = """\
Directory to store temporary request data as they are read. Directory to store temporary request data as they are read.
This may disappear in the near future. This may disappear in the near future.
This path should be writable by the process permissions set for Gunicorn This path should be writable by the process permissions set for Gunicorn
workers. If not specified, Gunicorn will choose a system generated workers. If not specified, Gunicorn will choose a system generated
temporary directory. temporary directory.
@ -599,10 +599,10 @@ class AccessLog(Setting):
cli = ["--access-logfile"] cli = ["--access-logfile"]
meta = "FILE" meta = "FILE"
validator = validate_string validator = validate_string
default = None default = None
desc = """\ desc = """\
The Access log file to write to. The Access log file to write to.
"-" means log to stdout. "-" means log to stdout.
""" """
@ -612,7 +612,7 @@ class AccessLogFormat(Setting):
cli = ["--access-logformat"] cli = ["--access-logformat"]
meta = "STRING" meta = "STRING"
validator = validate_string validator = validate_string
default = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' default = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
desc = """\ desc = """\
The Access log format . The Access log format .
@ -631,7 +631,7 @@ class AccessLogFormat(Setting):
T: request time in seconds T: request time in seconds
D: request time in microseconds D: request time in microseconds
You can also pass any WSGI request header as a parameter. You can also pass any WSGI request header as a parameter.
(ex '%(HTTP_HOST)s'). (ex '%(HTTP_HOST)s').
""" """
@ -644,7 +644,7 @@ class ErrorLog(Setting):
default = "-" default = "-"
desc = """\ desc = """\
The Error log file to write to. The Error log file to write to.
"-" means log to stdout. "-" means log to stdout.
""" """
@ -657,9 +657,9 @@ class Loglevel(Setting):
default = "info" default = "info"
desc = """\ desc = """\
The granularity of Error log outputs. The granularity of Error log outputs.
Valid level names are: Valid level names are:
* debug * debug
* info * info
* warning * warning
@ -681,8 +681,8 @@ class LoggerClass(Setting):
normal usages in logging. It provides error and access logging. normal usages in logging. It provides error and access logging.
You can provide your own worker by giving gunicorn a You can provide your own worker by giving gunicorn a
python path to a subclass like gunicorn.glogging.Logger. python path to a subclass like gunicorn.glogging.Logger.
Alternatively the syntax can also load the Logger class Alternatively the syntax can also load the Logger class
with `egg:gunicorn#simple` with `egg:gunicorn#simple`
""" """
@ -695,12 +695,12 @@ class Procname(Setting):
default = None default = None
desc = """\ desc = """\
A base to use with setproctitle for process naming. A base to use with setproctitle for process naming.
This affects things like ``ps`` and ``top``. If you're going to be This affects things like ``ps`` and ``top``. If you're going to be
running more than one instance of Gunicorn you'll probably want to set a running more than one instance of Gunicorn you'll probably want to set a
name to tell them apart. This requires that you install the setproctitle name to tell them apart. This requires that you install the setproctitle
module. module.
It defaults to 'gunicorn'. It defaults to 'gunicorn'.
""" """
@ -723,7 +723,7 @@ class OnStarting(Setting):
default = staticmethod(on_starting) default = staticmethod(on_starting)
desc = """\ desc = """\
Called just before the master process is initialized. Called just before the master process is initialized.
The callable needs to accept a single instance variable for the Arbiter. The callable needs to accept a single instance variable for the Arbiter.
""" """
@ -752,7 +752,7 @@ class WhenReady(Setting):
default = staticmethod(start_server) default = staticmethod(start_server)
desc = """\ desc = """\
Called just after the server is started. Called just after the server is started.
The callable needs to accept a single instance variable for the Arbiter. The callable needs to accept a single instance variable for the Arbiter.
""" """
@ -766,11 +766,11 @@ class Prefork(Setting):
default = staticmethod(pre_fork) default = staticmethod(pre_fork)
desc = """\ desc = """\
Called just before a worker is forked. Called just before a worker is forked.
The callable needs to accept two instance variables for the Arbiter and The callable needs to accept two instance variables for the Arbiter and
new Worker. new Worker.
""" """
class Postfork(Setting): class Postfork(Setting):
name = "post_fork" name = "post_fork"
section = "Server Hooks" section = "Server Hooks"
@ -781,7 +781,7 @@ class Postfork(Setting):
default = staticmethod(post_fork) default = staticmethod(post_fork)
desc = """\ desc = """\
Called just after a worker has been forked. Called just after a worker has been forked.
The callable needs to accept two instance variables for the Arbiter and The callable needs to accept two instance variables for the Arbiter and
new Worker. new Worker.
""" """
@ -796,7 +796,7 @@ class PreExec(Setting):
default = staticmethod(pre_exec) default = staticmethod(pre_exec)
desc = """\ desc = """\
Called just before a new master process is forked. Called just before a new master process is forked.
The callable needs to accept a single instance variable for the Arbiter. The callable needs to accept a single instance variable for the Arbiter.
""" """
@ -810,7 +810,7 @@ class PreRequest(Setting):
default = staticmethod(pre_request) default = staticmethod(pre_request)
desc = """\ desc = """\
Called just before a worker processes the request. Called just before a worker processes the request.
The callable needs to accept two instance variables for the Worker and The callable needs to accept two instance variables for the Worker and
the Request. the Request.
""" """

View File

@ -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.
"""The debug module contains utilities and functions for better """The debug module contains utilities and functions for better
debugging Gunicorn.""" debugging Gunicorn."""
import sys import sys
@ -69,5 +69,5 @@ def unspew():
"""Remove the trace hook installed by spew. """Remove the trace hook installed by spew.
""" """
sys.settrace(None) sys.settrace(None)

View File

@ -1,6 +1,6 @@
# -*- 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.
@ -8,7 +8,7 @@ class HaltServer(Exception):
def __init__(self, reason, exit_status=1): def __init__(self, reason, exit_status=1):
self.reason = reason self.reason = reason
self.exit_status = exit_status self.exit_status = exit_status
def __str__(self): def __str__(self):
return "<HaltServer %r %d>" % (self.reason, self.exit_status) return "<HaltServer %r %d>" % (self.reason, self.exit_status)

View File

@ -1,6 +1,6 @@
# -*- 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.
import datetime import datetime
@ -39,7 +39,7 @@ class Logger(object):
loglevel = self.LOG_LEVELS.get(cfg.loglevel.lower(), logging.INFO) loglevel = self.LOG_LEVELS.get(cfg.loglevel.lower(), logging.INFO)
self.error_log.setLevel(loglevel) self.error_log.setLevel(loglevel)
# always info in access log # always info in access log
self.access_log.setLevel(logging.INFO) self.access_log.setLevel(logging.INFO)
@ -100,13 +100,13 @@ class Logger(object):
'D': str(request_time.microseconds) 'D': str(request_time.microseconds)
} }
# add WSGI request headers # add WSGI request headers
atoms.update(dict([(k,v) for k, v in environ.items() \ atoms.update(dict([(k,v) for k, v in environ.items() \
if k.startswith('HTTP_')])) if k.startswith('HTTP_')]))
for k, v in atoms.items(): for k, v in atoms.items():
atoms[k] = v.replace('"', '\\"') atoms[k] = v.replace('"', '\\"')
try: try:
self.access_log.info(self.cfg.access_log_format % atoms) self.access_log.info(self.cfg.access_log_format % atoms)
except: except:
@ -138,12 +138,12 @@ class Logger(object):
util.close_on_exec(handler.stream.fileno()) util.close_on_exec(handler.stream.fileno())
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:
return h return h
def _set_handler(self, log, output, fmt): def _set_handler(self, log, output, fmt):
# remove previous gunicorn log handler # remove previous gunicorn log handler
h = self._get_gunicorn_handler(log) h = self._get_gunicorn_handler(log)

View File

@ -1,6 +1,6 @@
# -*- 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.
import errno import errno
@ -35,7 +35,7 @@ def sendfile(fdout, fdin, offset, nbytes):
ctypes.c_int] ctypes.c_int]
_nbytes = ctypes.c_uint64(nbytes) _nbytes = ctypes.c_uint64(nbytes)
result = _sendfile(fdin, fdout, offset, _nbytes, None, 0) result = _sendfile(fdin, fdout, offset, _nbytes, None, 0)
if result == -1: if result == -1:
e = ctypes.get_errno() e = ctypes.get_errno()
if e == errno.EAGAIN and _nbytes.value is not None: if e == errno.EAGAIN and _nbytes.value is not None:
@ -60,7 +60,7 @@ def sendfile(fdout, fdin, offset, nbytes):
ctypes.POINTER(ctypes.c_uint64), ctypes.c_size_t] ctypes.POINTER(ctypes.c_uint64), ctypes.c_size_t]
_offset = ctypes.c_uint64(offset) _offset = ctypes.c_uint64(offset)
sent = _sendfile(fdout, fdin, _offset, nbytes) sent = _sendfile(fdout, fdin, _offset, nbytes)
if sent == -1: if sent == -1:
e = ctypes.get_errno() e = ctypes.get_errno()
raise OSError(e, os.strerror(e)) raise OSError(e, os.strerror(e))

View File

@ -1,6 +1,6 @@
# -*- 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.
import sys import sys
@ -18,7 +18,7 @@ class ChunkedReader(object):
self.req = req self.req = req
self.parser = self.parse_chunked(unreader) self.parser = self.parse_chunked(unreader)
self.buf = StringIO() self.buf = StringIO()
def read(self, size): def read(self, size):
if not isinstance(size, (int, long)): if not isinstance(size, (int, long)):
raise TypeError("size must be an integral type") raise TypeError("size must be an integral type")
@ -40,11 +40,11 @@ class ChunkedReader(object):
self.buf.truncate(0) self.buf.truncate(0)
self.buf.write(rest) self.buf.write(rest)
return ret return ret
def parse_trailers(self, unreader, data): def parse_trailers(self, unreader, data):
buf = StringIO() buf = StringIO()
buf.write(data) buf.write(data)
idx = buf.getvalue().find("\r\n\r\n") idx = buf.getvalue().find("\r\n\r\n")
done = buf.getvalue()[:2] == "\r\n" done = buf.getvalue()[:2] == "\r\n"
while idx < 0 and not done: while idx < 0 and not done:
@ -73,7 +73,7 @@ class ChunkedReader(object):
rest += unreader.read() rest += unreader.read()
if rest[:2] != '\r\n': if rest[:2] != '\r\n':
raise ChunkMissingTerminator(rest[:2]) raise ChunkMissingTerminator(rest[:2])
(size, rest) = self.parse_chunk_size(unreader, data=rest[2:]) (size, rest) = self.parse_chunk_size(unreader, data=rest[2:])
def parse_chunk_size(self, unreader, data=None): def parse_chunk_size(self, unreader, data=None):
buf = StringIO() buf = StringIO()
@ -87,7 +87,7 @@ class ChunkedReader(object):
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(";", 1)[0].strip() chunk_size = line.split(";", 1)[0].strip()
try: try:
chunk_size = int(chunk_size, 16) chunk_size = int(chunk_size, 16)
@ -112,18 +112,18 @@ class LengthReader(object):
def __init__(self, unreader, length): def __init__(self, unreader, length):
self.unreader = unreader self.unreader = unreader
self.length = length self.length = length
def read(self, size): def read(self, size):
if not isinstance(size, (int, long)): if not isinstance(size, (int, long)):
raise TypeError("size must be an integral type") raise TypeError("size must be an integral type")
size = min(self.length, size) size = min(self.length, size)
if size < 0: if size < 0:
raise ValueError("Size must be positive.") raise ValueError("Size must be positive.")
if size == 0: if size == 0:
return "" return ""
buf = StringIO() buf = StringIO()
data = self.unreader.read() data = self.unreader.read()
while data: while data:
@ -131,7 +131,7 @@ class LengthReader(object):
if buf.tell() >= size: if buf.tell() >= size:
break break
data = self.unreader.read() data = self.unreader.read()
buf = buf.getvalue() buf = buf.getvalue()
ret, rest = buf[:size], buf[size:] ret, rest = buf[:size], buf[size:]
self.unreader.unread(rest) self.unreader.unread(rest)
@ -143,7 +143,7 @@ class EOFReader(object):
self.unreader = unreader self.unreader = unreader
self.buf = StringIO() self.buf = StringIO()
self.finished = False self.finished = False
def read(self, size): def read(self, size):
if not isinstance(size, (int, long)): if not isinstance(size, (int, long)):
raise TypeError("size must be an integral type") raise TypeError("size must be an integral type")
@ -151,7 +151,7 @@ class EOFReader(object):
raise ValueError("Size must be positive.") raise ValueError("Size must be positive.")
if size == 0: if size == 0:
return "" return ""
if self.finished: if self.finished:
data = self.buf.getvalue() data = self.buf.getvalue()
ret, rest = data[:size], data[size:] ret, rest = data[:size], data[size:]
@ -179,10 +179,10 @@ class Body(object):
def __init__(self, reader): def __init__(self, reader):
self.reader = reader self.reader = reader
self.buf = StringIO() self.buf = StringIO()
def __iter__(self): def __iter__(self):
return self return self
def next(self): def next(self):
ret = self.readline() ret = self.readline()
if not ret: if not ret:
@ -197,7 +197,7 @@ class Body(object):
elif size < 0: elif size < 0:
return sys.maxint return sys.maxint
return size return size
def read(self, size=None): def read(self, size=None):
size = self.getsize(size) size = self.getsize(size)
if size == 0: if size == 0:
@ -221,12 +221,12 @@ class Body(object):
self.buf.truncate(0) self.buf.truncate(0)
self.buf.write(rest) self.buf.write(rest)
return ret return ret
def readline(self, size=None): def readline(self, size=None):
size = self.getsize(size) size = self.getsize(size)
if size == 0: if size == 0:
return "" return ""
line = self.buf.getvalue() line = self.buf.getvalue()
idx = line.find("\n") idx = line.find("\n")
if idx >= 0: if idx >= 0:
@ -234,7 +234,7 @@ class Body(object):
self.buf.truncate(0) self.buf.truncate(0)
self.buf.write(line[idx+1:]) self.buf.write(line[idx+1:])
return ret return ret
self.buf.truncate(0) self.buf.truncate(0)
ch = "" ch = ""
buf = [line] buf = [line]
@ -246,7 +246,7 @@ class Body(object):
lsize += 1 lsize += 1
buf.append(ch) buf.append(ch)
return "".join(buf) return "".join(buf)
def readlines(self, size=None): def readlines(self, size=None):
ret = [] ret = []
data = self.read() data = self.read()

View File

@ -1,6 +1,6 @@
# -*- 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.
class ParseException(Exception): class ParseException(Exception):
@ -26,18 +26,18 @@ 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
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): def __init__(self, hdr):
self.hdr = hdr self.hdr = hdr
def __str__(self): def __str__(self):
return "Invalid HTTP Header: %r" % self.hdr return "Invalid HTTP Header: %r" % self.hdr
@ -51,13 +51,13 @@ class InvalidHeaderName(ParseException):
class InvalidChunkSize(ParseException): class InvalidChunkSize(ParseException):
def __init__(self, data): def __init__(self, data):
self.data = data self.data = data
def __str__(self): def __str__(self):
return "Invalid chunk size: %r" % self.data return "Invalid chunk size: %r" % self.data
class ChunkMissingTerminator(ParseException): class ChunkMissingTerminator(ParseException):
def __init__(self, term): def __init__(self, term):
self.term = term self.term = term
def __str__(self): def __str__(self):
return "Invalid chunk terminator is not '\\r\\n': %r" % self.term return "Invalid chunk terminator is not '\\r\\n': %r" % self.term

View File

@ -1,6 +1,6 @@
# -*- 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.
import re import re
@ -28,7 +28,7 @@ class Message(object):
unused = self.parse(self.unreader) unused = self.parse(self.unreader)
self.unreader.unread(unused) self.unreader.unread(unused)
self.set_body_reader() self.set_body_reader()
def parse(self): def parse(self):
raise NotImplementedError() raise NotImplementedError()
@ -50,12 +50,12 @@ class Message(object):
if self.hdrre.search(name): if self.hdrre.search(name):
raise InvalidHeaderName(name) raise InvalidHeaderName(name)
name, value = name.strip(), [value.lstrip()] name, value = name.strip(), [value.lstrip()]
# Consume value continuation lines # Consume value continuation lines
while len(lines) and lines[0].startswith((" ", "\t")): while len(lines) and lines[0].startswith((" ", "\t")):
value.append(lines.pop(0)) value.append(lines.pop(0))
value = ''.join(value).rstrip() value = ''.join(value).rstrip()
headers.append((name, value)) headers.append((name, value))
return headers return headers
@ -99,7 +99,7 @@ class Request(Message):
def __init__(self, unreader): def __init__(self, unreader):
self.methre = re.compile("[A-Z0-9$-_.]{3,20}") self.methre = re.compile("[A-Z0-9$-_.]{3,20}")
self.versre = re.compile("HTTP/(\d+).(\d+)") self.versre = re.compile("HTTP/(\d+).(\d+)")
self.method = None self.method = None
self.uri = None self.uri = None
self.scheme = None self.scheme = None
@ -119,12 +119,12 @@ class Request(Message):
raise StopIteration() raise StopIteration()
raise NoMoreData(buf.getvalue()) raise NoMoreData(buf.getvalue())
buf.write(data) buf.write(data)
def parse(self, unreader): def parse(self, unreader):
buf = StringIO() buf = StringIO()
self.get_data(unreader, buf, stop=True) self.get_data(unreader, buf, stop=True)
# Request line # Request line
idx = buf.getvalue().find("\r\n") idx = buf.getvalue().find("\r\n")
while idx < 0: while idx < 0:
@ -134,8 +134,8 @@ class Request(Message):
rest = buf.getvalue()[idx+2:] # Skip \r\n rest = buf.getvalue()[idx+2:] # Skip \r\n
buf = StringIO() buf = StringIO()
buf.write(rest) buf.write(rest)
# Headers # Headers
idx = buf.getvalue().find("\r\n\r\n") idx = buf.getvalue().find("\r\n\r\n")
@ -144,7 +144,7 @@ class Request(Message):
self.get_data(unreader, buf) self.get_data(unreader, buf)
idx = buf.getvalue().find("\r\n\r\n") idx = buf.getvalue().find("\r\n\r\n")
done = buf.getvalue()[:2] == "\r\n" done = buf.getvalue()[:2] == "\r\n"
if done: if done:
self.unreader.unread(buf.getvalue()[2:]) self.unreader.unread(buf.getvalue()[2:])
return "" return ""
@ -154,7 +154,7 @@ class Request(Message):
ret = buf.getvalue()[idx+4:] ret = buf.getvalue()[idx+4:]
buf = StringIO() buf = StringIO()
return ret return ret
def parse_request_line(self, line): def parse_request_line(self, line):
bits = line.split(None, 2) bits = line.split(None, 2)
if len(bits) != 3: if len(bits) != 3:

View File

@ -1,6 +1,6 @@
# -*- 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 Request from gunicorn.http.message import Request
@ -17,18 +17,18 @@ class Parser(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def next(self):
# Stop if HTTP dictates a stop. # Stop if HTTP dictates a stop.
if self.mesg and self.mesg.should_close(): if self.mesg and self.mesg.should_close():
raise StopIteration() raise StopIteration()
# Discard any unread body of the previous message # Discard any unread body of the previous message
if self.mesg: if self.mesg:
data = self.mesg.body.read(8192) data = self.mesg.body.read(8192)
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.mesg = self.mesg_class(self.unreader) self.mesg = self.mesg_class(self.unreader)
if not self.mesg: if not self.mesg:

View File

@ -1,6 +1,6 @@
# -*- 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.
import os import os
@ -16,10 +16,10 @@ except ImportError:
class Unreader(object): class Unreader(object):
def __init__(self): def __init__(self):
self.buf = StringIO() self.buf = StringIO()
def chunk(self): def chunk(self):
raise NotImplementedError() raise NotImplementedError()
def read(self, size=None): def read(self, size=None):
if size is not None and not isinstance(size, (int, long)): if size is not None and not isinstance(size, (int, long)):
raise TypeError("size parameter must be an int or long.") raise TypeError("size parameter must be an int or long.")
@ -48,7 +48,7 @@ class Unreader(object):
self.buf.truncate(0) self.buf.truncate(0)
self.buf.write(data[size:]) self.buf.write(data[size:])
return data[:size] return data[:size]
def unread(self, data): def unread(self, data):
self.buf.seek(0, os.SEEK_END) self.buf.seek(0, os.SEEK_END)
self.buf.write(data) self.buf.write(data)
@ -58,7 +58,7 @@ class SocketUnreader(Unreader):
super(SocketUnreader, self).__init__() super(SocketUnreader, self).__init__()
self.sock = sock self.sock = sock
self.mxchunk = max_chunk self.mxchunk = max_chunk
def chunk(self): def chunk(self):
return self.sock.recv(self.mxchunk) return self.sock.recv(self.mxchunk)

View File

@ -1,6 +1,6 @@
# -*- 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.
import logging import logging
@ -59,7 +59,7 @@ def create(req, sock, client, server, cfg):
"CONTENT_TYPE": "", "CONTENT_TYPE": "",
"CONTENT_LENGTH": "" "CONTENT_LENGTH": ""
} }
# authors should be aware that REMOTE_HOST and REMOTE_ADDR # authors should be aware that REMOTE_HOST and REMOTE_ADDR
# may not qualify the remote addr: # may not qualify the remote addr:
# http://www.ietf.org/rfc/rfc3875 # http://www.ietf.org/rfc/rfc3875
@ -98,7 +98,7 @@ def create(req, sock, client, server, cfg):
environ[key] = hdr_value environ[key] = hdr_value
environ['wsgi.url_scheme'] = url_scheme environ['wsgi.url_scheme'] = url_scheme
if isinstance(forward, basestring): if isinstance(forward, basestring):
# we only took the last one # we only took the last one
# http://en.wikipedia.org/wiki/X-Forwarded-For # http://en.wikipedia.org/wiki/X-Forwarded-For
@ -121,7 +121,7 @@ def create(req, sock, client, server, cfg):
remote = (host, port) remote = (host, port)
else: else:
remote = forward remote = forward
environ['REMOTE_ADDR'] = remote[0] environ['REMOTE_ADDR'] = remote[0]
environ['REMOTE_PORT'] = str(remote[1]) environ['REMOTE_PORT'] = str(remote[1])

View File

@ -1,6 +1,6 @@
# -*- 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.
# #
# Copyright 2001-2005 by Vinay Sajip. All Rights Reserved. # Copyright 2001-2005 by Vinay Sajip. All Rights Reserved.

View File

@ -1,12 +1,12 @@
# -*- 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 optparse import make_option from optparse import make_option
import sys import sys
import django import django
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from django.conf import settings from django.conf import settings
@ -56,17 +56,17 @@ class Command(BaseCommand):
option_list = BaseCommand.option_list + GUNICORN_OPTIONS option_list = BaseCommand.option_list + GUNICORN_OPTIONS
help = "Starts a fully-functional Web server using gunicorn." help = "Starts a fully-functional Web server using gunicorn."
args = '[optional port number, or ipaddr:port or unix:/path/to/sockfile]' args = '[optional port number, or ipaddr:port or unix:/path/to/sockfile]'
# Validation is called explicitly each time the server is reloaded. # Validation is called explicitly each time the server is reloaded.
requires_model_validation = False requires_model_validation = False
def handle(self, addrport=None, *args, **options): def handle(self, addrport=None, *args, **options):
if args: if args:
raise CommandError('Usage is run_gunicorn %s' % self.args) raise CommandError('Usage is run_gunicorn %s' % self.args)
if addrport: if addrport:
options['bind'] = addrport options['bind'] = addrport
options['default_proc_name'] = settings.SETTINGS_MODULE options['default_proc_name'] = settings.SETTINGS_MODULE
admin_media_path = options.pop('admin_media_path', '') admin_media_path = options.pop('admin_media_path', '')
@ -74,11 +74,11 @@ class Command(BaseCommand):
print "Validating models..." print "Validating models..."
self.validate(display_num_errors=True) self.validate(display_num_errors=True)
print "\nDjango version %s, using settings %r" % (django.get_version(), print "\nDjango version %s, using settings %r" % (django.get_version(),
settings.SETTINGS_MODULE) settings.SETTINGS_MODULE)
print "Server is running" print "Server is running"
print "Quit the server with %s." % quit_command print "Quit the server with %s." % quit_command
# django.core.management.base forces the locale to en-us. # django.core.management.base forces the locale to en-us.
translation.activate(settings.LANGUAGE_CODE) translation.activate(settings.LANGUAGE_CODE)
DjangoApplicationCommand(options, admin_media_path).run() DjangoApplicationCommand(options, admin_media_path).run()

View File

@ -1,6 +1,6 @@
# -*- 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 __future__ import with_statement from __future__ import with_statement
@ -20,7 +20,7 @@ class Pidfile(object):
def __init__(self, fname): def __init__(self, fname):
self.fname = fname self.fname = fname
self.pid = None self.pid = None
def create(self, pid): def create(self, pid):
oldpid = self.validate() oldpid = self.validate()
if oldpid: if oldpid:
@ -30,7 +30,7 @@ class Pidfile(object):
"(or pid file '%s' is stale)" % (os.getpid(), self.fname)) "(or pid file '%s' is stale)" % (os.getpid(), self.fname))
self.pid = pid self.pid = pid
# Write pidfile # Write pidfile
fdir = os.path.dirname(self.fname) fdir = os.path.dirname(self.fname)
if fdir and not os.path.isdir(fdir): if fdir and not os.path.isdir(fdir):
@ -43,14 +43,14 @@ class Pidfile(object):
self.fname = fname self.fname = fname
os.close(fd) os.close(fd)
# set permissions to -rw-r--r-- # set permissions to -rw-r--r--
os.chmod(self.fname, 420) os.chmod(self.fname, 420)
def rename(self, path): def rename(self, path):
self.unlink() self.unlink()
self.fname = path self.fname = path
self.create(self.pid) self.create(self.pid)
def unlink(self): def unlink(self):
""" delete pidfile""" """ delete pidfile"""
try: try:
@ -61,7 +61,7 @@ class Pidfile(object):
os.unlink(self.fname) os.unlink(self.fname)
except: except:
pass pass
def validate(self): def validate(self):
""" Validate pidfile and make it stale if needed""" """ Validate pidfile and make it stale if needed"""
if not self.fname: if not self.fname:

View File

@ -1,6 +1,6 @@
# -*- 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.
import errno import errno
@ -14,7 +14,7 @@ from gunicorn import util
class BaseSocket(object): class BaseSocket(object):
def __init__(self, conf, log, fd=None): def __init__(self, conf, log, fd=None):
self.log = log self.log = log
self.conf = conf self.conf = conf
@ -24,13 +24,13 @@ class BaseSocket(object):
else: else:
sock = socket.fromfd(fd, self.FAMILY, socket.SOCK_STREAM) sock = socket.fromfd(fd, self.FAMILY, socket.SOCK_STREAM)
self.sock = self.set_options(sock, bound=(fd is not None)) self.sock = self.set_options(sock, bound=(fd is not None))
def __str__(self, name): def __str__(self, name):
return "<socket %d>" % self.sock.fileno() return "<socket %d>" % self.sock.fileno()
def __getattr__(self, name): def __getattr__(self, name):
return getattr(self.sock, name) return getattr(self.sock, name)
def set_options(self, sock, bound=False): def set_options(self, sock, bound=False):
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if not bound: if not bound:
@ -38,10 +38,10 @@ class BaseSocket(object):
sock.setblocking(0) sock.setblocking(0)
sock.listen(self.conf.backlog) sock.listen(self.conf.backlog)
return sock return sock
def bind(self, sock): def bind(self, sock):
sock.bind(self.address) sock.bind(self.address)
def close(self): def close(self):
try: try:
self.sock.close() self.sock.close()
@ -51,12 +51,12 @@ class BaseSocket(object):
del self.sock del self.sock
class TCPSocket(BaseSocket): class TCPSocket(BaseSocket):
FAMILY = socket.AF_INET FAMILY = socket.AF_INET
def __str__(self): def __str__(self):
return "http://%s:%d" % self.sock.getsockname() return "http://%s:%d" % self.sock.getsockname()
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)
@ -70,9 +70,9 @@ class TCP6Socket(TCPSocket):
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
def __init__(self, conf, log, fd=None): def __init__(self, conf, log, fd=None):
if fd is None: if fd is None:
try: try:
@ -80,16 +80,16 @@ class UnixSocket(BaseSocket):
except OSError: except OSError:
pass pass
super(UnixSocket, self).__init__(conf, log, fd=fd) super(UnixSocket, self).__init__(conf, log, fd=fd)
def __str__(self): def __str__(self):
return "unix:%s" % self.address return "unix:%s" % self.address
def bind(self, sock): def bind(self, sock):
old_umask = os.umask(self.conf.umask) old_umask = os.umask(self.conf.umask)
sock.bind(self.address) sock.bind(self.address)
util.chown(self.address, self.conf.uid, self.conf.gid) util.chown(self.address, self.conf.uid, self.conf.gid)
os.umask(old_umask) os.umask(old_umask)
def close(self): def close(self):
super(UnixSocket, self).close() super(UnixSocket, self).close()
os.unlink(self.address) os.unlink(self.address)
@ -103,7 +103,7 @@ def create_socket(conf, log):
""" """
# get it only once # get it only once
addr = conf.address addr = conf.address
if isinstance(addr, tuple): if isinstance(addr, tuple):
if util.is_ipv6(addr[0]): if util.is_ipv6(addr[0]):
sock_type = TCP6Socket sock_type = TCP6Socket
@ -127,7 +127,7 @@ def create_socket(conf, log):
# If we fail to create a socket from GUNICORN_FD # If we fail to create a socket from GUNICORN_FD
# we fall through and try and open the socket # we fall through and try and open the socket
# normally. # normally.
for i in range(5): for i in range(5):
try: try:
return sock_type(conf, log) return sock_type(conf, log)
@ -140,6 +140,6 @@ def create_socket(conf, log):
if i < 5: if i < 5:
log.error("Retrying in 1 second.") log.error("Retrying in 1 second.")
time.sleep(1) time.sleep(1)
log.error("Can't connect to %s", str(addr)) log.error("Can't connect to %s", str(addr))
sys.exit(1) sys.exit(1)

View File

@ -1,6 +1,6 @@
# -*- 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.
@ -55,11 +55,11 @@ hop_headers = set("""
te trailers transfer-encoding upgrade te trailers transfer-encoding upgrade
server date server date
""".split()) """.split())
try: try:
from setproctitle import setproctitle from setproctitle import setproctitle
def _setproctitle(title): def _setproctitle(title):
setproctitle("gunicorn: %s" % title) setproctitle("gunicorn: %s" % title)
except ImportError: except ImportError:
def _setproctitle(title): def _setproctitle(title):
return return
@ -82,9 +82,9 @@ def load_class(uri, default="sync", section="gunicorn.workers"):
if uri.startswith("#"): if uri.startswith("#"):
uri = uri[1:] uri = uri[1:]
return pkg_resources.load_entry_point("gunicorn", return pkg_resources.load_entry_point("gunicorn",
section, uri) section, uri)
except ImportError: except ImportError:
raise RuntimeError("class uri invalid or not found") raise RuntimeError("class uri invalid or not found")
klass = components.pop(-1) klass = components.pop(-1)
mod = __import__('.'.join(components)) mod = __import__('.'.join(components))
@ -103,10 +103,10 @@ def set_owner_process(uid,gid):
# versions of python < 2.6.2 don't manage unsigned int for # versions of python < 2.6.2 don't manage unsigned int for
# groups like on osx or fedora # groups like on osx or fedora
os.setgid(-ctypes.c_int(-gid).value) os.setgid(-ctypes.c_int(-gid).value)
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)
@ -122,7 +122,7 @@ def is_ipv6(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]
@ -136,7 +136,7 @@ def parse_address(netloc, default_port=8000):
host = "0.0.0.0" host = "0.0.0.0"
else: else:
host = netloc.lower() host = netloc.lower()
#get port #get port
netloc = netloc.split(']')[-1] netloc = netloc.split(']')[-1]
if ":" in netloc: if ":" in netloc:
@ -145,9 +145,9 @@ def parse_address(netloc, default_port=8000):
raise RuntimeError("%r is not a valid port number." % port) raise RuntimeError("%r is not a valid port number." % port)
port = int(port) port = int(port)
else: else:
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):
@ -158,7 +158,7 @@ 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)
@ -183,7 +183,7 @@ except ImportError:
def write_chunk(sock, data): def write_chunk(sock, data):
chunk = "".join(("%X\r\n" % len(data), data, "\r\n")) chunk = "".join(("%X\r\n" % len(data), data, "\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)
@ -199,7 +199,7 @@ def write_nonblock(sock, data, chunked=False):
sock.setblocking(1) sock.setblocking(1)
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)
@ -229,7 +229,7 @@ def write_error(sock, status_int, reason, mesg):
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)
if len(parts) == 1: if len(parts) == 1:
@ -264,7 +264,7 @@ def http_date(timestamp=None):
day, monthname[month], year, day, monthname[month], year,
hh, mm, ss) hh, mm, ss)
return s return s
def to_bytestring(s): def to_bytestring(s):
""" convert to bytestring an unicode """ """ convert to bytestring an unicode """
if not isinstance(s, basestring): if not isinstance(s, basestring):
@ -289,11 +289,11 @@ def daemonize():
if os.fork(): if os.fork():
os._exit(0) os._exit(0)
os.umask(0) os.umask(0)
maxfd = get_maxfd() maxfd = get_maxfd()
closerange(0, maxfd) closerange(0, maxfd)
os.open(REDIRECT_TO, os.O_RDWR) os.open(REDIRECT_TO, os.O_RDWR)
os.dup2(0, 1) os.dup2(0, 1)
os.dup2(0, 2) os.dup2(0, 2)

View File

@ -1,6 +1,6 @@
# -*- 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 __future__ import with_statement from __future__ import with_statement
@ -21,7 +21,7 @@ class AsyncWorker(base.Worker):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(AsyncWorker, self).__init__(*args, **kwargs) super(AsyncWorker, self).__init__(*args, **kwargs)
self.worker_connections = self.cfg.worker_connections self.worker_connections = self.cfg.worker_connections
def timeout_ctx(self): def timeout_ctx(self):
raise NotImplementedError() raise NotImplementedError()

View File

@ -1,6 +1,6 @@
# -*- 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.
@ -24,7 +24,7 @@ class Worker(object):
lambda x: getattr(signal, "SIG%s" % x), lambda x: getattr(signal, "SIG%s" % x),
"HUP QUIT INT TERM USR1 USR2 WINCH CHLD".split() "HUP QUIT INT TERM USR1 USR2 WINCH CHLD".split()
) )
PIPE = [] PIPE = []
def __init__(self, age, ppid, socket, app, timeout, cfg, log): def __init__(self, age, ppid, socket, app, timeout, cfg, log):
@ -47,11 +47,11 @@ class Worker(object):
self.log = log self.log = log
self.debug = cfg.debug self.debug = cfg.debug
self.address = self.socket.getsockname() self.address = self.socket.getsockname()
self.tmp = WorkerTmp(cfg) self.tmp = WorkerTmp(cfg)
def __str__(self): def __str__(self):
return "<Worker %s>" % self.pid return "<Worker %s>" % self.pid
@property @property
def pid(self): def pid(self):
return os.getpid() return os.getpid()
@ -88,7 +88,7 @@ class Worker(object):
self.PIPE = os.pipe() self.PIPE = os.pipe()
map(util.set_non_blocking, self.PIPE) map(util.set_non_blocking, self.PIPE)
map(util.close_on_exec, self.PIPE) map(util.close_on_exec, self.PIPE)
# Prevent fd inherientence # Prevent fd inherientence
util.close_on_exec(self.socket) util.close_on_exec(self.socket)
util.close_on_exec(self.tmp.fileno()) util.close_on_exec(self.tmp.fileno())
@ -96,9 +96,9 @@ class Worker(object):
self.log.close_on_exec() self.log.close_on_exec()
self.init_signals() self.init_signals()
self.wsgi = self.app.wsgi() self.wsgi = self.app.wsgi()
# Enter main run loop # Enter main run loop
self.booted = True self.booted = True
self.run() self.run()
@ -118,7 +118,7 @@ class Worker(object):
def handle_usr1(self, sig, frame): def handle_usr1(self, sig, frame):
self.log.reopen_files() self.log.reopen_files()
def handle_quit(self, sig, frame): def handle_quit(self, sig, frame):
self.alive = False self.alive = False
@ -135,10 +135,10 @@ class Worker(object):
if isinstance(exc, (InvalidRequestLine, InvalidRequestMethod, if isinstance(exc, (InvalidRequestLine, InvalidRequestMethod,
InvalidHTTPVersion, InvalidHeader, InvalidHeaderName,)): InvalidHTTPVersion, InvalidHeader, InvalidHeaderName,)):
status_int = 400 status_int = 400
reason = "Bad Request" reason = "Bad Request"
if isinstance(exc, InvalidRequestLine): if isinstance(exc, InvalidRequestLine):
mesg = "<p>Invalid Request Line '%s'</p>" % str(exc) mesg = "<p>Invalid Request Line '%s'</p>" % str(exc)
elif isinstance(exc, InvalidRequestMethod): elif isinstance(exc, InvalidRequestMethod):
@ -147,7 +147,7 @@ class Worker(object):
mesg = "<p>Invalid HTTP Version '%s'</p>" % str(exc) mesg = "<p>Invalid HTTP Version '%s'</p>" % str(exc)
elif isinstance(exc, (InvalidHeaderName, InvalidHeader,)): elif isinstance(exc, (InvalidHeaderName, InvalidHeader,)):
mesg = "<p>Invalid Header '%s'</p>" % str(exc) mesg = "<p>Invalid Header '%s'</p>" % str(exc)
if self.debug: if self.debug:
tb = traceback.format_exc() tb = traceback.format_exc()
mesg += "<h2>Traceback:</h2>\n<pre>%s</pre>" % tb mesg += "<h2>Traceback:</h2>\n<pre>%s</pre>" % tb
@ -156,7 +156,7 @@ class Worker(object):
util.write_error(client, status_int, reason, mesg) util.write_error(client, status_int, reason, mesg)
except: except:
self.log.warning("Failed to send error message.") self.log.warning("Failed to send error message.")
def handle_winch(self, sig, fname): def handle_winch(self, sig, fname):
# Ignore SIGWINCH in worker. Fixes a crash on OpenBSD. # Ignore SIGWINCH in worker. Fixes a crash on OpenBSD.
return return

View File

@ -1,6 +1,6 @@
# -*- 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 __future__ import with_statement from __future__ import with_statement
@ -28,9 +28,9 @@ class EventletWorker(AsyncWorker):
def init_process(self): def init_process(self):
hubs.use_hub() hubs.use_hub()
super(EventletWorker, self).init_process() super(EventletWorker, self).init_process()
def timeout_ctx(self): def timeout_ctx(self):
return eventlet.Timeout(self.cfg.keepalive, False) return eventlet.Timeout(self.cfg.keepalive, False)
def run(self): def run(self):
self.socket = GreenSocket(family_or_realsock=self.socket.sock) self.socket = GreenSocket(family_or_realsock=self.socket.sock)

View File

@ -1,11 +1,11 @@
# -*- 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 datetime import datetime from datetime import datetime
from gunicorn.workers.ggevent import BASE_WSGI_ENV, GeventWorker from gunicorn.workers.ggevent import BASE_WSGI_ENV, GeventWorker
from gevent import wsgi from gevent import wsgi
@ -30,9 +30,9 @@ class WSGIHandler(wsgi.WSGIHandler):
self.time_start = datetime.now() self.time_start = datetime.now()
super(WSGIHandler, self).handle() super(WSGIHandler, self).handle()
class WSGIServer(wsgi.WSGIServer): class WSGIServer(wsgi.WSGIServer):
base_env = BASE_WSGI_ENV base_env = BASE_WSGI_ENV
class GeventWSGIWorker(GeventWorker): class GeventWSGIWorker(GeventWorker):
"The Gevent StreamServer based workers." "The Gevent StreamServer based workers."

View File

@ -1,6 +1,6 @@
# -*- 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.
import os import os
@ -19,7 +19,7 @@ from gunicorn.workers.base import Worker
from gunicorn import __version__ as gversion from gunicorn import __version__ as gversion
class TornadoWorker(Worker): class TornadoWorker(Worker):
@classmethod @classmethod
def setup(cls): def setup(cls):
web = sys.modules.pop("tornado.web") web = sys.modules.pop("tornado.web")
@ -29,18 +29,18 @@ class TornadoWorker(Worker):
self._headers["Server"] += " (Gunicorn/%s)" % gversion self._headers["Server"] += " (Gunicorn/%s)" % gversion
web.RequestHandler.clear = clear web.RequestHandler.clear = clear
sys.modules["tornado.web"] = web sys.modules["tornado.web"] = web
def handle_quit(self, sig, frame): def handle_quit(self, sig, frame):
super(TornadoWorker, self).handle_quit(sig, frame) super(TornadoWorker, self).handle_quit(sig, frame)
self.ioloop.stop() self.ioloop.stop()
def watchdog(self): def watchdog(self):
self.notify() self.notify()
if self.ppid != os.getppid(): if self.ppid != os.getppid():
self.log.info("Parent changed, shutting down: %s", self) self.log.info("Parent changed, shutting down: %s", self)
self.ioloop.stop() self.ioloop.stop()
def run(self): def run(self):
self.socket.setblocking(0) self.socket.setblocking(0)
self.ioloop = IOLoop.instance() self.ioloop = IOLoop.instance()

View File

@ -1,6 +1,6 @@
# -*- 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.
# #
@ -16,7 +16,7 @@ import gunicorn.util as util
import gunicorn.workers.base as base import gunicorn.workers.base as base
class SyncWorker(base.Worker): class SyncWorker(base.Worker):
def run(self): def run(self):
# self.socket appears to lose its blocking status after # self.socket appears to lose its blocking status after
# we fork in the arbiter. Reset it here. # we fork in the arbiter. Reset it here.
@ -24,7 +24,7 @@ class SyncWorker(base.Worker):
while self.alive: while self.alive:
self.notify() self.notify()
# Accept a connection. If we get an error telling us # Accept a connection. If we get an error telling us
# that no connection is waiting we fall down to the # that no connection is waiting we fall down to the
# select which is where we'll wait for a bit for new # select which is where we'll wait for a bit for new
@ -48,7 +48,7 @@ class SyncWorker(base.Worker):
if self.ppid != os.getppid(): if self.ppid != os.getppid():
self.log.info("Parent changed, shutting down: %s", self) self.log.info("Parent changed, shutting down: %s", self)
return return
try: try:
self.notify() self.notify()
ret = select.select([self.socket], [], self.PIPE, self.timeout) ret = select.select([self.socket], [], self.PIPE, self.timeout)
@ -63,7 +63,7 @@ class SyncWorker(base.Worker):
else: else:
return return
raise raise
def handle(self, client, addr): def handle(self, client, addr):
try: try:
parser = http.RequestParser(client) parser = http.RequestParser(client)
@ -78,7 +78,7 @@ class SyncWorker(base.Worker):
self.log.debug("Ignoring EPIPE") self.log.debug("Ignoring EPIPE")
except Exception, e: except Exception, e:
self.handle_error(client, e) self.handle_error(client, e)
finally: finally:
util.close(client) util.close(client)
def handle_request(self, req, client, addr): def handle_request(self, req, client, addr):
@ -113,7 +113,7 @@ class SyncWorker(base.Worker):
raise raise
except Exception, e: except Exception, e:
# Only send back traceback in HTTP in debug mode. # Only send back traceback in HTTP in debug mode.
self.handle_error(client, e) self.handle_error(client, e)
return return
finally: finally:
try: try:

View File

@ -1,6 +1,6 @@
# -*- 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.
import os import os
@ -13,7 +13,7 @@ class WorkerTmp(object):
def __init__(self, cfg): def __init__(self, cfg):
old_umask = os.umask(cfg.umask) old_umask = os.umask(cfg.umask)
fd, name = tempfile.mkstemp(prefix="wgunicorn-") fd, name = tempfile.mkstemp(prefix="wgunicorn-")
# allows the process to write to the file # allows the process to write to the file
util.chown(name, cfg.uid, cfg.gid) util.chown(name, cfg.uid, cfg.gid)
os.umask(old_umask) os.umask(old_umask)
@ -28,7 +28,7 @@ class WorkerTmp(object):
self.spinner = 0 self.spinner = 0
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)
@ -42,6 +42,6 @@ class WorkerTmp(object):
def fileno(self): def fileno(self):
return self._tmp.fileno() return self._tmp.fileno()
def close(self): def close(self):
return self._tmp.close() return self._tmp.close()