bump version to 24.0.0, remove sphinx docs

This commit is contained in:
Benoit Chesneau 2026-01-23 01:12:46 +01:00
parent f9df39f600
commit 58d803977d
75 changed files with 1 additions and 6452 deletions

View File

@ -1,160 +0,0 @@
# Makefile for Sphinx documentation
#
# if you want to compare this file to current sphinx defaults, recreate it:
# BUILDDIR=build sphinx-quickstart --sep --extensions=gunicorn_ext --templatedir=_templates --makefile --batchfile --no-use-make-mode --master=index
# You can set these variables from the command line.
PYTHON = python
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: help clean html htmlview dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " htmlview to open the index page built by the html target in your browser"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
htmlview: html
$(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')"
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Gunicorn.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Gunicorn.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/Gunicorn"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Gunicorn"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

View File

@ -1,19 +0,0 @@
Generate Documentation
======================
Requirements
------------
To generate documentation you need to install:
- Python >= 3.7
- Sphinx (https://www.sphinx-doc.org/)
Generate html
-------------
::
$ make html
The command generates html document inside ``build/html`` dir.

View File

@ -1,102 +0,0 @@
import os
import inspect
from docutils import nodes, utils
import gunicorn.config as guncfg
HEAD = """\
.. Please update gunicorn/config.py instead.
.. _settings:
Settings
========
This is an exhaustive list of settings for Gunicorn. Some settings are only
able to be set from a configuration file. The setting name is what should be
used in the configuration file. The command line arguments are listed as well
for reference on setting at the command line.
.. note::
Settings can be specified by using environment variable
``GUNICORN_CMD_ARGS``. All available command line arguments can be used.
For example, to specify the bind address and number of workers::
$ GUNICORN_CMD_ARGS="--bind=127.0.0.1 --workers=3" gunicorn app:app
.. versionadded:: 19.7
"""
ISSUE_URI = 'https://github.com/benoitc/gunicorn/issues/%s'
PULL_REQUEST_URI = 'https://github.com/benoitc/gunicorn/pull/%s'
def format_settings(app):
settings_file = os.path.join(app.srcdir, "settings.rst")
ret = []
known_settings = sorted(guncfg.KNOWN_SETTINGS, key=lambda s: s.section)
for i, s in enumerate(known_settings):
if i == 0 or s.section != known_settings[i - 1].section:
ret.append("%s\n%s\n\n" % (s.section, "-" * len(s.section)))
ret.append(fmt_setting(s))
with open(settings_file, 'w') as settings:
settings.write(HEAD)
settings.write(''.join(ret))
def fmt_setting(s):
if hasattr(s, "default_doc"):
val = s.default_doc
elif callable(s.default):
val = inspect.getsource(s.default)
val = "\n".join(" %s" % line for line in val.splitlines())
val = "\n\n.. code-block:: python\n\n" + val
elif s.default == '':
val = "``''``"
else:
val = "``%r``" % s.default
if s.cli and s.meta:
cli = " or ".join("``%s %s``" % (arg, s.meta) for arg in s.cli)
elif s.cli:
cli = " or ".join("``%s``" % arg for arg in s.cli)
else:
cli = ""
out = []
out.append(".. _%s:\n" % s.name.replace("_", "-"))
out.append("``%s``" % s.name)
out.append("~" * (len(s.name) + 4))
out.append("")
if s.cli:
out.append("**Command line:** %s" % cli)
out.append("")
out.append("**Default:** %s" % val)
out.append("")
out.append(s.desc)
out.append("")
out.append("")
return "\n".join(out)
def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
issue = utils.unescape(text)
text = 'issue ' + issue
refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue)
return [refnode], []
def pull_request_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
issue = utils.unescape(text)
text = 'pull request ' + issue
refnode = nodes.reference(text, text, refuri=PULL_REQUEST_URI % issue)
return [refnode], []
def setup(app):
app.connect('builder-inited', format_settings)
app.add_role('issue', issue_role)
app.add_role('pr', pull_request_role)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@ -1,119 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="740.18402"
height="161.62476"
id="svg4375">
<defs
id="defs4377">
<linearGradient
x1="-403.07309"
y1="-40.681377"
x2="-560.61346"
y2="-32.881535"
id="linearGradient4343"
xlink:href="#linearGradient3354-9"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3354-9">
<stop
id="stop3356-9"
style="stop-color:#959595;stop-opacity:1"
offset="0" />
<stop
id="stop3358-9"
style="stop-color:#cccccc;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="-403.07309"
y1="-40.681377"
x2="-560.61346"
y2="-32.881535"
id="linearGradient3269"
xlink:href="#linearGradient3354-9"
gradientUnits="userSpaceOnUse" />
</defs>
<metadata
id="metadata4380">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(215.61577,-659.72777)"
id="layer1">
<g
transform="matrix(0.95410088,0,0,1.0481072,336.12082,766.65951)"
id="text3109-8-2-3-2"
style="font-size:118.26729584px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#4d4d4d;fill-opacity:1;stroke:none;font-family:Century Gothic;-inkscape-font-specification:Century Gothic Bold">
<path
d="m -192.30737,-56.190303 15.93837,0 0,30.259797 c -2e-5,5.890292 0.40421,9.990375 1.2127,12.300261 0.80844,2.271427 2.09814,4.042355 3.8691,5.3127882 1.8094,1.2704632 4.02306,1.9056873 6.64098,1.9056742 2.61786,1.31e-5 4.83152,-0.6159618 6.64099,-1.8479265 1.84788,-1.2704333 3.21458,-3.1183579 4.10009,-5.5437799 0.65442,-1.809405 0.98166,-5.678498 0.98171,-11.607288 l 0,-30.779526 15.82287,0 0,26.621691 c -6e-5,10.972089 -0.86628,18.479283 -2.59865,22.5216047 -2.11747,4.9278127 -5.23585,8.7199081 -9.35513,11.3762975 -4.11938,2.6178955 -9.35517,3.9268422 -15.70737,3.9268438 -6.89126,-1.6e-6 -12.47353,-1.5399388 -16.74684,-4.6198163 -4.23484,-3.07987137 -7.21847,-7.3724463 -8.95089,-12.8777377 -1.23196,-3.811329 -1.84793,-10.741046 -1.84793,-20.789173 l 0,-26.15971"
id="path2910-3"
style="fill:#4d4d4d" />
<path
d="m -130.62894,-56.190303 15.70737,0 0,6.409995 c 3.58033,-3.002821 6.8142,-5.081736 9.70161,-6.236752 2.92585,-1.193388 5.909485,-1.790114 8.950903,-1.790178 6.236704,6.4e-5 11.530238,2.175225 15.880619,6.52549 3.657292,3.695907 5.485968,9.162684 5.486031,16.400348 l 0,41.5205983 -15.591879,0 0,-27.5456543 c -4.9e-5,-7.507166 -0.346534,-12.492713 -1.039459,-14.956655 -0.65452,-2.463857 -1.828723,-4.331031 -3.52261,-5.601527 -1.655476,-1.308899 -3.71514,-1.963372 -6.179015,-1.963422 -3.1954,5e-5 -5.94804,1.078006 -8.25791,3.233871 -2.27144,2.117461 -3.84987,5.062591 -4.73531,8.835399 -0.46201,1.963458 -0.693,6.217534 -0.69298,12.762242 l 0,25.2357463 -15.70737,0 0,-62.8295013"
id="path2912-9"
style="fill:#4d4d4d" />
<path
d="m -58.382674,-82.061274 c 2.771873,8.9e-5 5.139526,1.001048 7.102968,3.002881 2.001897,2.002004 3.002856,4.427405 3.00288,7.276211 -2.4e-5,2.810463 -0.981734,5.216615 -2.945133,7.218462 -1.963441,1.963492 -4.311845,2.945202 -7.04522,2.945133 -2.810399,6.9e-5 -5.216551,-1.000891 -7.218462,-3.00288 -1.963427,-2.040346 -2.945137,-4.504245 -2.945133,-7.391706 -4e-6,-2.771809 0.981706,-5.139462 2.945133,-7.102968 1.963413,-1.963334 4.331066,-2.945044 7.102967,-2.945133 m -7.911435,25.870971 15.82287,0 0,62.8295013 -15.82287,0 0,-62.8295013"
id="path2914-9"
style="fill:#4d4d4d" />
<path
d="m 22.756753,-43.485808 -13.1087298,7.218463 c -2.4639564,-2.579352 -4.9086068,-4.369529 -7.3339592,-5.370536 -2.38695243,-1.000911 -5.1973376,-1.501391 -8.4311656,-1.501441 -5.8902994,5e-5 -10.6641044,1.770978 -14.3214284,5.312789 -3.618878,3.503402 -5.428304,8.007718 -5.428283,13.512962 -2.1e-5,5.351313 1.751657,9.720885 5.25504,13.108729 3.503331,3.3878798 8.103892,5.0818107 13.8016994,5.0817979 7.04517317,1.28e-5 12.5312,-2.4061391 16.4580968,-7.2184629 L 22.06378,-4.8525946 C 15.326486,3.8865605 5.8173728,8.2561324 -6.4635876,8.256134 -17.512676,8.2561324 -26.174822,4.9837658 -32.450051,-1.5609755 c -6.23676,-6.544725 -9.355133,-14.2059125 -9.355128,-22.9835855 -5e-6,-6.082721 1.520683,-11.684243 4.562068,-16.804582 3.041367,-5.120243 7.276194,-9.143329 12.704495,-12.06927 5.466754,-2.925821 11.568754,-4.388761 18.3060194,-4.388825 6.23670517,6.4e-5 11.838228,1.251263 16.8045846,3.7536 4.96624,2.463961 9.027824,5.986567 12.184765,10.56783"
id="path2916-7"
style="fill:#4d4d4d" />
<path
d="m 61.798097,-57.807238 c 5.928721,6.4e-5 11.491744,1.482254 16.689087,4.446573 5.235731,2.964439 9.316569,6.987525 12.242523,12.06927 2.925814,5.08184 4.388768,10.567867 4.388838,16.458095 -7e-5,5.92879 -1.482264,11.472564 -4.446588,16.6313386 C 87.746013,-3.0431569 83.742165,0.99917828 78.660426,3.9250563 73.57858,6.8124412 67.977058,8.2561324 61.855845,8.256134 52.847175,8.2561324 45.147489,5.0607627 38.756764,-1.3299847 32.404509,-7.7592146 29.228388,-15.555147 29.228393,-24.717804 c -5e-6,-9.817069 3.599598,-17.997985 10.79882,-24.542774 6.313727,-5.697712 13.570681,-8.546596 21.770884,-8.54666 m 0.230991,14.841159 c -4.889338,5e-5 -8.970172,1.71323 -12.242513,5.139546 -3.233893,3.387906 -4.850827,7.738229 -4.850807,13.050981 -2e-5,5.466808 1.597664,9.894128 4.79306,13.281972 3.233842,3.3878795 7.314676,5.0818105 12.242513,5.0817974 4.927761,1.31e-5 9.027844,-1.7131671 12.30026,-5.1395454 3.272317,-3.426342 4.908505,-7.834413 4.908555,-13.224224 -5e-5,-5.389749 -1.616989,-9.759321 -4.850807,-13.108729 -3.19542,-3.387817 -7.295502,-5.081748 -12.300261,-5.081798"
id="path2918-0"
style="fill:#4d4d4d" />
<path
d="m 101.59025,-56.190303 13.51297,0 0,7.911436 c 1.46292,-3.118318 3.40709,-5.485972 5.83251,-7.102968 2.42538,-1.616872 5.08177,-2.425339 7.96919,-2.425403 2.04038,6.4e-5 4.17705,0.539042 6.40999,1.616935 l -4.90855,13.570711 c -1.84796,-0.923913 -3.36865,-1.385895 -4.56207,-1.385945 -2.42543,5e-5 -4.4851,1.501489 -6.179,4.504321 -1.65546,3.002923 -2.48318,8.893183 -2.48316,17.670797 l 0.0577,3.060628 0,25.4089893 -15.64963,0 0,-62.8295013"
id="path2920-3"
style="fill:#4d4d4d" />
<path
d="m 141.78656,-56.190303 15.70737,0 0,6.409995 c 3.58033,-3.002821 6.8142,-5.081736 9.70162,-6.236752 2.92584,-1.193388 5.90947,-1.790114 8.95089,-1.790178 6.2367,6.4e-5 11.53024,2.175225 15.88062,6.52549 3.65729,3.695907 5.48597,9.162684 5.48603,16.400348 l 0,41.5205983 -15.59188,0 0,-27.5456543 c -5e-5,-7.507166 -0.34653,-12.492713 -1.03946,-14.956655 -0.65452,-2.463857 -1.82872,-4.331031 -3.52261,-5.601527 -1.65547,-1.308899 -3.71514,-1.963372 -6.179,-1.963422 -3.19541,5e-5 -5.94805,1.078006 -8.25792,3.233871 -2.27144,2.117461 -3.84988,5.062591 -4.73532,8.835399 -0.462,1.963458 -0.69299,6.217534 -0.69297,12.762242 l 0,25.2357463 -15.70737,0 0,-62.8295013"
id="path2922-9"
style="fill:#4d4d4d" />
</g>
<g
transform="matrix(1.4868765,0,0,1.4868765,477.80324,740.33267)"
id="g2886-8"
style="fill:#4d4d4d;fill-opacity:1">
<text
x="-299.4765"
y="15.69857"
transform="scale(0.95410088,1.0481072)"
id="text3109-8-2-3-7-6"
xml:space="preserve"
style="font-size:127.35551453px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#4d4d4d;fill-opacity:1;stroke:none;font-family:Palatino;-inkscape-font-specification:Palatino Bold"><tspan
x="-299.4765"
y="15.69857"
id="tspan2884-5"
style="font-size:127.35551453px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#4d4d4d;fill-opacity:1;font-family:Palatino;-inkscape-font-specification:Palatino Bold">g</tspan></text>
</g>
<path
d="m -339.89735,-32.881535 a 120.17799,8.4974337 0 1 1 -240.35599,0 120.17799,8.4974337 0 1 1 240.35599,0 z"
transform="matrix(1.1060606,0,0,1.1060606,426.17959,848.32285)"
id="path3423-1"
style="opacity:0.26353838;fill:url(#linearGradient3269);fill-opacity:1;stroke:none" />
<path
d="m -100.65527,815.73848 c -2.57334,-0.81915 -2.58247,-1.18087 -0.21166,-8.37918 2.367628,-7.18862 1.282568,-13.86445 -3.10637,-19.11195 -5.96822,-7.13575 -8.84216,-13.22467 -9.75823,-20.67444 -0.78646,-6.3958 -1.03575,-6.90285 -3.6397,-7.40279 -1.74646,-0.33531 -4.15929,0.32877 -9.90965,2.72745 -8.36615,3.4898 -10.35876,5.02218 -12.33291,9.4843 -1.03707,2.34406 -1.16172,3.7482 -0.57348,6.45967 0.7183,3.31089 3.66212,8.64054 4.77653,8.64768 0.29081,0.002 1.89748,1.1023 3.57036,2.44541 2.77589,2.22869 2.96643,2.61592 2.18093,4.43265 -1.70673,3.94745 -5.76177,8.73342 -7.39962,8.73342 -0.91894,0 -4.67154,-2.62848 -8.80223,-6.16546 -8.11348,-6.94729 -8.45354,-7.64379 -9.29155,-19.03126 -0.99988,-13.58711 2.34128,-19.92818 17.22216,-32.68537 l 9.33328,-8.0013 0.5961,-4.8534 c 0.61452,-5.00328 -0.25183,-16.91684 -1.70841,-23.49298 -0.86051,-3.885 -3.7003,-7.58525 -6.39519,-8.33292 -2.93605,-0.8146 -4.65723,0.86613 -6.89082,6.72892 -2.40994,6.32567 -4.71315,8.53245 -8.90528,8.53245 -2.61108,0 -5.04774,-1.67029 -6.73027,-4.61349 -1.20562,-2.10894 -1.90545,-14.77861 -1.18473,-21.44783 0.34669,-3.20813 0.36656,-6.45629 0.0442,-7.21814 -0.52459,-1.23963 -5.04199,-3.92118 -15.69218,-9.31491 -1.93608,-0.98052 -4.19318,-2.30073 -5.01577,-2.93381 -0.82258,-0.63307 -2.95712,-1.79702 -4.74342,-2.58654 -4.0461,-1.78831 -14.59582,-7.95686 -13.60818,-7.95686 1.86847,0 9.78678,2.4371 14.00212,4.30958 2.57327,1.14308 5.0365,2.07831 5.47385,2.07831 0.43736,0 5.39838,1.59698 11.0245,3.54885 5.62613,1.95185 10.76835,3.54883 11.42716,3.54883 1.56481,0 1.81019,-1.35379 1.30876,-7.22052 -0.22777,-2.66503 -0.21772,-4.84552 0.0224,-4.84552 0.24005,0 1.27682,0.51453 2.3039,1.14339 3.13787,1.92125 9.88743,3.09794 17.82053,3.10678 7.58555,0.009 17.48687,1.51346 21.27112,3.23319 5.42864,2.46702 11.72565,10.17235 19.713658,24.12261 5.55341,9.69849 11.5205,13.80519 20.07216,13.81419 3.45705,0.004 12.6805,-1.42134 25.17062,-3.88871 10.29868,-2.03446 23.894192,-2.49173 29.171452,-0.98115 6.43791,1.8428 14.95039,6.76935 21.98861,12.72577 6.58741,5.57491 7.60197,6.81262 11.64852,14.21045 4.82928,8.82878 10.15926,21.37645 14.899,35.07479 0.67537,1.95185 2.10182,5.23512 3.1699,7.29614 2.84984,5.49914 2.70779,5.83455 -2.47093,5.83455 -5.62088,0 -8.25697,-0.88636 -11.94164,-4.01528 -3.534,-3.00098 -4.45715,-4.83696 -9.98855,-19.86556 -2.83329,-7.6979 -5.59135,-12.31728 -7.35421,-12.31728 -1.20786,0 -3.65266,8.24914 -3.65266,12.32476 0,2.89469 1.814,6.8052 6.50386,14.02068 7.61871,11.72159 11.62643,28.29168 10.02221,41.4373 l -0.69293,5.67814 -5.07747,0.21136 c -7.99385,0.33278 -7.91382,0.44389 -7.91382,-10.98681 0,-12.16922 -0.82877,-14.80464 -6.19901,-19.71247 -2.2306,-2.03853 -7.23508,-7.83031 -11.12107,-12.87062 -3.88602,-5.04032 -7.60749,-9.16422 -8.26995,-9.16422 -1.52225,0 -2.28133,4.14488 -2.36225,12.8988 -0.0532,5.76495 -0.28025,6.74074 -1.98112,8.5172 -4.611042,4.81598 -7.847772,13.58519 -9.843172,26.668 -0.44167,2.89579 -0.82033,3.43751 -2.6974,3.85899 -2.76002,0.61973 -10.40844,0.72118 -11.06755,0.14681 -0.56842,-0.49534 0.42766,-8.35904 2.68721,-21.21493 0.85765,-4.87965 1.79377,-11.42725 2.08028,-14.55022 0.51005,-5.55953 -0.62987,-15.97557 -1.97899,-18.08289 -0.56095,-0.8762 -3.4173,-1.06606 -16.77722,-1.11512 -8.85564,-0.0325 -18.56749,-0.32384 -21.58186,-0.64737 l -5.48072,-0.58825 0,2.43214 c 0,2.60447 0.66758,4.90008 5.1317,17.6466 1.57224,4.48928 3.85053,11.33318 5.06287,15.20868 l 2.20425,7.04637 -1.86007,5.72944 c -1.02305,3.15119 -2.54137,6.92717 -3.37407,8.39107 -1.46872,2.58204 -1.64095,2.65994 -5.76025,2.60558 -2.33545,-0.0308 -5.28634,-0.38711 -6.557538,-0.79175 z"
id="path3046-2-3-0"
style="fill:#499848;fill-opacity:1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,190 +0,0 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
set I18NSPHINXOPTS=%SPHINXOPTS% source
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Gunicorn.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Gunicorn.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end

View File

View File

@ -1 +0,0 @@
gunicorn.org

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/index.html#community">
<title>Green Unicorn - Community</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/index.html#community">here</a>
</h2>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
<title>Green Unicorn - Configuration</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/">here</a>
</h2>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
<title>Green Unicorn - Configure</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/">here</a>
</h2>
</body>
</html>

View File

@ -1,402 +0,0 @@
html,body {
margin: 0;
padding: 0;
}
h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,cite,
code,del,dfn,em,img,q,s,samp,small,strike,strong,sub,sup,tt,var,
dd,dl,dt,li,ol,ul,fieldset,form,label,legend,button,table,caption,
tbody,tfoot,thead,tr,th,td {
margin: 0;
padding: 0;
border: 0;
font: inherit;
vertical-align: baseline;
}
ol,ul {
list-style: none;
}
html {
overflow-y: scroll;
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
a:hover, a:active, a:focus {
outline: 0;
}
img {
border: 0;
-ms-interpolation-mode: bicubic;
}
body {
background: #F8F8F3;
margin: 0;
font: 14px/1.4 "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, "Lucida Grande", sans-serif;
color: #67686B;
height: auto;
}
a,
a:hover {
text-decoration: none;
}
.clearall {
clear: both;
display: block;
overflow: hidden;
visibility: hidden;
width: 0;
height: 0;
}
.logo-wrapper {
border-bottom: 1px solid #2A8729;
}
.latest {
width: 150px;
top: 0;
display: block;
float: right;
font-weight: bold;
}
.logo-div {
width: 1000px;
margin: 0 auto;
padding: 5px;
height: 72px;
}
.logo {
width: 250px;
margin: 0 auto;
height: 119px;
background: url(../images/logo-bottom.png) no-repeat bottom center;
position: relative;
z-index: 99999;
}
.banner-wrapper {
background: url(../images/banner-bg.jpg) repeat;
display: block;
width: 100%;
min-height: 365px;
margin-top: 1px;
margin-bottom: 1px;
}
.banner {
width: 1000px;
margin: 0 auto;
padding: 15px;
}
.title {
width: 250px;
margin: 0 auto;
margin-top: 32px;
text-align:center;
}
.banner h1 {
font-size: 20px;
color: #FFF;
margin: 15px 10px 0;
padding: 5px 40px;
text-align: center;
line-height: 28px;
}
.greenbutton {
background: url(../images/greenbutton.jpg) repeat-x;
height: 54px;
width: 224px;
line-height: 54px;
display: inline-block;
text-align: center;
border-radius: 3px;
border: solid 1px #1D692D;
color: #fff;
font-size: 22px;
letter-spacing: 1px;
text-shadow: 1px 1px 1px #000;
}
.greenbutton:hover {
background: url(../images/greenbutton.jpg) repeat-x bottom;
}
.redbutton {
background: url(../images/redbutton.jpg) repeat-x;
height: 54px;
width: 224px;
line-height: 54px;
display: inline-block;
text-align: center;
border-radius: 3px;
border: solid 1px #7D180A;
color: #fff;
font-size: 22px;
letter-spacing: 1px;
text-shadow: 1px 1px 1px #000;
}
.redbutton:hover {
background: url(../images/redbutton.jpg) repeat-x bottom;
}
.banner-button {
width: 460px;
margin: 0 auto;
margin-top: 30px;
}
.banner-link {
width: 250px;
margin: 0 auto;
margin-top: 15px;
padding: 5px;
text-align: center;
}
.banner-link a {
color: #fff;
font-weight: 700;
letter-spacing: 1px;
}
.banner-link a:hover {
color: #000;
}
.mid-wrapper {
width: 100%;
border-top: 1px solid #2A8729;
padding-top: 15px;
}
.tabs {
width: 1000px;
margin: 0 auto;
padding: 3px;
margin-top: 5px;
margin-bottom: 25px;
}
.tab-bar li {
width: 230px;
padding: 3px;
text-align: center;
float: left;
margin-right: 5px;
margin-left: 6px;
}
.tab-bar li a {
display: inline-block;
}
.tab-bar li a:hover > p,
.tab-bar li a:hover > h2 {
color: #1D692D;
}
.tab-bar li a p,
.tab-bar li a h2 {
color: #404028;
margin-top: 8px;
line-height: 1.2;
}
.tab-bar li a h2 {
font-weight: 700;
text-transform: uppercase;
}
.withborder {
background: url(../images/separator.jpg) no-repeat;
}
.gabout, .gcommunity, .gdownloads, .gdocuments {
height: 80px;
width: 230px;
padding-top: 118px;
}
.gabout {
background: url(../images/about.jpg) no-repeat 50% 0;
}
.gcommunity {
background: url(../images/community.jpg) no-repeat 50% 0;
}
.gdocuments {
background: url(../images/documents.jpg) no-repeat 50% 0;
}
.gdownloads {
background: url(../images/downloads.jpg) no-repeat 50% 0;
}
.tabs li.active a,
.gabout:hover,
.gcommunity:hover,
.gdocuments:hover,
.gdownloads:hover {
background-position: 50% -220px;
}
.tabs div {
display:none;
}
.tabs div.active {
display: block;
}
.tab-box {
color: #3F3F27;
border: 1px solid #DDDDD5;
padding: 25px 35px;
position: relative;
margin-top: 20px;
border-radius: 3px;
}
.tab-box h1 {
font-size: 28px;
color: #2A8729;
}
.tab-box p {
margin: 0 0 9px;
}
.tab-box ul {
padding-left: 40px;
}
.tab-box li {
list-style: disc;
margin: 0 0 9px;
}
.tab-box a,
.latest a {
color: #3F3F27;
text-decoration: underline;
}
.tab-box a:hover,
.latest a:hover {
color: #1D692D;
}
.arrow {
background: url(../images/arrow.png) no-repeat;
position: absolute;
left: 115px;
top: -7px;
height: 10px;
width: 20px;
}
pre {
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
font-size: 14px;
color: #333333;
display: block;
padding: 8.5px;
margin: 0 0 9px;
font-size: 14px;
line-height: 18px;
word-break: break-all;
word-wrap: break-word;
white-space: pre;
white-space: pre-wrap;
background-color: #EEFFCC;
border-top: 1px solid #A9CC99;
border-bottom: 1px solid #A9CC99;
}
.user-wrapper {
background: url(../images/banner-bg.jpg) repeat;
height: 110px;
}
.users {
width: 1000px;
padding: 20px 5px;
margin: 0 auto;
color: #fff;
}
.users h3 {
font-size: 12px;
margin-left: 5px;
padding-top: 15px;
}
.users h2 {
font-size: 26px;
margin-left: 5px;
}
.users .left-details {
width: 120px;
float: left;
height: 66px;
background: url(../images/footer-arrow.png) no-repeat top right;
padding-right: 15px;
text-align: right;
}
.users .company-logos {
float: left;
width: 820px;
height: 70px;
margin-left: 20px;
}
.users .company-logos a img {
float: left;
border: solid 1px #004000;
margin: 0 6px;
}
.users .company-logos a:hover img {
border: solid 1px #000;
}
.footer {
background-color: #F8F8F3;
display: block;
height: 70px;
}
.footer .footer-wp {
margin: 0 auto;
padding: 15px 5px;
width: 930px;
background: url(../images/footer-logo.jpg) no-repeat 0 50%;
padding-left: 70px;
}
.footer-wp a {
color: #3F3F27;
text-decoration: underline;
}
.footer-wp a:hover {
color: #1D692D;
}

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/index.html#deployment">
<title>Green Unicorn - Deployment</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/index.html#deployment">here</a>
</h2>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/index.html#deployment">
<title>Green Unicorn - Deployment</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/index.html#deployment">here</a>
</h2>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
<title>Green Unicorn - Design</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/">here</a>
</h2>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
<title>Green Unicorn - FAQ</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/">here</a>
</h2>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,185 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Gunicorn - Python WSGI HTTP Server for UNIX</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<link rel="stylesheet" type="text/css" href="css/style.css" />
<link rel="shortcut icon" href="images/favicon.png" type="image/x-icon">
<link rel="alternate"
href="https://github.com/benoitc/gunicorn/commits/master.atom"
type="application/atom+xml" title="Gunicorn commits">
</head>
<body>
<div class="logo-wrapper">
<div class="logo-div">
<div class="latest">
Latest version: <strong><a
href="https://docs.gunicorn.org/en/stable/">23.0.0</a></strong>
</div>
<div class="logo"><img src="images/logo.jpg" ></div>
</div>
</div>
<div class="banner-wrapper">
<div class="banner">
<div class="title"><img src="images/title.png"></div>
<h1>Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.</h1>
<div class="banner-button">
<a href="https://github.com/benoitc/gunicorn" title="View source at github" class="greenbutton">View source</a>
<a href="http://pypi.python.org/pypi/gunicorn/" title="Download from PyPi" class="redbutton">Download</a>
</div>
</div>
</div>
<div class="mid-wrapper">
<div class="tabs">
<ul class="tab-bar">
<li class="active">
<a href="#quickstart" title="Quickstart" class="gabout">
<h2>Quickstart</h2>
<p>Read the quickstart guide to get started using Gunicorn.</p>
</a>
</li>
<li class="withborder">
<a href="#deployment" title="Deployment" class="gdownloads">
<h2>Deployment</h2>
<p>Learn how to deploy the Gunicorn server.</p>
</a>
</li>
<li class="withborder">
<a href="#community" title="Community" class="gcommunity">
<h2>Community</h2>
<p>Get in touch with the community.</p>
</a>
</li>
<li class="withborder">
<a href="#docs" title="Documentation" class="gdocuments">
<h2>Documentation</h2>
<p>Read the documentation to learn more about Gunicorn.</p>
</a>
</li>
</ul>
<div class="clearall active"></div>
<div class="tab-box active" data-tab="quickstart">
<h1>Installation</h1>
<p>
Here's a quick rundown on how to get started with Gunicorn. For more details read the <a href="http://docs.gunicorn.org/en/stable/">documentation</a>.
</p>
<pre>
$ pip install gunicorn
$ cat myapp.py
def app(environ, start_response):
data = b"Hello, World!\n"
start_response("200 OK", [
("Content-Type", "text/plain"),
("Content-Length", str(len(data)))
])
return iter([data])
$ gunicorn -w 4 myapp:app
[2014-09-10 10:22:28 +0000] [30869] [INFO] Listening at: http://127.0.0.1:8000 (30869)
[2014-09-10 10:22:28 +0000] [30869] [INFO] Using worker: sync
[2014-09-10 10:22:28 +0000] [30874] [INFO] Booting worker with pid: 30874
[2014-09-10 10:22:28 +0000] [30875] [INFO] Booting worker with pid: 30875
[2014-09-10 10:22:28 +0000] [30876] [INFO] Booting worker with pid: 30876
[2014-09-10 10:22:28 +0000] [30877] [INFO] Booting worker with pid: 30877
</pre>
</div>
<div class="tab-box" data-tab="deployment">
<h1>Deployment</h1>
<p>
Gunicorn is a WSGI HTTP server. It is best to use Gunicorn behind an HTTP proxy server. We strongly advise you to use <a href="http://www.nginx.org/">nginx</a>.
</p>
<p>Here's an example to help you get started with using nginx:</p>
<pre>
server {
listen 80;
server_name example.org;
access_log /var/log/nginx/example.log;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
</pre>
<p>Nginx is set up as reverse proxy server to a Gunicorn server running on localhost port 8000.</p>
<p>Read the full documentation at <a
href="http://docs.gunicorn.org/en/latest/deploy.html">docs.gunicorn.org</a></p>
</div>
<div class="tab-box" data-tab="community">
<h1>Project Management</h1>
<p><strong>Gunicorn</strong> uses <a href="https://github.com/benoitc/gunicorn/projects">GitHub for the project management</a>. GitHub issues are used for 3 different purposes:</p>
<ul>
<li><a href="https://github.com/benoitc/gunicorn/projects/2">Bug tracker</a></li>
<li><a href="https://github.com/benoitc/gunicorn/projects/4">Forum</a></li>
<li><a href="https://github.com/benoitc/gunicorn/projects/3">Mailing list</a>
</ul>
<p>Project maintenance guidelines are available on the <a href="https://github.com/benoitc/gunicorn/wiki/Project-management">wiki</a></p>
<h1>IRC</h1>
<p>The Gunicorn channel is on the <a href="https://libera.chat/">Libera Chat</a> IRC
network. You can chat with the community on the <a href="https://web.libera.chat/?channels=#gunicorn">#gunicorn channel</a>.</p>
<h1>Issue Tracking</h1>
<p>Bug reports, enhancement requests and tasks generally go in the <a href="http://github.com/benoitc/gunicorn/issues">Github
issue tracker</a>.</p>
<h1>Security Issues</h1>
<p>The security mailing list is a place to report security issues. Only
developers are subscribed to it. To post a message to the list use the
address <a href="mailto:security&#64;gunicorn.org">security&#64;gunicorn.org</a></p>
</div>
<div class="tab-box" data-tab="docs">
<h1>Documentation</h1>
<p>You can read more comprehensive documentation at <a href="http://docs.gunicorn.org">docs.gunicorn.org</a>.</p>
<p>The contents are:</p>
<ul>
<li><a href="http://docs.gunicorn.org/en/latest/install.html">Installation</a></li>
<li><a
href="http://docs.gunicorn.org/en/latest/run.html">Running
Gunicorn</a></li>
<li><a
href="http://docs.gunicorn.org/en/latest/configure.html">Configuration
Overview</a></li>
<li><a href="http://docs.gunicorn.org/en/latest/deploy.html">Deploying Gunicorn</a></li>
<li><a href="http://docs.gunicorn.org/en/latest/design.html">Design</a></li>
<li><a href="http://docs.gunicorn.org/en/latest/faq.html">FAQ</a></li>
<li><a href="http://docs.gunicorn.org/en/latest/news.html">Changelog</a></li>
</div>
</div>
</div>
<!-- <div class="user-wrapper">
<div class="users">
<div class="left-details">
<h3>Who is using</h3>
<h2>Gunicorn</h2>
</div>
<div class="company-logos">
<a href="#"><img src="images/user1.jpg"></a>
<a href="#"><img src="images/user1.jpg"></a>
<a href="#"><img src="images/user1.jpg"></a>
<a href="#"><img src="images/user1.jpg"></a>
<a href="#"><img src="images/user1.jpg"></a>
<a href="#"><img src="images/user1.jpg"></a>
</div>
<div class="clearall"></div>
</div>
</div> -->
<div class="footer">
<div class="footer-wp">
This open sourced site is hosted on GitHub. <br>
<a href="http://github.com/benoitc/gunicorn/issues">Patches, suggestions, and comments are welcome.</a>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
<title>Green Unicorn - Install</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/">here</a>
</h2>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
<title>Green Unicorn - Install</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/">here</a>
</h2>
</body>
</html>

View File

@ -1,46 +0,0 @@
$(document).ready(function() {
Tabs.init();
});
var Tabs = {
init: function(){
var activateTab = function ($tab) {
var // this links tabs set
$tabs = $tab.parents('.tabs'),
// currently active tab
activeTab = {
'tab' : $tabs.find('ul').children('li.active'),
'content' : $tabs.find('div[data-tab].active')
},
// newly clicked tab
newTab = {
'tab' : $tab.parent('li'),
'content' : $tabs.find('[data-tab=' + $tab.attr('href').replace('#', '') + ']')
},
x, y;
// remove active class from tab and content
for (x in activeTab) {
activeTab[x].removeClass('active');
}
// add active class to tab and content
for (y in newTab) {
newTab[y].addClass('active');
}
};
// hook up tab links
$(document).on('click', '.tabs ul li a', function(e) {
activateTab($(this));
//alert($(this));
});
// hook up initial load active tab
if (window.location.hash) {
var $activeTab = $('a[href="' + window.location.hash + '"]');
if ($activeTab.length && $activeTab.parents('.tabs').length) {
activateTab($activeTab);
}
}
}
};

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
<title>Green Unicorn - News</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/">here</a>
</h2>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
<title>Green Unicorn - Run</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/">here</a>
</h2>
</body>
</html>

View File

@ -1,73 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://gunicorn.org/</loc>
<lastmod>2019-11-27T00:02:48+01:00</lastmod>
<priority>1.0</priority>
</url>
<url>
<loc>http://gunicorn.org/community.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/configuration.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/configure.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/deploy.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/deployment.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/design.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/faq.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/install.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/installation.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/news.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/run.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/tuning.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
<url>
<loc>http://gunicorn.org/usage.html</loc>
<lastmod>2012-10-04T00:43:15+05:45</lastmod>
<priority>0.5</priority>
</url>
</urlset>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
<title>Green Unicorn - FAQ</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/">here</a>
</h2>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=http://gunicorn.org/">
<title>Green Unicorn - Run</title>
</head>
<body>
<h2>
Redirecting to <a href="http://gunicorn.org/">here</a>
</h2>
</body>
</html>

View File

@ -1,41 +0,0 @@
import os
import subprocess
from xml.etree import ElementTree
def main():
generate(
site_path=os.path.join(os.path.dirname(__file__), 'site'),
special_priorities={'index.html': 1.0})
def generate(site_path, special_priorities, directory_index='index.html'):
urlset = ElementTree.Element('urlset', xmlns='http://www.sitemaps.org/schemas/sitemap/0.9')
urlset.text = '\n '
for root, dirs, filenames in os.walk(site_path):
for filename in filenames:
if filename.endswith('.html'):
absolute_filepath = os.path.join(root, filename)
relative_path = os.path.relpath(absolute_filepath, site_path)
relative_url = os.path.dirname(relative_path) if filename == directory_index else relative_path
last_modification = subprocess.check_output(
['git', 'log', '-1', '--pretty="%cI"', absolute_filepath]).decode('ascii').strip('\n"')
url_element = ElementTree.SubElement(urlset, 'url')
loc_element = ElementTree.SubElement(url_element, 'loc')
loc_element.text = 'http://gunicorn.org/' + relative_url
lastmod_element = ElementTree.SubElement(url_element, 'lastmod')
lastmod_element.text = last_modification
priority_element = ElementTree.SubElement(url_element, 'priority')
priority_element.text = str(special_priorities.get(relative_path, 0.5))
url_element.tail = priority_element.tail = '\n '
url_element.text = loc_element.tail = lastmod_element.tail = '\n '
# We sort the url nodes instead of the filenames because
# filenames might be altered by the directory_index option
urlset[:] = sorted([url for url in urlset], key=lambda url: url[0].text)
urlset.tail = urlset[-1].tail = '\n'
with open(os.path.join(site_path, 'sitemap.xml'), 'wb') as sitemap_file:
ElementTree.ElementTree(urlset).write(sitemap_file, encoding='UTF-8', xml_declaration=True)
if __name__ == '__main__':
main()

View File

@ -1,211 +0,0 @@
Changelog - 2010
================
0.12.0 / 2010-12-22
-------------------
- Add support for logging configuration using a ini file.
It uses the standard Python logging's module Configuration
file format and allows anyone to use his custom file handler
- Add IPV6 support
- Add multidomain application example
- Improve gunicorn_django command when importing settings module
using DJANGO_SETTINGS_MODULE environment variable
- Send appropriate error status on http parsing
- Fix pidfile, set permissions so other user can read
it and use it.
- Fix temporary file leaking
- Fix setpgrp issue, can now be launched via ubuntu upstart
- Set the number of workers to zero on WINCH
0.11.2 / 2010-10-30
-------------------
* Add SERVER_SOFTWARE to the os.environ
* Add support for django settings environment variable
* Add support for logging configuration in Paster ini-files
* Improve arbiter notification in asynchronous workers
* Display the right error when a worker can't be used
* Fix Django support
* Fix HUP with Paster applications
* Fix readline in wsgi.input
0.11.1 / 2010-09-02
-------------------
* Implement max-requests feature to prevent memory leaks.
* Added 'worker_exit' server hook.
* Reseed the random number generator after fork().
* Improve Eventlet worker.
* Fix Django command `run_gunicorn`.
* Fix the default proc name internal setting.
* Workaround to prevent Gevent worker to segfault on MacOSX.
0.11.0 / 2010-08-12
-------------------
* Improve dramatically performances of Gevent and Eventlet workers
* Optimize HTTP parsing
* Drop Server and Date headers in start_response when provided.
* Fix latency issue in async workers
0.10.1 / 2010-08-06
-------------------
* Improve gevent's workers. Add "egg:gunicorn#gevent_wsgi" worker using
`gevent.wsgi <http://www.gevent.org/gevent.wsgi.html>`_ and
"egg:gunicorn#gevent_pywsgi" worker using `gevent.pywsgi
<http://www.gevent.org/gevent.pywsgi.html>`_ .
**"egg:gunicorn#gevent"** using our own HTTP parser is still here and
is **recommended** for normal uses. Use the "gevent.wsgi" parser if you
need really fast connections and don't need streaming, keepalive or ssl.
* Add pre/post request hooks
* Exit more quietly
* Fix gevent dns issue
0.10.0 / 2010-07-08
-------------------
* New HTTP parser.
* New HUP behaviour. Re-reads the configuration and then reloads all
worker processes without changing the master process id. Helpful for
code reloading and monitoring applications like supervisord and runit.
* Added a preload configuration parameter. By default, application code
is now loaded after a worker forks. This couple with the new HUP
handling can be used for dev servers to do hot code reloading. Using
the preload flag can help a bit in small memory VM's.
* Allow people to pass command line arguments to WSGI applications. See:
`examples/alt_spec.py
<http://github.com/benoitc/gunicorn/raw/master/examples/alt_spec.py>`_
* Added an example gevent reloader configuration:
`examples/example_gevent_reloader.py
<http://github.com/benoitc/gunicorn/blob/master/examples/example_gevent_reloader.py>`_.
* New gevent worker "egg:gunicorn#gevent2", working with gevent.wsgi.
* Internal refactoring and various bug fixes.
* New documentation website.
0.9.1 / 2010-05-26
------------------
* Support https via X-Forwarded-Protocol or X-Forwarded-Ssl headers
* Fix configuration
* Remove -d options which was used instead of -D for daemon.
* Fix umask in unix socket
0.9.0 / 2010-05-24
------------------
* Added *when_ready* hook. Called just after the server is started
* Added *preload* setting. Load application code before the worker processes
are forked.
* Refactored Config
* Fix pidfile
* Fix QUIT/HUP in async workers
* Fix reexec
* Documentation improvements
0.8.1 / 2010-04-29
------------------
* Fix builtins import in config
* Fix installation with pip
* Fix Tornado WSGI support
* Delay application loading until after processing all configuration
0.8.0 / 2010-04-22
------------------
* Refactored Worker management for better async support. Now use the -k option
to set the type of request processing to use
* Added support for Tornado_
0.7.2 / 2010-04-15
------------------
* Added --spew option to help debugging (installs a system trace hook)
* Some fixes in async arbiters
* Fix a bug in start_response on error
0.7.1 / 2010-04-01
------------------
* Fix bug when responses have no body.
0.7.0 / 2010-03-26
------------------
* Added support for Eventlet_ and Gevent_ based workers.
* Added Websockets_ support
* Fix Chunked Encoding
* Fix SIGWINCH on OpenBSD_
* Fix `PEP 333`_ compliance for the write callable.
0.6.5 / 2010-03-11
------------------
* Fix pidfile handling
* Fix Exception Error
0.6.4 / 2010-03-08
------------------
* Use cStringIO for performance when possible.
* Fix worker freeze when a remote connection closes unexpectedly.
0.6.3 / 2010-03-07
------------------
* Make HTTP parsing faster.
* Various bug fixes
0.6.2 / 2010-03-01
------------------
* Added support for chunked response.
* Added proc_name option to the config file.
* Improved the HTTP parser. It now uses buffers instead of strings to store
temporary data.
* Improved performance when sending responses.
* Workers are now murdered by age (the oldest is killed first).
0.6.1 / 2010-02-24
------------------
* Added gunicorn config file support for Django admin command
* Fix gunicorn config file. -c was broken.
* Removed TTIN/TTOU from workers which blocked other signals.
0.6.0 / 2010-02-22
------------------
* Added setproctitle support
* Change privilege switch behavior. We now work like NGINX, master keeps the
permissions, new uid/gid permissions are only set for workers.
0.5.1 / 2010-02-22
------------------
* Fix umask
* Added Debian packaging
0.5.0 / 2010-02-20
------------------
* Added `configuration file <configuration.html>`_ handler.
* Added support for pre/post fork hooks
* Added support for before_exec hook
* Added support for unix sockets
* Added launch of workers processes under different user/group
* Added umask option
* Added SCRIPT_NAME support
* Better support of some exotic settings for Django projects
* Better support of Paste-compatible applications
* Some refactoring to make the code easier to hack
* Allow multiple keys in request and response headers
.. _Tornado: http://www.tornadoweb.org/
.. _`PEP 333`: https://www.python.org/dev/peps/pep-0333/
.. _Eventlet: http://eventlet.net/
.. _Gevent: http://www.gevent.org/
.. _OpenBSD: https://www.openbsd.org/
.. _Websockets: https://html.spec.whatwg.org/multipage/web-sockets.html

View File

@ -1,73 +0,0 @@
Changelog - 2011
================
0.13.4 / 2011-09-23
-------------------
- fix util.closerange function used to prevent leaking fds on python 2.5
(typo)
0.13.3 / 2011-09-19
-------------------
- refactor gevent worker
- prevent leaking fds on reexec
- fix inverted request_time computation
0.13.2 / 2011-09-17
-------------------
- Add support for Tornado 2.0 in tornado worker
- Improve access logs: allows customisation of the log format & add
request time
- Logger module is now pluggable
- Improve graceful shutdown in Python versions >= 2.6
- Fix post_request root arity for compatibility
- Fix sendfile support
- Fix Django reloading
0.13.1 / 2011-08-22
-------------------
- Fix unix socket. log argument was missing.
0.13.0 / 2011-08-22
-------------------
- Improve logging: allows file-reopening and add access log file
compatible with the `apache combined log format <http://httpd.apache.org/docs/2.0/logs.html#combined>`_
- Add the possibility to set custom SSL headers. X-Forwarded-Protocol
and X-Forwarded-SSL are still the default
- New `on_reload` hook to customize how gunicorn spawn new workers on
SIGHUP
- Handle projects with relative path in django_gunicorn command
- Preserve path parameters in PATH_INFO
- post_request hook now accepts the environ as argument.
- When stopping the arbiter, close the listener asap.
- Fix Django command `run_gunicorn` in settings reloading
- Fix Tornado_ worker exiting
- Fix the use of sendfile in wsgi.file_wrapper
0.12.2 / 2011-05-18
-------------------
- Add wsgi.file_wrapper optimised for FreeBSD, Linux & MacOSX (use
sendfile if available)
- Fix django run_gunicorn command. Make sure we reload the application
code.
- Fix django localisation
- Compatible with gevent 0.14dev
0.12.1 / 2011-03-23
-------------------
- Add "on_starting" hook. This hook can be used to set anything before
the arbiter really start
- Support bdist_rpm in setup
- Improve content-length handling (pep 3333)
- Improve Django support
- Fix daemonizing (#142)
- Fix ipv6 handling
.. _Tornado: http://www.tornadoweb.org/

View File

@ -1,128 +0,0 @@
Changelog - 2012
================
0.17.0 / 2012-12-25
-------------------
- allows gunicorn to bind to multiple address
- add SSL support
- add syslog support
- add nworkers_changed hook
- add response arg for post_request hook
- parse command line with argparse (replace deprecated optparse)
- fix PWD detection in arbiter
- miscellaneous PEP8 fixes
0.16.1 / 2012-11-19
-------------------
- Fix packaging
0.16.0 / 2012-11-19
-------------------
- **Added support for Python 3.2 & 3.3**
- Expose --pythonpath command to all gunicorn commands
- Honor $PORT environment variable, useful for deployment on heroku
- Removed support for Python 2.5
- Make sure we reopen the logs on the console
- Fix django settings module detection from path
- Reverted timeout for client socket. Fix issue on blocking issues.
- Fixed gevent worker
0.15.0 / 2012-10-18
-------------------
- new documentation site on http://docs.gunicorn.org
- new website on http://gunicorn.org
- add `haproxy PROXY protocol <http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt>`_ support
- add ForwardedAllowIPS option: allows to filter Front-end's IPs
allowed to handle X-Forwarded-* headers.
- add callable hooks for paster config
- add x-forwarded-proto as secure scheme default (Heroku is using this)
- allows gunicorn to load a pre-compiled application
- support file reopening & reexec for all loggers
- initialize the logging config file with defaults.
- set timeout for client socket (slow client DoS).
- NoMoreData, ChunkMissingTerminator, InvalidChunkSize are now
IOError exceptions
- fix graceful shutdown in gevent
- fix limit request line check
0.14.6 / 2012-07-26
-------------------
- fix gevent & subproces
- fix request line length check
- fix keepalive = 0
- fix tornado worker
0.14.5 / 2012-06-24
--------------------
- fix logging during daemonisation
0.14.4 / 2012-06-24
-------------------
- new --graceful-timeout option
- fix multiple issues with request limit
- more fixes in django settings resolutions
- fix gevent.core import
- fix keepalive=0 in eventlet worker
- fix handle_error display with the unix worker
- fix tornado.wsgi.WSGIApplication calling error
- **breaking change**: take the control on graceful reload back.
graceful can't be overridden anymore using the on_reload function.
0.14.3 / 2012-05-15
-------------------
- improvement: performance of http.body.Body.readline()
- improvement: log HTTP errors in access log like Apache
- improvement: display traceback when the worker fails to boot
- improvement: makes gunicorn work with gevent 1.0
- examples: websocket example now supports hybi13
- fix: reopen log files after initialization
- fix: websockets support
- fix: django1.4 support
- fix: only load the paster application 1 time
0.14.2 / 2012-03-16
-------------------
- add validate_class validator: allows to use a class or a method to
initialize the app during in-code configuration
- add support for max_requests in tornado worker
- add support for disabling x_forwarded_for_header in tornado worker
- gevent_wsgi is now an alias of gevent_pywsgi
- Fix gevent_pywsgi worker
0.14.1 / 2012-03-02
-------------------
- fixing source archive, reducing its size
0.14.0 / 2012-02-27
-------------------
- check if Request line is too large: You can now pass the parameter
``--limit-request-line`` or set the ``limit_request_line`` in your
configuration file to set the max size of the request line in bytes.
- limit the number of headers fields and their size. Add
``--limit-request-field`` and ``limit-request-field-size`` settings
- add ``p`` variable to the log access format to log pidfile
- add ``{HeaderName}o`` variable to the logo access format to log the
response header HeaderName
- request header is now logged with the variable ``{HeaderName}i`` in the
access log file
- improve error logging
- support logging.configFile
- support django 1.4 in both gunicorn_django & run_gunicorn command
- improve reload in django run_gunicorn command (should just work now)
- allows people to set the ``X-Forwarded-For`` header key and disable it by
setting an empty string.
- fix support of Tornado
- many other fixes.

View File

@ -1,90 +0,0 @@
Changelog - 2013
================
18.0 / 2013-08-26
-----------------
- new: add ``-e/--env`` command line argument to pass an environment variables to
gunicorn
- new: add ``--chdir`` command line argument to specified directory
before apps loading. - new: add wsgi.file_wrapper support in async workers
- new: add ``--paste`` command line argument to set the paster config file
- deprecated: the command ``gunicorn_django`` is now deprecated. You should now
run your application with the WSGI interface installed with your project (see
https://docs.djangoproject.com/en/1.4/howto/deployment/wsgi/gunicorn/) for
more infos.
- deprecated: the command ``gunicorn_paste`` is deprecated. You now should use
the new ``--paste`` argument to set the configuration file of your paster
application.
- fix: Removes unmatched leading quote from the beginning of the default access
log format string
- fix: null timeout
- fix: gevent worker
- fix: don't reload the paster app when using pserve
- fix: after closing for error do not keep alive the connection
- fix: responses 1xx, 204 and 304 should not force the connection to be closed
17.5 / 2013-07-03
------------------
- new: add signals documentation
- new: add post_worker_init hook for workers
- new: try to use gunicorn.conf.py in current folder as the default
config file.
- fix graceful timeout with the Eventlet worker
- fix: don't raise an error when closing the socket if already closed
- fix: fix --settings parameter for django application and try to find
the django settings when using the ``gunicorn`` command.
- fix: give the initial global_conf to paster application
- fix: fix 'Expect: 100-continue' support on Python 3
New versioning:
++++++++++++++++
With this release, the versioning of Gunicorn is changing. Gunicorn is
stable since a long time and there is no point to release a "1.0" now.
It should have been done since a long time. 0.17 really meant it was the
17th stable version. From the beginning we have only 2 kind of
releases:
major release: releases with major changes or huge features added
services releases: fixes and minor features added So from now we will
apply the following versioning ``<major>.<service>``. For example ``17.5`` is a
service release.
0.17.4 / 2013-04-24
-------------------
- fix unix socket address parsing
0.17.3 / 2013-04-23
-------------------
- add systemd sockets support
- add ``python -m gunicorn.app.wsgiapp`` support
- improve logger class inheritance
- exit when the config file isn't found
- add the -R option to enable stdio inheritance in daemon mode
- don't close file descriptors > 3 in daemon mode
- improve STDOUT/STDERR logging
- fix pythonpath option
- fix pidfile creation on Python 3
- fix gevent worker exit
- fix ipv6 detection when the platform isn't supporting it
0.17.2 / 2013-01-07
-------------------
- optimize readline
- make imports errors more visible when loading an app or a logging
class
- fix tornado worker: don't pass ssl options if there are none
- fix PEP3333: accept only bytetrings in the response body
- fix support on CYGWIN platforms
0.17.1 / 2013-01-05
-------------------
- add syslog facility name setting
- fix ``--version`` command line argument
- fix wsgi url_scheme for https

View File

@ -1,228 +0,0 @@
================
Changelog - 2014
================
.. note::
Please see :doc:`news` for the latest changes.
19.1.1 / 2014-08-16
===================
Changes
-------
Core
++++
- fix :issue:`835`: display correct pid of already running instance
- fix :pr:`833`: fix `PyTest` class in setup.py.
Logging
+++++++
- fix :issue:`838`: statsd logger, send statsd timing metrics in milliseconds
- fix :issue:`839`: statsd logger, allows for empty log message while pushing
metrics and restore worker number in DEBUG logs
- fix :issue:`850`: add timezone to logging
- fix :issue:`853`: Respect logger_class setting unless statsd is on
AioHttp worker
++++++++++++++
- fix :issue:`830` make sure gaiohttp worker is shipped with gunicorn.
19.1 / 2014-07-26
=================
Changes
-------
Core
++++
- fix :issue:`785`: handle binary type address given to a client socket address
- fix graceful shutdown. make sure QUIT and TERMS signals are switched everywhere.
- :issue:`799`: fix support loading config from module
- :issue:`805`: fix check for file-like objects
- fix :issue:`815`: args validation in WSGIApplication.init
- fix :issue:`787`: check if we load a pyc file or not.
Tornado worker
++++++++++++++
- fix :issue:`771`: support tornado 4.0
- fix :issue:`783`: x_headers error. The x-forwarded-headers option has been removed
in `c4873681299212d6082cd9902740eef18c2f14f1
<https://github.com/benoitc/gunicorn/commit/c4873681299212d6082cd9902740eef18c2f14f1>`_.
The discussion is available on :pr:`633`.
AioHttp worker
++++++++++++++
- fix: fetch all body in input. fix :issue:`803`
- fix: don't install the worker if python < 3.3
- fix :issue:`822`: Support UNIX sockets in gaiohttp worker
Async worker
++++++++++++
- fix :issue:`790`: StopIteration shouldn't be caught at this level.
Logging
+++++++
- add statsd logging handler fix :issue:`748`
Paster
++++++
- fix :issue:`809`: Set global logging configuration from a Paste config.
Extra
+++++
- fix RuntimeError in gunicorn.reloader (:issue:`807`)
Documentation
+++++++++++++
- update faq: put a note on how `watch logs in the console
<http://docs.gunicorn.org/en/latest/faq.html#why-i-don-t-see-any-logs-in-the-console>`_
since many people asked for it.
19.0 / 2014-06-12
=================
Gunicorn 19.0 is a major release with new features and fixes. This
version improve a lot the usage of Gunicorn with python 3 by adding `two
new workers <http://docs.gunicorn.org/en/latest/design.html#asyncio-workers>`_
to it: `gthread` a fully threaded async worker using futures and `gaiohttp` a
worker using asyncio.
Breaking Changes
----------------
Switch QUIT and TERM signals
++++++++++++++++++++++++++++
With this change, when gunicorn receives a QUIT all the workers are
killed immediately and exit and TERM is used for the graceful shutdown.
Note: the old behaviour was based on the NGINX but the new one is more
correct according the following doc:
https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
also it is complying with the way the signals are sent by heroku:
https://devcenter.heroku.com/articles/python-faq#what-constraints-exist-when-developing-applications-on-heroku
Deprecations
++++++++++++
`run_gunicorn`, `gunicorn_django` and `gunicorn_paster` are now
completely deprecated and will be removed in the next release. Use the
`gunicorn` command instead.
Changes
-------
core
++++
- add aiohttp worker named `gaiohttp` using asyncio. Full async worker
on python 3.
- fix HTTP-violating excess whitespace in write_error output
- fix: try to log what happened in the worker after a timeout, add a
`worker_abort` hook on SIGABRT signal.
- fix: save listener socket name in workers so we can handle buffered
keep-alive requests after the listener has closed.
- add on_exit hook called just before exiting gunicorn.
- add support for python 3.4
- fix: do not swallow unexpected errors when reaping
- fix: remove incompatible SSL option with python 2.6
- add new async gthread worker and `--threads` options allows to set multiple
threads to listen on connection
- deprecate `gunicorn_django` and `gunicorn_paster`
- switch QUIT and TERM signal
- reap workers in SIGCHLD handler
- add universal wheel support
- use `email.utils.formatdate` in gunicorn.util.http_date
- deprecate the `--debug` option
- fix: log exceptions that occur after response start …
- allows loading of applications from `.pyc` files (#693)
- fix: issue #691, raw_env config file parsing
- use a dynamic timeout to wait for the optimal time. (Reduce power
usage)
- fix python3 support when notifying the arbiter
- add: honor $WEB_CONCURRENCY environment variable. Useful for heroku
setups.
- add: include tz offset in access log
- add: include access logs in the syslog handler.
- add --reload option for code reloading
- add the capability to load `gunicorn.base.Application` without the loading of
the arguments of the command line. It allows you to :ref:`embed gunicorn in
your own application <custom>`.
- improve: set wsgi.multithread to True for async workers
- fix logging: make sure to redirect wsgi.errors when needed
- add: syslog logging can now be done to a unix socket
- fix logging: don't try to redirect stdout/stderr to the logfile.
- fix logging: don't propagate log
- improve logging: file option can be overridden by the gunicorn options
`--error-logfile` and `--access-logfile` if they are given.
- fix: don't override SERVER_* by the Host header
- fix: handle_error
- add more option to configure SSL
- fix: sendfile with SSL
- add: worker_int callback (to react on SIGTERM)
- fix: don't depend on entry point for internal classes, now absolute
modules path can be given.
- fix: Error messages are now encoded in latin1
- fix: request line length check
- improvement: proxy_allow_ips: Allow proxy protocol if "*" specified
- fix: run worker's `setup` method before setting num_workers
- fix: FileWrapper inherit from `object` now
- fix: Error messages are now encoded in latin1
- fix: don't spam the console on SIGWINCH.
- fix: logging -don't stringify T and D logging atoms (#621)
- add support for the latest django version
- deprecate `run_gunicorn` django option
- fix: sys imported twice
gevent worker
+++++++++++++
- fix: make sure to stop all listeners
- fix: monkey patching is now done in the worker
- fix: "global name 'hub' is not defined"
- fix: reinit `hub` on old versions of gevent
- support gevent 1.0
- fix: add subprocess in monkey patching
- fix: add support for multiple listener
eventlet worker
+++++++++++++++
- fix: merge duplicate EventletWorker.init_process method (fixes #657)
- fix: missing errno import for eventlet sendfile patch
- fix: add support for multiple listener
tornado worker
++++++++++++++
- add graceful stop support

View File

@ -1,219 +0,0 @@
================
Changelog - 2015
================
.. note::
Please see :doc:`news` for the latest changes.
19.4.3 / 2015/12/30
===================
- fix: don't check if a file is writable using os.stat with SELINUX (:issue:`1171`)
19.4.2 / 2015/12/29
===================
Core
++++
- improvement: handle HaltServer in manage_workers (:issue:`1095`)
- fix: Do not rely on sendfile sending requested count (:issue:`1155`)
- fix: claridy --no-sendfile default (:issue:`1156`)
- fix: LoggingCatch sendfile failure from no file descriptor (:issue:`1160`)
Logging
+++++++
- fix: Always send access log to syslog if syslog is on
- fix: check auth before trying to own a file (:issue:`1157`)
Documentation
+++++++++++++
- fix: Fix Slowloris broken link. (:issue:`1142`)
- Tweak markup in faq.rst
Testing
+++++++
- fix: gaiohttp test (:issue:`1164`)
19.4.1 / 2015/11/25
===================
- fix tornado worker (:issue:`1154`)
19.4.0 / 2015/11/20
===================
Core
++++
- fix: make sure that a user is able to access to the logs after dropping a
privilege (:issue:`1116`)
- improvement: inherit the `Exception` class where it needs to be (:issue:`997`)
- fix: make sure headers are always encoded as latin1 RFC 2616 (:issue:`1102`)
- improvement: reduce arbiter noise (:issue:`1078`)
- fix: don't close the unix socket when the worker exit (:issue:`1088`)
- improvement: Make last logged worker count an explicit instance var (:issue:`1078`)
- improvement: prefix config file with its type (:issue:`836`)
- improvement: pidfile handing (:issue:`1042`)
- fix: catch OSError as well as ValueError on race condition (:issue:`1052`)
- improve support of ipv6 by backporting urlparse.urlsplit from Python 2.7 to
Python 2.6.
- fix: raise InvalidRequestLine when the line contains malicious data
(:issue:`1023`)
- fix: fix argument to disable sendfile
- fix: add gthread to the list of supported workers (:issue:`1011`)
- improvement: retry socket binding up to five times upon EADDRNOTAVAIL
(:issue:`1004`)
- **breaking change**: only honor headers that can be encoded in ascii to comply to
the RFC 7230 (See :issue:`1151`).
Logging
+++++++
- add new parameters to access log (:issue:`1132`)
- fix: make sure that files handles are correctly reopened on HUP
(:issue:`627`)
- include request URL in error message (:issue:`1071`)
- get username in access logs (:issue:`1069`)
- fix statsd logging support on Python 3 (:issue:`1010`)
Testing
+++++++
- use last version of mock.
- many fixes in Travis CI support
- miscellaneous improvements in tests
Thread worker
+++++++++++++
- fix: Fix self.nr usage in ThreadedWorker so that auto restart works as
expected (:issue:`1031`)
Gevent worker
+++++++++++++
- fix quit signal handling (:issue:`1128`)
- add support for Python 3 (:issue:`1066`)
- fix: make graceful shutdown thread-safe (:issue:`1032`)
Tornado worker
++++++++++++++
- fix ssl options (:issue:`1146`, :issue:`1135`)
- don't check timeout when stopping gracefully (:issue:`1106`)
AIOHttp worker
++++++++++++++
- add SSL support (:issue:`1105`)
Documentation
+++++++++++++
- fix link to proc name setting (:issue:`1144`)
- fix worker class documentation (:issue:`1141`, :issue:`1104`)
- clarify graceful timeout documentation (:issue:`1137`)
- don't duplicate NGINX config files examples (:issue:`1050`, :issue:`1048`)
- add `web.py` framework example (:issue:`1117`)
- update Debian/Ubuntu installations instructions (:issue:`1112`)
- clarify `pythonpath` setting description (:issue:`1080`)
- tweak some example for python3
- clarify `sendfile` documentation
- miscellaneous typos in source code comments (thanks!)
- clarify why REMOTE_ADD may not be the user's IP address (:issue:`1037`)
Misc
++++
- fix: reloader should survive SyntaxError (:issue:`994`)
- fix: expose the reloader class to the worker.
19.3.0 / 2015/03/06
===================
Core
++++
- fix: :issue:`978` make sure a listener is inheritable
- add `check_config` class method to workers
- fix: :issue:`983` fix select timeout in sync worker with multiple
connections
- allows workers to access to the reloader. close :issue:`984`
- raise TypeError instead of AssertionError
Logging
+++++++
- make Logger.loglevel a class attribute
Documentation
+++++++++++++
- fix: :issue:`988` fix syntax errors in examples/gunicorn_rc
19.2.1 / 2015/02/4
==================
Logging
+++++++
- expose loglevel in the Logger class
AsyncIO worker (gaiohttp)
+++++++++++++++++++++++++
- fix :issue:`977` fix initial crash
Documentation
+++++++++++++
- document security mailing-list in the contributing page.
19.2 / 2015/01/30
=================
Core
++++
- optimize the sync workers when listening on a single interface
- add `--sendfile` settings to enable/disable sendfile. fix :issue:`856` .
- add the selectors module to the code base. :issue:`886`
- add `--max-requests-jitter` setting to set the maximum jitter to add to the
max-requests setting.
- fix :issue:`899` propagate proxy_protocol_info to keep-alive requests
- fix :issue:`863` worker timeout: dynamic timeout has been removed
- fix: Avoid world writable file
Logging
+++++++
- fix :issue:`941` set logconfig default to paster more trivially
- add statsd-prefix config setting: set the prefix to use when emitting statsd
metrics
- :issue:`832` log to console by default
Thread Worker
+++++++++++++
- fix :issue:`908` make sure the worker can continue to accept requests
Eventlet Worker
+++++++++++++++
- fix :issue:`867` Fix eventlet shutdown to actively shut down the workers.
Documentation
+++++++++++++
Many improvements and fixes have been done, see the detailed changelog for
more information.

View File

@ -1,91 +0,0 @@
================
Changelog - 2016
================
.. note::
Please see :doc:`news` for the latest changes
19.6.0 / 2016/05/21
===================
Core & Logging
++++++++++++++
- improvement of the binary upgrade behaviour using USR2: remove file locking (:issue:`1270`)
- add the ``--capture-output`` setting to capture stdout/stderr tot the log
file (:issue:`1271`)
- Allow disabling ``sendfile()`` via the ``SENDFILE`` environment variable
(:issue:`1252`)
- fix reload under pycharm (:issue:`1129`)
Workers
+++++++
- fix: make sure to remove the signal from the worker pipe (:issue:`1269`)
- fix: **gthread** worker, handle removed socket in the select loop
(:issue:`1258`)
19.5.0 / 2016/05/10
===================
Core
++++
- fix: Ensure response to HEAD request won't have message body
- fix: lock domain socket and remove on last arbiter exit (:issue:`1220`)
- improvement: use EnvironmentError instead of socket.error (:issue:`939`)
- add: new ``FORWARDED_ALLOW_IPS`` environment variable (:issue:`1205`)
- fix: infinite recursion when destroying sockets (:issue:`1219`)
- fix: close sockets on shutdown (:issue:`922`)
- fix: clean up sys.exc_info calls to drop circular refs (:issue:`1228`)
- fix: do post_worker_init after load_wsgi (:issue:`1248`)
Workers
+++++++
- fix access logging in gaiohttp worker (:issue:`1193`)
- eventlet: handle QUIT in a new coroutine (:issue:`1217`)
- gevent: remove obsolete exception clauses in run (:issue:`1218`)
- tornado: fix extra "Server" response header (:issue:`1246`)
- fix: unblock the wait loop under python 3.5 in sync worker (:issue:`1256`)
Logging
+++++++
- fix: log message for listener reloading (:issue:`1181`)
- Let logging module handle traceback printing (:issue:`1201`)
- improvement: Allow configuring logger_class with statsd_host (:issue:`1188`)
- fix: traceback formatting (:issue:`1235`)
- fix: print error logs on stderr and access logs on stdout (:issue:`1184`)
Documentation
+++++++++++++
- Simplify installation instructions in gunicorn.org (:issue:`1072`)
- Fix URL and default worker type in example_config (:issue:`1209`)
- update django doc url to 1.8 lts (:issue:`1213`)
- fix: miscellaneous wording corrections (:issue:`1216`)
- Add PSF License Agreement of selectors.py to NOTICE (:issue: `1226`)
- document LOGGING overriding (:issue:`1051`)
- put a note that error logs are only errors from Gunicorn (:issue:`1124`)
- add a note about the requirements of the threads workers under python 2.x (:issue:`1200`)
- add access_log_format to config example (:issue:`1251`)
Tests
+++++
- Use more pytest.raises() in test_http.py
19.4.5 / 2016/01/05
===================
- fix: NameError fileno in gunicorn.http.wsgi (:issue:`1178`)
19.4.4 / 2016/01/04
===================
- fix: check if a fileobject can be used with sendfile(2) (:issue:`1174`)
- doc: be more descriptive in errorlog option (:issue:`1173`)

View File

@ -1,46 +0,0 @@
================
Changelog - 2017
================
.. note::
Please see :doc:`news` for the latest changes
19.7.1 / 2017/03/21
===================
- fix: continue if SO_REUSEPORT seems to be available but fails (:issue:`1480`)
- fix: support non-decimal values for the umask command line option (:issue:`1325`)
19.7.0 / 2017/03/01
===================
- The previously deprecated ``gunicorn_django`` command has been removed.
Use the :ref:`gunicorn-cmd` command-line interface instead.
- The previously deprecated ``django_settings`` setting has been removed.
Use the :ref:`raw-env` setting instead.
- The default value of :ref:`ssl-version` has been changed from
``ssl.PROTOCOL_TLSv1`` to ``ssl.PROTOCOL_SSLv23``.
- fix: initialize the group access list when initgroups is set (:issue:`1297`)
- add environment variables to gunicorn access log format (:issue:`1291`)
- add --paste-global-conf option (:issue:`1304`)
- fix: print access logs to STDOUT (:issue:`1184`)
- remove upper limit on max header size config (:issue:`1313`)
- fix: print original exception on AppImportError (:issue:`1334`)
- use SO_REUSEPORT if available (:issue:`1344`)
- `fix leak <https://github.com/benoitc/gunicorn/commit/b4c41481e2d5ef127199a4601417a6819053c3fd>`_ of duplicate file descriptor for bound sockets.
- add --reload-engine option, support inotify and other backends (:issue:`1368`, :issue:`1459`)
- fix: reject request with invalid HTTP versions
- add ``child_exit`` callback (:issue:`1394`)
- add support for eventlets _AlreadyHandled object (:issue:`1406`)
- format boot tracebacks properly with reloader (:issue:`1408`)
- refactor socket activation and fd inheritance for better support of SystemD (:issue:`1310`)
- fix: o fds are given by default in gunicorn (:issue:`1423`)
- add ability to pass settings to GUNICORN_CMD_ARGS environment variable which helps in container world (:issue:`1385`)
- fix: catch access denied to pid file (:issue:`1091`)
- many additions and improvements to the documentation
Breaking Change
+++++++++++++++
- **Python 2.6.0** is the last supported version

View File

@ -1,68 +0,0 @@
================
Changelog - 2018
================
.. note::
Please see :doc:`news` for the latest changes
19.9.0 / 2018/07/03
===================
- fix: address a regression that prevented syslog support from working
(:issue:`1668`, :pr:`1773`)
- fix: correctly set `REMOTE_ADDR` on versions of Python 3 affected by
`Python Issue 30205 <https://bugs.python.org/issue30205>`_
(:issue:`1755`, :pr:`1796`)
- fix: show zero response length correctly in access log (:pr:`1787`)
- fix: prevent raising :exc:`AttributeError` when ``--reload`` is not passed
in case of a :exc:`SyntaxError` raised from the WSGI application.
(:issue:`1805`, :pr:`1806`)
- The internal module ``gunicorn.workers.async`` was renamed to ``gunicorn.workers.base_async``
since ``async`` is now a reserved word in Python 3.7.
(:pr:`1527`)
19.8.1 / 2018/04/30
===================
- fix: secure scheme headers when bound to a unix socket
(:issue:`1766`, :pr:`1767`)
19.8.0 / 2018/04/28
===================
- Eventlet 0.21.0 support (:issue:`1584`)
- Tornado 5 support (:issue:`1728`, :pr:`1752`)
- support watching additional files with ``--reload-extra-file``
(:pr:`1527`)
- support configuring logging with a dictionary with ``--logging-config-dict``
(:issue:`1087`, :pr:`1110`, :pr:`1602`)
- add support for the ``--config`` flag in the ``GUNICORN_CMD_ARGS`` environment
variable (:issue:`1576`, :pr:`1581`)
- disable ``SO_REUSEPORT`` by default and add the ``--reuse-port`` setting
(:issue:`1553`, :issue:`1603`, :pr:`1669`)
- fix: installing `inotify` on MacOS no longer breaks the reloader
(:issue:`1540`, :pr:`1541`)
- fix: do not throw ``TypeError`` when ``SO_REUSEPORT`` is not available
(:issue:`1501`, :pr:`1491`)
- fix: properly decode HTTP paths containing certain non-ASCII characters
(:issue:`1577`, :pr:`1578`)
- fix: remove whitespace when logging header values under gevent (:pr:`1607`)
- fix: close unlinked temporary files (:issue:`1327`, :pr:`1428`)
- fix: parse ``--umask=0`` correctly (:issue:`1622`, :pr:`1632`)
- fix: allow loading applications using relative file paths
(:issue:`1349`, :pr:`1481`)
- fix: force blocking mode on the gevent sockets (:issue:`880`, :pr:`1616`)
- fix: preserve leading `/` in request path (:issue:`1512`, :pr:`1511`)
- fix: forbid contradictory secure scheme headers
- fix: handle malformed basic authentication headers in access log
(:issue:`1683`, :pr:`1684`)
- fix: defer handling of ``USR1`` signal to a new greenlet under gevent
(:issue:`1645`, :pr:`1651`)
- fix: the threaded worker would sometimes close the wrong keep-alive
connection under Python 2 (:issue:`1698`, :pr:`1699`)
- fix: re-open log files on ``USR1`` signal using ``handler._open`` to
support subclasses of ``FileHandler`` (:issue:`1739`, :pr:`1742`)
- deprecation: the ``gaiohttp`` worker is deprecated, see the
:ref:`worker-class` documentation for more information
(:issue:`1338`, :pr:`1418`, :pr:`1569`)

View File

@ -1,121 +0,0 @@
================
Changelog - 2019
================
.. note::
Please see :doc:`news` for the latest changes
20.0.4 / 2019/11/26
===================
- fix binding a socket using the file descriptor
- remove support for the `bdist_rpm` build
20.0.3 / 2019/11/24
===================
- fixed load of a config file without a Python extension
- fixed `socketfromfd.fromfd` when defaults are not set
.. note:: we now warn when we load a config file without Python Extension
20.0.2 / 2019/11/23
===================
- fix changelog
20.0.1 / 2019/11/23
===================
- fixed the way the config module is loaded. `__file__` is now available
- fixed `wsgi.input_terminated`. It is always true.
- use the highest protocol version of openssl by default
- only support Python >= 3.5
- added `__repr__` method to `Config` instance
- fixed support of AIX platform and musl libc in `socketfromfd.fromfd` function
- fixed support of applications loaded from a factory function
- fixed chunked encoding support to prevent any `request smuggling <https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn>`_
- Capture os.sendfile before patching in gevent and eventlet workers.
fix `RecursionError`.
- removed locking in reloader when adding new files
- load the WSGI application before the loader to pick up all files
.. note:: this release add official support for applications loaded from a factory function
as documented in Flask and other places.
19.10.0 / 2019/11/23
====================
- unblock select loop during reload of a sync worker
- security fix: http desync attack
- handle `wsgi.input_terminated`
- added support for str and bytes in unix socket addresses
- fixed `max_requests` setting
- headers values are now encoded as LATN1, not ASCII
- fixed `InotifyReloadeder`: handle `module.__file__` is None
- fixed compatibility with tornado 6
- fixed root logging
- Prevent removalof unix sockets from `reuse_port`
- Clear tornado ioloop before os.fork
- Miscellaneous fixes and improvement for linting using Pylint
20.0 / 2019/10/30
=================
- Fixed `fdopen` `RuntimeWarning` in Python 3.8
- Added check and exception for str type on value in Response process_headers method.
- Ensure WSGI header value is string before conducting regex search on it.
- Added pypy3 to list of tested environments
- Grouped `StopIteration` and `KeyboardInterrupt` exceptions with same body together in Arbiter.run()
- Added `setproctitle` module to `extras_require` in setup.py
- Avoid unnecessary chown of temporary files
- Logging: Handle auth type case insensitively
- Removed `util.import_module`
- Removed fallback for `types.SimpleNamespace` in tests utils
- Use `SourceFileLoader` instead instead of `execfile_`
- Use `importlib` instead of `__import__` and eval`
- Fixed eventlet patching
- Added optional `datadog <https://www.datadoghq.com>`_ tags for statsd metrics
- Header values now are encoded using latin-1, not ascii.
- Rewritten `parse_address` util added test
- Removed redundant super() arguments
- Simplify `futures` import in gthread module
- Fixed worker_connections` setting to also affects the Gthread worker type
- Fixed setting max_requests
- Bump minimum Eventlet and Gevent versions to 0.24 and 1.4
- Use Python default SSL cipher list by default
- handle `wsgi.input_terminated` extension
- Simplify Paste Deployment documentation
- Fix root logging: root and logger are same level.
- Fixed typo in ssl_version documentation
- Documented systemd deployment unit examples
- Added systemd sd_notify support
- Fixed typo in gthread.py
- Added `tornado <https://www.tornadoweb.org/>`_ 5 and 6 support
- Declare our setuptools dependency
- Added support to `--bind` to open file descriptors
- Document how to serve WSGI app modules from Gunicorn
- Provide guidance on X-Forwarded-For access log in documentation
- Add support for named constants in the `--ssl-version` flag
- Clarify log format usage of header & environment in documentation
- Fixed systemd documentation to properly setup gunicorn unix socket
- Prevent removal unix socket for reuse_port
- Fix `ResourceWarning` when reading a Python config module
- Remove unnecessary call to dict keys method
- Support str and bytes for UNIX socket addresses
- fixed `InotifyReloadeder`: handle `module.__file__` is None
- `/dev/shm` as a convenient alternative to making your own tmpfs mount in fchmod FAQ
- fix examples to work on python3
- Fix typo in `--max-requests` documentation
- Clear tornado ioloop before os.fork
- Miscellaneous fixes and improvement for linting using Pylint
Breaking Change
+++++++++++++++
- Removed gaiohttp worker
- Drop support for Python 2.x
- Drop support for EOL Python 3.2 and 3.3
- Drop support for Paste Deploy server blocks

View File

@ -1,7 +0,0 @@
================
Changelog - 2020
================
.. note::
Please see :doc:`news` for the latest changes

View File

@ -1,54 +0,0 @@
================
Changelog - 2021
================
.. note::
Please see :doc:`news` for the latest changes
20.1.0 - 2021-02-12
===================
- document WEB_CONCURRENCY is set by, at least, Heroku
- capture peername from accept: Avoid calls to getpeername by capturing the peer name returned by
accept
- log a warning when a worker was terminated due to a signal
- fix tornado usage with latest versions of Django
- add support for python -m gunicorn
- fix systemd socket activation example
- allows to set wsgi application in config file using `wsgi_app`
- document `--timeout = 0`
- always close a connection when the number of requests exceeds the max requests
- Disable keepalive during graceful shutdown
- kill tasks in the gthread workers during upgrade
- fix latency in gevent worker when accepting new requests
- fix file watcher: handle errors when new worker reboot and ensure the list of files is kept
- document the default name and path of the configuration file
- document how variable impact configuration
- document the `$PORT` environment variable
- added milliseconds option to request_time in access_log
- added PIP requirements to be used for example
- remove version from the Server header
- fix sendfile: use `socket.sendfile` instead of `os.sendfile`
- reloader: use absolute path to prevent empty to prevent0 `InotifyError` when a file
is added to the working directory
- Add --print-config option to print the resolved settings at startup.
- remove the `--log-dict-config` CLI flag because it never had a working format
(the `logconfig_dict` setting in configuration files continues to work)
** Breaking changes **
- minimum version is Python 3.5
- remove version from the Server header
** Documentation **
** Others **
- miscellaneous changes in the code base to be a better citizen with Python 3
- remove dead code
- fix documentation generation

View File

@ -1,39 +0,0 @@
================
Changelog - 2023
================
21.2.0 - 2023-07-19
===================
- fix thread worker: revert change considering connection as idle .
*** NOTE ***
This is fixing the bad file description error.
21.1.0 - 2023-07-18
===================
- fix thread worker: fix socket removal from the queue
21.0.1 - 2023-07-17
===================
- fix documentation build
21.0.0 - 2023-07-17
===================
- support python 3.11
- fix gevent and eventlet workers
- fix threads support (gththread): improve performance and unblock requests
- SSL: now use SSLContext object
- HTTP parser: miscellaneous fixes
- remove unnecessary setuid calls
- fix testing
- improve logging
- miscellaneous fixes to core engine
*** RELEASE NOTE ***
We made this release major to start our new release cycle. More info will be provided on our discussion forum.

View File

@ -1,61 +0,0 @@
================
Changelog - 2024
================
23.0.0 - 2024-08-10
===================
- minor docs fixes (:pr:`3217`, :pr:`3089`, :pr:`3167`)
- worker_class parameter accepts a class (:pr:`3079`)
- fix deadlock if request terminated during chunked parsing (:pr:`2688`)
- permit receiving Transfer-Encodings: compress, deflate, gzip (:pr:`3261`)
- permit Transfer-Encoding headers specifying multiple encodings. note: no parameters, still (:pr:`3261`)
- sdist generation now explicitly excludes sphinx build folder (:pr:`3257`)
- decode bytes-typed status (as can be passed by gevent) as utf-8 instead of raising `TypeError` (:pr:`2336`)
- raise correct Exception when encounting invalid chunked requests (:pr:`3258`)
- the SCRIPT_NAME and PATH_INFO headers, when received from allowed forwarders, are no longer restricted for containing an underscore (:pr:`3192`)
- include IPv6 loopback address ``[::1]`` in default for :ref:`forwarded-allow-ips` and :ref:`proxy-allow-ips` (:pr:`3192`)
** NOTE **
- The SCRIPT_NAME change mitigates a regression that appeared first in the 22.0.0 release
- Review your :ref:`forwarded-allow-ips` setting if you are still not seeing the SCRIPT_NAME transmitted
- Review your :ref:`forwarder-headers` setting if you are missing headers after upgrading from a version prior to 22.0.0
** Breaking changes **
- refuse requests where the uri field is empty (:pr:`3255`)
- refuse requests with invalid CR/LR/NUL in heade field values (:pr:`3253`)
- remove temporary ``--tolerate-dangerous-framing`` switch from 22.0 (:pr:`3260`)
- If any of the breaking changes affect you, be aware that now refused requests can post a security problem, especially so in setups involving request pipe-lining and/or proxies.
22.0.0 - 2024-04-17
===================
- use `utime` to notify workers liveness
- migrate setup to pyproject.toml
- fix numerous security vulnerabilities in HTTP parser (closing some request smuggling vectors)
- parsing additional requests is no longer attempted past unsupported request framing
- on HTTP versions < 1.1 support for chunked transfer is refused (only used in exploits)
- requests conflicting configured or passed SCRIPT_NAME now produce a verbose error
- Trailer fields are no longer inspected for headers indicating secure scheme
- support Python 3.12
** Breaking changes **
- minimum version is Python 3.7
- the limitations on valid characters in the HTTP method have been bounded to Internet Standards
- requests specifying unsupported transfer coding (order) are refused by default (rare)
- HTTP methods are no longer casefolded by default (IANA method registry contains none affected)
- HTTP methods containing the number sign (#) are no longer accepted by default (rare)
- HTTP versions < 1.0 or >= 2.0 are no longer accepted by default (rare, only HTTP/1.1 is supported)
- HTTP versions consisting of multiple digits or containing a prefix/suffix are no longer accepted
- HTTP header field names Gunicorn cannot safely map to variables are silently dropped, as in other software
- HTTP headers with empty field name are refused by default (no legitimate use cases, used in exploits)
- requests with both Transfer-Encoding and Content-Length are refused by default (such a message might indicate an attempt to perform request smuggling)
- empty transfer codings are no longer permitted (reportedly seen with really old & broken proxies)
** SECURITY **
- fix CVE-2024-1135

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,37 +0,0 @@
=========
Community
=========
Use these channels to communicate about the project:
Project Management & Discussions
================================
Project maintenance guidelines are available on the `wiki <https://github.com/benoitc/gunicorn/wiki/Project-management>`_
GitHub issues are used for 3 different purposes:
* `Bug tracker <https://github.com/benoitc/gunicorn/issues>`_ : To check for latest bugs. Tip: See existing issues before opening a new one!
* `Forum <https://github.com/benoitc/gunicorn/discussions>`_ : Stackoverflow-style questions about Gunicorn usage.
* `Other Issues <https://github.com/benoitc/gunicorn/issues>`_ : Discussion of Gunicorn development, new features
and project management.
IRC
===
The Gunicorn channel is on the `Libera Chat <https://libera.chat/>`_ IRC
network. You can chat with others on `#gunicorn channel
<https://web.libera.chat/?channels=#gunicorn>`_
Issue Tracking
==============
Bug reports, enhancement requests and tasks generally go in the `Github
issue tracker <http://github.com/benoitc/gunicorn/issues>`_
Security Issues
===============
The security mailing list is a place to report security issues. Only
developers are subscribed to it. To post a message to the list use the address
to `security@gunicorn.org <mailto:security@gunicorn.org>`_

View File

@ -1,72 +0,0 @@
#
# Gunicorn documentation build configuration file
#
import os
import sys
import time
DOCS_DIR = os.path.abspath(os.path.dirname(__file__))
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
# for gunicorn_ext.py
sys.path.append(os.path.join(DOCS_DIR, os.pardir))
sys.path.insert(0, os.path.join(DOCS_DIR, os.pardir, os.pardir))
extensions = ['gunicorn_ext']
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = 'Gunicorn'
copyright = '2009-%s, Benoit Chesneau' % time.strftime('%Y')
# gunicorn version
import gunicorn
release = version = gunicorn.__version__
exclude_patterns = []
pygments_style = 'sphinx'
# -- Options for HTML output ---------------------------------------------------
if not on_rtd: # only import and set the theme if we're building docs locally
try:
import sphinx_rtd_theme
except ImportError:
html_theme = 'default'
else:
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
else:
html_theme = 'default'
html_static_path = ['_static']
htmlhelp_basename = 'Gunicorndoc'
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
}
latex_documents = [
('index', 'Gunicorn.tex', 'Gunicorn Documentation',
'Benoit Chesneau', 'manual'),
]
# -- Options for manual page output --------------------------------------------
man_pages = [
('index', 'gunicorn', 'Gunicorn Documentation',
['Benoit Chesneau'], 1)
]
texinfo_documents = [
('index', 'Gunicorn', 'Gunicorn Documentation',
'Benoit Chesneau', 'Gunicorn', 'One line description of project.',
'Miscellaneous'),
]

View File

@ -1,118 +0,0 @@
.. _configuration:
======================
Configuration Overview
======================
Gunicorn reads configuration information from five places.
Gunicorn first reads environment variables for some configuration
:ref:`settings <settings>`.
Gunicorn then reads configuration from a framework specific configuration
file. Currently this only affects Paster applications.
The third source of configuration information is an optional configuration file
``gunicorn.conf.py`` searched in the current working directory or specified
using a command line argument. Anything specified in this configuration file
will override any framework specific settings.
The fourth place of configuration information are command line arguments
stored in an environment variable named ``GUNICORN_CMD_ARGS``.
Lastly, the command line arguments used to invoke Gunicorn are the final place
considered for configuration settings. If an option is specified on the command
line, this is the value that will be used.
When a configuration file is specified in the command line arguments and in the
``GUNICORN_CMD_ARGS`` environment variable, only the configuration
file specified on the command line is used.
Once again, in order of least to most authoritative:
1. Environment Variables
2. Framework Settings
3. Configuration File
4. ``GUNICORN_CMD_ARGS``
5. Command Line
.. note::
To print your resolved configuration when using the command line or the
configuration file you can run the following command::
$ gunicorn --print-config APP_MODULE
To check your resolved configuration when using the command line or the
configuration file you can run the following command::
$ gunicorn --check-config APP_MODULE
It also allows you to know if your application can be launched.
Command Line
============
If an option is specified on the command line, it overrides all other values
that may have been specified in the app specific settings, or in the optional
configuration file. Not all Gunicorn settings are available to be set from the
command line. To see the full list of command line settings you can do the
usual::
$ gunicorn -h
There is also a ``--version`` flag available to the command line scripts that
isn't mentioned in the list of :ref:`settings <settings>`.
.. _configuration_file:
Configuration File
==================
The configuration file should be a valid Python source file with a **python
extension** (e.g. `gunicorn.conf.py`). It only needs to be readable from the
file system. More specifically, it does not have to be on the module path
(sys.path, PYTHONPATH). Any Python is valid. Just consider that this will be
run every time you start Gunicorn (including when you signal Gunicorn to reload).
To set a parameter, just assign to it. There's no special syntax. The values
you provide will be used for the configuration values.
For instance::
import multiprocessing
bind = "127.0.0.1:8000"
workers = multiprocessing.cpu_count() * 2 + 1
All the settings are mentioned in the :ref:`settings <settings>` list.
Framework Settings
==================
Currently, only Paster applications have access to framework specific
settings. If you have ideas for providing settings to WSGI applications or
pulling information from Django's settings.py feel free to open an issue_ to
let us know.
.. _issue: https://github.com/benoitc/gunicorn/issues
Paster Applications
-------------------
In your INI file, you can specify to use Gunicorn as the server like such:
.. code-block:: ini
[server:main]
use = egg:gunicorn#main
host = 192.168.0.1
port = 80
workers = 2
proc_name = brim
Any parameters that Gunicorn knows about will automatically be inserted into
the base configuration. Remember that these will be overridden by the config
file and/or the command line.

View File

@ -1,72 +0,0 @@
.. _custom:
==================
Custom Application
==================
.. versionadded:: 19.0
Sometimes, you want to integrate Gunicorn with your WSGI application. In this
case, you can inherit from :class:`gunicorn.app.base.BaseApplication`.
Here is a small example where we create a very small WSGI app and load it with
a custom Application:
.. literalinclude:: ../../examples/standalone_app.py
:start-after: # See the NOTICE for more information
:lines: 2-
Using server hooks
------------------
If you wish to include server hooks in your custom application, you can specify a function in the config options. Here is an example with the `pre_fork` hook:
.. code-block:: python
def pre_fork(server, worker):
print(f"pre-fork server {server} worker {worker}", file=sys.stderr)
# ...
if __name__ == '__main__':
options = {
'bind': '%s:%s' % ('127.0.0.1', '8080'),
'workers': number_of_workers(),
'pre_fork': pre_fork,
}
Direct Usage of Existing WSGI Apps
----------------------------------
If necessary, you can run Gunicorn straight from Python, allowing you to
specify a WSGI-compatible application at runtime. This can be handy for
rolling deploys or in the case of using PEX files to deploy your application,
as the app and Gunicorn can be bundled in the same PEX file. Gunicorn has
this functionality built-in as a first class citizen known as
:class:`gunicorn.app.wsgiapp`. This can be used to run WSGI-compatible app
instances such as those produced by Flask or Django. Assuming your WSGI API
package is *exampleapi*, and your application instance is *app*, this is all
you need to get going::
gunicorn.app.wsgiapp exampleapi:app
This command will work with any Gunicorn CLI parameters or a config file - just
pass them along as if you're directly giving them to Gunicorn:
.. code-block:: bash
# Custom parameters
$ python gunicorn.app.wsgiapp exampleapi:app --bind=0.0.0.0:8081 --workers=4
# Using a config file
$ python gunicorn.app.wsgiapp exampleapi:app -c config.py
Note for those using PEX: use ``-c gunicorn`` as your entry at build
time, and your compiled app should work with the entry point passed to it at
run time.
.. code-block:: bash
# Generic pex build command via bash from root of exampleapi project
$ pex . -v -c gunicorn -o compiledapp.pex
# Running it
./compiledapp.pex exampleapi:app -c gunicorn_config.py

View File

@ -1,380 +0,0 @@
==================
Deploying Gunicorn
==================
We strongly recommend using Gunicorn behind a proxy server.
Nginx Configuration
===================
Although there are many HTTP proxies available, we strongly advise that you
use Nginx_. If you choose another proxy server you need to make sure that it
buffers slow clients when you use default Gunicorn workers. Without this
buffering Gunicorn will be easily susceptible to denial-of-service attacks.
You can use Hey_ to check if your proxy is behaving properly.
An `example configuration`_ file for fast clients with Nginx_:
.. literalinclude:: ../../examples/nginx.conf
:language: nginx
:caption: **nginx.conf**
If you want to be able to handle streaming request/responses or other fancy
features like Comet, Long polling, or Web sockets, you need to turn off the
proxy buffering. **When you do this** you must run with one of the async worker
classes.
To turn off buffering, you only need to add ``proxy_buffering off;`` to your
``location`` block::
...
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://app_server;
}
...
If you want to ignore aborted requests like health check of Load Balancer, some
of which close the connection without waiting for a response, you need to turn
on `ignoring client abort`_.
To ignore aborted requests, you only need to add
``proxy_ignore_client_abort on;`` to your ``location`` block::
...
proxy_ignore_client_abort on;
...
.. note::
The default value of ``proxy_ignore_client_abort`` is ``off``. Error code
499 may appear in Nginx log and ``Ignoring EPIPE`` may appear in Gunicorn
log if loglevel is set to ``debug``.
It is recommended to pass protocol information to Gunicorn. Many web
frameworks use this information to generate URLs. Without this
information, the application may mistakenly generate 'http' URLs in
'https' responses, leading to mixed content warnings or broken
applications. To configure Nginx to pass an appropriate header, add
a ``proxy_set_header`` directive to your ``location`` block::
...
proxy_set_header X-Forwarded-Proto $scheme;
...
If you are running Nginx on a different host than Gunicorn you need to tell
Gunicorn to trust the ``X-Forwarded-*`` headers sent by Nginx. By default,
Gunicorn will only trust these headers if the connection comes from localhost.
This is to prevent a malicious client from forging these headers::
$ gunicorn -w 3 --forwarded-allow-ips="10.170.3.217,10.170.3.220" test:app
When the Gunicorn host is completely firewalled from the external network such
that all connections come from a trusted proxy (e.g. Heroku) this value can
be set to '*'. Using this value is **potentially dangerous** if connections to
Gunicorn may come from untrusted proxies or directly from clients since the
application may be tricked into serving SSL-only content over an insecure
connection.
Gunicorn 19 introduced a breaking change concerning how ``REMOTE_ADDR`` is
handled. Previous to Gunicorn 19 this was set to the value of
``X-Forwarded-For`` if received from a trusted proxy. However, this was not in
compliance with :rfc:`3875` which is why the ``REMOTE_ADDR`` is now the IP
address of **the proxy** and **not the actual user**.
To have access logs indicate **the actual user** IP when proxied, set
:ref:`access-log-format` with a format which includes ``X-Forwarded-For``. For
example, this format uses ``X-Forwarded-For`` in place of ``REMOTE_ADDR``::
%({x-forwarded-for}i)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
It is also worth noting that the ``REMOTE_ADDR`` will be completely empty if
you bind Gunicorn to a UNIX socket and not a TCP ``host:port`` tuple.
Using Virtualenv
================
To serve an app from a Virtualenv_ it is generally easiest to just install
Gunicorn directly into the Virtualenv. This will create a set of Gunicorn
scripts for that Virtualenv which can be used to run applications normally.
If you have Virtualenv installed, you should be able to do something like
this::
$ mkdir ~/venvs/
$ virtualenv ~/venvs/webapp
$ source ~/venvs/webapp/bin/activate
$ pip install gunicorn
$ deactivate
Then you just need to use one of the three Gunicorn scripts that was installed
into ``~/venvs/webapp/bin``.
Note: You can force the installation of Gunicorn in your Virtualenv by
passing ``-I`` or ``--ignore-installed`` option to pip::
$ source ~/venvs/webapp/bin/activate
$ pip install -I gunicorn
Monitoring
==========
.. note::
Make sure that when using either of these service monitors you do not
enable the Gunicorn's daemon mode. These monitors expect that the process
they launch will be the process they need to monitor. Daemonizing will
fork-exec which creates an unmonitored process and generally just
confuses the monitor services.
Gaffer
------
Using Gafferd and gaffer
++++++++++++++++++++++++
Gaffer_ can be used to monitor Gunicorn. A simple configuration is::
[process:gunicorn]
cmd = gunicorn -w 3 test:app
cwd = /path/to/project
Then you can easily manage Gunicorn using Gaffer_.
Using a Procfile
++++++++++++++++
Create a ``Procfile`` in your project::
gunicorn = gunicorn -w 3 test:app
You can launch any other applications that should be launched at the same time.
Then you can start your Gunicorn application using Gaffer_::
gaffer start
If gafferd is launched you can also load your Procfile in it directly::
gaffer load
All your applications will be then supervised by gafferd.
Runit
-----
A popular method for deploying Gunicorn is to have it monitored by runit_.
Here is an `example service`_ definition::
#!/bin/sh
GUNICORN=/usr/local/bin/gunicorn
ROOT=/path/to/project
PID=/var/run/gunicorn.pid
APP=main:application
if [ -f $PID ]; then rm $PID; fi
cd $ROOT
exec $GUNICORN -c $ROOT/gunicorn.conf.py --pid=$PID $APP
Save this as ``/etc/sv/[app_name]/run``, and make it executable
(``chmod u+x /etc/sv/[app_name]/run``).
Then run ``ln -s /etc/sv/[app_name] /etc/service/[app_name]``.
If runit is installed, Gunicorn should start running automatically as soon
as you create the symlink.
If it doesn't start automatically, run the script directly to troubleshoot.
Supervisor
----------
Another useful tool to monitor and control Gunicorn is Supervisor_. A
`simple configuration`_ is::
[program:gunicorn]
command=/path/to/gunicorn main:application -c /path/to/gunicorn.conf.py
directory=/path/to/project
user=nobody
autostart=true
autorestart=true
redirect_stderr=true
Upstart
-------
Using Gunicorn with upstart is simple. In this example we will run the app
"myapp" from a virtualenv. All errors will go to
``/var/log/upstart/myapp.log``.
**/etc/init/myapp.conf**::
description "myapp"
start on (filesystem)
stop on runlevel [016]
respawn
setuid nobody
setgid nogroup
chdir /path/to/app/directory
exec /path/to/virtualenv/bin/gunicorn myapp:app
Systemd
-------
A tool that is starting to be common on linux systems is Systemd_. It is a
system services manager that allows for strict process management, resources
and permissions control.
Below are configuration files and instructions for using systemd to create
a unix socket for incoming Gunicorn requests. Systemd will listen on this
socket and start gunicorn automatically in response to traffic. Later in
this section are instructions for configuring Nginx to forward web traffic
to the newly created unix socket:
**/etc/systemd/system/gunicorn.service**::
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
# gunicorn can let systemd know when it is ready
Type=notify
NotifyAccess=main
# the specific user that our service will run as
User=someuser
Group=someuser
# this user can be transiently created by systemd
# DynamicUser=true
RuntimeDirectory=gunicorn
WorkingDirectory=/home/someuser/applicationroot
ExecStart=/usr/bin/gunicorn applicationname.wsgi
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
# if your app does not need administrative capabilities, let systemd know
# ProtectSystem=strict
[Install]
WantedBy=multi-user.target
**/etc/systemd/system/gunicorn.socket**::
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
# Our service won't need permissions for the socket, since it
# inherits the file descriptor by socket activation.
# Only the nginx daemon will need access to the socket:
SocketUser=www-data
SocketGroup=www-data
# Once the user/group is correct, restrict the permissions:
SocketMode=0660
[Install]
WantedBy=sockets.target
Next enable and start the socket (it will autostart at boot too)::
systemctl enable --now gunicorn.socket
Now let's see if the nginx daemon will be able to connect to the socket.
Running ``sudo -u www-data curl --unix-socket /run/gunicorn.sock http``,
our Gunicorn service will be automatically started and you should see some
HTML from your server in the terminal.
.. note::
systemd employs cgroups to track the processes of a service, so it doesn't
need pid files. In the rare case that you need to find out the service main
pid, you can use ``systemctl show --value -p MainPID gunicorn.service``, but
if you only want to send a signal an even better option is
``systemctl kill -s HUP gunicorn.service``.
.. note::
``www-data`` is the default nginx user in debian, other distributions use
different users (for example: ``http`` or ``nginx``). Check your distro to
know what to put for the socket user, and for the sudo command.
You must now configure your web proxy to send traffic to the new Gunicorn
socket. Edit your ``nginx.conf`` to include the following:
**/etc/nginx/nginx.conf**::
user www-data;
...
http {
server {
listen 8000;
server_name 127.0.0.1;
location / {
proxy_pass http://unix:/run/gunicorn.sock;
}
}
}
...
.. note::
The listen and server_name used here are configured for a local machine.
In a production server you will most likely listen on port 80,
and use your URL as the server_name.
Now make sure you enable the nginx service so it automatically starts at boot::
systemctl enable nginx.service
Either reboot, or start Nginx with the following command::
systemctl start nginx
Now you should be able to test Nginx with Gunicorn by visiting
http://127.0.0.1:8000/ in any web browser. Systemd is now set up.
Logging
=======
Logging can be configured by using various flags detailed in the
`configuration documentation`_ or by creating a `logging configuration file`_.
Send the ``USR1`` signal to rotate logs if you are using the logrotate
utility::
kill -USR1 $(cat /var/run/gunicorn.pid)
.. note::
Overriding the ``LOGGING`` dictionary requires to set
``disable_existing_loggers: False`` to not interfere with the Gunicorn
logging.
.. warning::
Gunicorn error log is here to log errors from Gunicorn, not from another
application.
.. _Nginx: https://nginx.org/
.. _Hey: https://github.com/rakyll/hey
.. _`example configuration`: https://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf
.. _runit: http://smarden.org/runit/
.. _`example service`: https://github.com/benoitc/gunicorn/blob/master/examples/gunicorn_rc
.. _Supervisor: http://supervisord.org/
.. _`simple configuration`: https://github.com/benoitc/gunicorn/blob/master/examples/supervisor.conf
.. _`configuration documentation`: http://docs.gunicorn.org/en/latest/settings.html#logging
.. _`logging configuration file`: https://github.com/benoitc/gunicorn/blob/master/examples/logging.conf
.. _Virtualenv: https://pypi.python.org/pypi/virtualenv
.. _Systemd: https://www.freedesktop.org/wiki/Software/systemd/
.. _Gaffer: https://gaffer.readthedocs.io/
.. _`ignoring client abort`: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_client_abort

View File

@ -1,150 +0,0 @@
.. _design:
======
Design
======
A brief description of the architecture of Gunicorn.
Server Model
============
Gunicorn is based on the pre-fork worker model. This means that there is a
central master process that manages a set of worker processes. The master
never knows anything about individual clients. All requests and responses are
handled completely by worker processes.
Master
------
The master process is a simple loop that listens for various process signals
and reacts accordingly. It manages the list of running workers by listening
for signals like TTIN, TTOU, and CHLD. TTIN and TTOU tell the master to
increase or decrease the number of running workers. CHLD indicates that a child
process has terminated, in this case the master process automatically restarts
the failed worker.
Sync Workers
------------
The most basic and the default worker type is a synchronous worker class that
handles a single request at a time. This model is the simplest to reason about
as any errors will affect at most a single request. Though as we describe below
only processing a single request at a time requires some assumptions about how
applications are programmed.
``sync`` worker does not support persistent connections - each connection is
closed after response has been sent (even if you manually add ``Keep-Alive``
or ``Connection: keep-alive`` header in your application).
Async Workers
-------------
The asynchronous workers available are based on Greenlets_ (via Eventlet_ and
Gevent_). Greenlets are an implementation of cooperative multi-threading for
Python. In general, an application should be able to make use of these worker
classes with no changes.
For full greenlet support applications might need to be adapted.
When using, e.g., Gevent_ and Psycopg_ it makes sense to ensure psycogreen_ is
installed and `setup <http://www.gevent.org/api/gevent.monkey.html#plugins>`_.
Other applications might not be compatible at all as they, e.g., rely on
the original unpatched behavior.
Gthread Workers
---------------
The worker `gthread` is a threaded worker. It accepts connections in the
main loop. Accepted connections are added to the thread pool as a
connection job. On keepalive connections are put back in the loop
waiting for an event. If no event happens after the keepalive timeout,
the connection is closed.
Tornado Workers
---------------
There's also a Tornado worker class. It can be used to write applications using
the Tornado framework. Although the Tornado workers are capable of serving a
WSGI application, this is not a recommended configuration.
.. _asyncio-workers:
AsyncIO Workers
---------------
Third-party workers can be used to use Gunicorn with asyncio frameworks.
Choosing a Worker Type
======================
The default synchronous workers assume that your application is resource-bound
in terms of CPU and network bandwidth. Generally this means that your
application shouldn't do anything that takes an undefined amount of time. An
example of something that takes an undefined amount of time is a request to the
internet. At some point the external network will fail in such a way that
clients will pile up on your servers. So, in this sense, any web application
which makes outgoing requests to APIs will benefit from an asynchronous worker.
This resource bound assumption is why we require a buffering proxy in front of
a default configuration Gunicorn. If you exposed synchronous workers to the
internet, a DOS attack would be trivial by creating a load that trickles data to
the servers. For the curious, Hey_ is an example of this type of load.
Some examples of behavior requiring asynchronous workers:
* Applications making long blocking calls (Ie, external web services)
* Serving requests directly to the internet
* Streaming requests and responses
* Long polling
* Web sockets
* Comet
How Many Workers?
=================
DO NOT scale the number of workers to the number of clients you expect to have.
Gunicorn should only need 4-12 worker processes to handle hundreds or thousands
of requests per second.
Gunicorn relies on the operating system to provide all of the load balancing
when handling requests. Generally we recommend ``(2 x $num_cores) + 1`` as the
number of workers to start off with. While not overly scientific, the formula
is based on the assumption that for a given core, one worker will be reading
or writing from the socket while the other worker is processing a request.
Obviously, your particular hardware and application are going to affect the
optimal number of workers. Our recommendation is to start with the above guess
and tune using TTIN and TTOU signals while the application is under load.
Always remember, there is such a thing as too many workers. After a point your
worker processes will start thrashing system resources decreasing the
throughput of the entire system.
How Many Threads?
===================
Since Gunicorn 19, a threads option can be used to process requests in multiple
threads. Using threads assumes use of the gthread worker. One benefit from threads
is that requests can take longer than the worker timeout while notifying the
master process that it is not frozen and should not be killed. Depending on the
system, using multiple threads, multiple worker processes, or some mixture, may
yield the best results. For example, CPython may not perform as well as Jython
when using threads, as threading is implemented differently by each. Using
threads instead of processes is a good way to reduce the memory footprint of
Gunicorn, while still allowing for application upgrades using the reload
signal, as the application code will be shared among workers but loaded only in
the worker processes (unlike when using the preload setting, which loads the
code in the master process).
.. _Greenlets: https://github.com/python-greenlet/greenlet
.. _Eventlet: http://eventlet.net/
.. _Gevent: http://www.gevent.org/
.. _Hey: https://github.com/rakyll/hey
.. _aiohttp: https://docs.aiohttp.org/en/stable/deployment.html#nginx-gunicorn
.. _`example`: https://github.com/benoitc/gunicorn/blob/master/examples/frameworks/flaskapp_aiohttp_wsgi.py
.. _Psycopg: http://initd.org/psycopg/
.. _psycogreen: https://github.com/psycopg/psycogreen/

View File

@ -1,244 +0,0 @@
.. _faq:
===
FAQ
===
WSGI Bits
=========
How do I set SCRIPT_NAME?
-------------------------
By default ``SCRIPT_NAME`` is an empty string. The value could be set by
setting ``SCRIPT_NAME`` in the environment or as an HTTP header. Note that
this headers contains and underscore, so it is only accepted from trusted
forwarders listed in the :ref:`forwarded-allow-ips` setting.
.. note::
If your application should appear in a subfolder, your ``SCRIPT_NAME``
would typically start with single slash but contain no trailing slash.
Server Stuff
============
How do I reload my application in Gunicorn?
-------------------------------------------
You can gracefully reload by sending HUP signal to gunicorn::
$ kill -HUP masterpid
How might I test a proxy configuration?
---------------------------------------
The Hey_ program is a great way to test that your proxy is correctly
buffering responses for the synchronous workers::
$ hey -n 10000 -c 100 http://127.0.0.1:5000/
This runs a benchmark of 10000 requests with 100 running concurrently.
How can I name processes?
-------------------------
If you install the Python package setproctitle_ Gunicorn will set the process
names to something a bit more meaningful. This will affect the output you see
in tools like ``ps`` and ``top``. This helps for distinguishing the master
process as well as between masters when running more than one app on a single
machine. See the proc_name_ setting for more information.
Why is there no HTTP Keep-Alive?
--------------------------------
The default Sync workers are designed to run behind Nginx which only uses
HTTP/1.0 with its upstream servers. If you want to deploy Gunicorn to
handle unbuffered requests (ie, serving requests directly from the internet)
you should use one of the async workers.
.. _Hey: https://github.com/rakyll/hey
.. _setproctitle: https://pypi.python.org/pypi/setproctitle
.. _proc_name: settings.html#proc-name
Worker Processes
================
How do I know which type of worker to use?
------------------------------------------
Read the :ref:`design` page for help on the various worker types.
What types of workers are there?
--------------------------------
Check out the configuration docs for worker_class_.
How can I figure out the best number of worker processes?
---------------------------------------------------------
Here is our recommendation for tuning the `number of workers`_.
How can I change the number of workers dynamically?
---------------------------------------------------
TTIN and TTOU signals can be sent to the master to increase or decrease
the number of workers.
To increase the worker count by one::
$ kill -TTIN $masterpid
To decrease the worker count by one::
$ kill -TTOU $masterpid
Does Gunicorn suffer from the thundering herd problem?
------------------------------------------------------
The thundering herd problem occurs when many sleeping request handlers, which
may be either threads or processes, wake up at the same time to handle a new
request. Since only one handler will receive the request, the others will have
been awakened for no reason, wasting CPU cycles. At this time, Gunicorn does
not implement any IPC solution for coordinating between worker processes. You
may experience high load due to this problem when using many workers or
threads. However `a work has been started
<https://github.com/benoitc/gunicorn/issues/792>`_ to remove this issue.
.. _worker_class: settings.html#worker-class
.. _`number of workers`: design.html#how-many-workers
Why I don't see any logs in the console?
----------------------------------------
In version 19.0, Gunicorn doesn't log by default in the console.
To watch the logs in the console you need to use the option ``--log-file=-``.
In version 19.2, Gunicorn logs to the console by default again.
Kernel Parameters
=================
When dealing with large numbers of concurrent connections there are a handful
of kernel parameters that you might need to adjust. Generally these should only
affect sites with a very large concurrent load. These parameters are not
specific to Gunicorn, they would apply to any sort of network server you may be
running.
These commands are for Linux. Your particular OS may have slightly different
parameters.
How can I increase the maximum number of file descriptors?
----------------------------------------------------------
One of the first settings that usually needs to be bumped is the maximum number
of open file descriptors for a given process. For the confused out there,
remember that Unices treat sockets as files.
.. warning:: ``sudo ulimit`` may not work
Considering non-privileged users are not able to relax the limit, you should
firstly switch to root user, increase the limit, then run gunicorn. Using ``sudo
ulimit`` would not take effect.
Try systemd's service unit file, or an initscript which runs as root.
How can I increase the maximum socket backlog?
----------------------------------------------
Listening sockets have an associated queue of incoming connections that are
waiting to be accepted. If you happen to have a stampede of clients that fill
up this queue new connections will eventually start getting dropped.
::
$ sudo sysctl -w net.core.somaxconn="2048"
How can I disable the use of ``sendfile()``
-------------------------------------------
Disabling the use ``sendfile()`` can be done by using the ``--no-sendfile``
setting or by setting the environment variable ``SENDFILE`` to 0.
Troubleshooting
===============
How do I fix Django reporting an ``ImproperlyConfigured`` error?
----------------------------------------------------------------
With asynchronous workers, creating URLs with the ``reverse`` function of
``django.core.urlresolvers`` may fail. Use ``reverse_lazy`` instead.
.. _blocking-os-fchmod:
How do I avoid Gunicorn excessively blocking in ``os.fchmod``?
--------------------------------------------------------------
The current heartbeat system involves calling ``os.fchmod`` on temporary file
handlers and may block a worker for arbitrary time if the directory is on a
disk-backed filesystem. For example, by default ``/tmp`` is not mounted as
``tmpfs`` in Ubuntu; in AWS an EBS root instance volume may sometimes hang for
half a minute and during this time Gunicorn workers may completely block in
``os.fchmod``. ``os.fchmod`` may introduce extra delays if the disk gets full.
Also Gunicorn may refuse to start if it can't create the files when the disk is
full.
Currently to avoid these problems you can use a ``tmpfs`` mount (for a new
directory or for ``/tmp``) and pass its path to ``--worker-tmp-dir``. First,
check whether your ``/tmp`` is disk-backed or RAM-backed::
$ df /tmp
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/xvda1 ... ... ... ... /
No luck. If you are using Fedora or Ubuntu, you should already have a ``tmpfs``
mount at ``/dev/shm``::
$ df /dev/shm
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs ... ... ... ... /dev/shm
In this case you can set ``--worker-tmp-dir /dev/shm``, otherwise you can
create a new ``tmpfs`` mount::
sudo cp /etc/fstab /etc/fstab.orig
sudo mkdir /mem
echo 'tmpfs /mem tmpfs defaults,size=64m,mode=1777,noatime,comment=for-gunicorn 0 0' | sudo tee -a /etc/fstab
sudo mount /mem
Check the result::
$ df /mem
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 65536 0 65536 0% /mem
Now you can set ``--worker-tmp-dir /mem``.
Why are Workers Silently Killed?
--------------------------------------------------------------
A sometimes subtle problem to debug is when a worker process is killed and there
is little logging information about what happened.
If you use a reverse proxy like NGINX you might see 502 returned to a client.
In the gunicorn logs you might simply see ``[35] [INFO] Booting worker with pid: 35``
It's completely normal for workers to be stop and start, for example due to
max-requests setting. Ordinarily gunicorn will capture any signals and log something.
This particular failure case is usually due to a SIGKILL being received, as it's
not possible to catch this signal silence is usually a common side effect! A common
cause of SIGKILL is when OOM killer terminates a process due to low memory condition.
This is increasingly common in container deployments where memory limits are enforced
by cgroups, you'll usually see evidence of this from dmesg::
dmesg | grep gunicorn
Memory cgroup out of memory: Kill process 24534 (gunicorn) score 1506 or sacrifice child
Killed process 24534 (gunicorn) total-vm:1016648kB, anon-rss:550160kB, file-rss:25824kB, shmem-rss:0kB
In these instances adjusting the memory limit is usually your best bet, it's also possible
to configure OOM not to send SIGKILL by default.

View File

@ -1,46 +0,0 @@
======================
Gunicorn - WSGI server
======================
.. image:: _static/gunicorn.png
:Website: http://gunicorn.org
:Source code: https://github.com/benoitc/gunicorn
:Issue tracker: https://github.com/benoitc/gunicorn/issues
:IRC: ``#gunicorn`` on Libera Chat
:Usage questions: https://github.com/benoitc/gunicorn/issues
Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork
worker model ported from Ruby's Unicorn project. The Gunicorn server is broadly
compatible with various web frameworks, simply implemented, light on server
resources, and fairly speedy.
Features
--------
* Natively supports WSGI, Django, and Paster
* Automatic worker process management
* Simple Python configuration
* Multiple worker configurations
* Various server hooks for extensibility
* Compatible with Python 3.x >= 3.10
Contents
--------
.. toctree::
:maxdepth: 2
install
run
configure
settings
instrumentation
deploy
signals
custom
design
faq
community
news

View File

@ -1,172 +0,0 @@
============
Installation
============
.. highlight:: bash
:Requirements: **Python 3.x >= 3.10**
To install the latest released version of Gunicorn::
$ pip install gunicorn
From Source
===========
You can install Gunicorn from source just as you would install any other
Python package::
$ pip install git+https://github.com/benoitc/gunicorn.git
This will allow you to keep up to date with development on GitHub::
$ pip install -U git+https://github.com/benoitc/gunicorn.git
Async Workers
=============
You may also want to install Eventlet_ or Gevent_ if you expect that your
application code may need to pause for extended periods of time during request
processing. Check out the `design docs`_ for more information on when you'll
want to consider one of the alternate worker types.
::
$ pip install greenlet # Required for both
$ pip install eventlet # For eventlet workers
$ pip install gunicorn[eventlet] # Or, using extra
$ pip install gevent # For gevent workers
$ pip install gunicorn[gevent] # Or, using extra
.. note::
Both require ``greenlet``, which should get installed automatically.
If its installation fails, you probably need to install
the Python headers. These headers are available in most package
managers. On Ubuntu the package name for ``apt-get`` is
``python-dev``.
Gevent_ also requires that ``libevent`` 1.4.x or 2.0.4 is installed.
This could be a more recent version than what is available in your
package manager. If Gevent_ fails to build even with libevent_
installed, this is the most likely reason.
Extra Packages
==============
Some Gunicorn options require additional packages. You can use the ``[extra]``
syntax to install these at the same time as Gunicorn.
Most extra packages are needed for alternate worker types. See the
`design docs`_ for more information on when you'll want to consider an
alternate worker type.
* ``gunicorn[eventlet]`` - Eventlet-based greenlets workers
* ``gunicorn[gevent]`` - Gevent-based greenlets workers
* ``gunicorn[gthread]`` - Threaded workers
* ``gunicorn[tornado]`` - Tornado-based workers, not recommended
If you are running more than one instance of Gunicorn, the :ref:`proc-name`
setting will help distinguish between them in tools like ``ps`` and ``top``.
* ``gunicorn[setproctitle]`` - Enables setting the process name
Multiple extras can be combined, like
``pip install gunicorn[gevent,setproctitle]``.
Debian GNU/Linux
================
If you are using Debian GNU/Linux it is recommended that you use
system packages to install Gunicorn except maybe when you want to use
different versions of Gunicorn with virtualenv. This has a number of
advantages:
* Zero-effort installation: Automatically starts multiple Gunicorn instances
based on configurations defined in ``/etc/gunicorn.d``.
* Sensible default locations for logs (``/var/log/gunicorn``). Logs
can be automatically rotated and compressed using ``logrotate``.
* Improved security: Can easily run each Gunicorn instance with a dedicated
UNIX user/group.
* Sensible upgrade path: Upgrades to newer versions result in less downtime,
handle conflicting changes in configuration options, and can be quickly
rolled back in case of incompatibility. The package can also be purged
entirely from the system in seconds.
stable ("buster")
------------------
The version of Gunicorn in the Debian_ "stable" distribution is 19.9.0
(December 2020). You can install it using::
$ sudo apt-get install gunicorn3
You can also use the most recent version 20.0.4 (December 2020) by using
`Debian Backports`_. First, copy the following line to your
``/etc/apt/sources.list``::
deb http://ftp.debian.org/debian buster-backports main
Then, update your local package lists::
$ sudo apt-get update
You can then install the latest version using::
$ sudo apt-get -t buster-backports install gunicorn
oldstable ("stretch")
---------------------
While Debian releases newer than Stretch will give you gunicorn with Python 3
support no matter if you install the gunicorn or gunicorn3 package for Stretch
you specifically have to install gunicorn3 to get Python 3 support.
The version of Gunicorn in the Debian_ "oldstable" distribution is 19.6.0
(December 2020). You can install it using::
$ sudo apt-get install gunicorn3
You can also use the most recent version 19.7.1 (December 2020) by using
`Debian Backports`_. First, copy the following line to your
``/etc/apt/sources.list``::
deb http://ftp.debian.org/debian stretch-backports main
Then, update your local package lists::
$ sudo apt-get update
You can then install the latest version using::
$ sudo apt-get -t stretch-backports install gunicorn3
Testing ("bullseye") / Unstable ("sid")
---------------------------------------
"bullseye" and "sid" contain the latest released version of Gunicorn 20.0.4
(December 2020). You can install it in the usual way::
$ sudo apt-get install gunicorn
Ubuntu
======
Ubuntu_ 20.04 LTS (Focal Fossa) or later contains the Gunicorn package by
default 20.0.4 (December 2020) so that you can install it in the usual way::
$ sudo apt-get update
$ sudo apt-get install gunicorn
.. _`design docs`: design.html
.. _Eventlet: http://eventlet.net
.. _Gevent: http://www.gevent.org/
.. _libevent: http://libevent.org/
.. _Debian: https://www.debian.org/
.. _`Debian Backports`: https://backports.debian.org/
.. _Ubuntu: https://www.ubuntu.com/

View File

@ -1,36 +0,0 @@
.. _instrumentation:
===============
Instrumentation
===============
.. versionadded:: 19.1
Gunicorn provides an optional instrumentation of the arbiter and
workers using the statsD_ protocol over UDP. Thanks to the
``gunicorn.instrument.statsd`` module, Gunicorn becomes a statsD client.
The use of UDP cleanly isolates Gunicorn from the receiving end of the statsD
metrics so that instrumentation does not cause Gunicorn to be held up by a slow
statsD consumer.
To use statsD, just tell Gunicorn where the statsD server is:
.. code-block:: bash
$ gunicorn --statsd-host=localhost:8125 --statsd-prefix=service.app ...
The ``Statsd`` logger overrides ``gunicorn.glogging.Logger`` to track
all requests. The following metrics are generated:
* ``gunicorn.requests``: request rate per second
* ``gunicorn.request.duration``: histogram of request duration (in millisecond)
* ``gunicorn.workers``: number of workers managed by the arbiter (gauge)
* ``gunicorn.log.critical``: rate of critical log messages
* ``gunicorn.log.error``: rate of error log messages
* ``gunicorn.log.warning``: rate of warning log messages
* ``gunicorn.log.exception``: rate of exceptional log messages
See the statsd-host_ setting for more information.
.. _statsd-host: settings.html#statsd-host
.. _statsD: https://github.com/etsy/statsd

View File

@ -1,83 +0,0 @@
=========
Changelog
=========
23.0.0 - 2024-08-10
===================
- minor docs fixes (:pr:`3217`, :pr:`3089`, :pr:`3167`)
- worker_class parameter accepts a class (:pr:`3079`)
- fix deadlock if request terminated during chunked parsing (:pr:`2688`)
- permit receiving Transfer-Encodings: compress, deflate, gzip (:pr:`3261`)
- permit Transfer-Encoding headers specifying multiple encodings. note: no parameters, still (:pr:`3261`)
- sdist generation now explicitly excludes sphinx build folder (:pr:`3257`)
- decode bytes-typed status (as can be passed by gevent) as utf-8 instead of raising `TypeError` (:pr:`2336`)
- raise correct Exception when encounting invalid chunked requests (:pr:`3258`)
- the SCRIPT_NAME and PATH_INFO headers, when received from allowed forwarders, are no longer restricted for containing an underscore (:pr:`3192`)
- include IPv6 loopback address ``[::1]`` in default for :ref:`forwarded-allow-ips` and :ref:`proxy-allow-ips` (:pr:`3192`)
** NOTE **
- The SCRIPT_NAME change mitigates a regression that appeared first in the 22.0.0 release
- Review your :ref:`forwarded-allow-ips` setting if you are still not seeing the SCRIPT_NAME transmitted
- Review your :ref:`forwarder-headers` setting if you are missing headers after upgrading from a version prior to 22.0.0
** Breaking changes **
- refuse requests where the uri field is empty (:pr:`3255`)
- refuse requests with invalid CR/LR/NUL in heade field values (:pr:`3253`)
- remove temporary ``--tolerate-dangerous-framing`` switch from 22.0 (:pr:`3260`)
- If any of the breaking changes affect you, be aware that now refused requests can post a security problem, especially so in setups involving request pipe-lining and/or proxies.
22.0.0 - 2024-04-17
===================
- use `utime` to notify workers liveness
- migrate setup to pyproject.toml
- fix numerous security vulnerabilities in HTTP parser (closing some request smuggling vectors)
- parsing additional requests is no longer attempted past unsupported request framing
- on HTTP versions < 1.1 support for chunked transfer is refused (only used in exploits)
- requests conflicting configured or passed SCRIPT_NAME now produce a verbose error
- Trailer fields are no longer inspected for headers indicating secure scheme
- support Python 3.12
** Breaking changes **
- minimum version is Python 3.7
- the limitations on valid characters in the HTTP method have been bounded to Internet Standards
- requests specifying unsupported transfer coding (order) are refused by default (rare)
- HTTP methods are no longer casefolded by default (IANA method registry contains none affected)
- HTTP methods containing the number sign (#) are no longer accepted by default (rare)
- HTTP versions < 1.0 or >= 2.0 are no longer accepted by default (rare, only HTTP/1.1 is supported)
- HTTP versions consisting of multiple digits or containing a prefix/suffix are no longer accepted
- HTTP header field names Gunicorn cannot safely map to variables are silently dropped, as in other software
- HTTP headers with empty field name are refused by default (no legitimate use cases, used in exploits)
- requests with both Transfer-Encoding and Content-Length are refused by default (such a message might indicate an attempt to perform request smuggling)
- empty transfer codings are no longer permitted (reportedly seen with really old & broken proxies)
** SECURITY **
- fix CVE-2024-1135
History
=======
.. toctree::
:titlesonly:
2024-news
2023-news
2021-news
2020-news
2019-news
2018-news
2017-news
2016-news
2015-news
2014-news
2013-news
2012-news
2011-news
2010-news

View File

@ -1,184 +0,0 @@
================
Running Gunicorn
================
.. highlight:: bash
You can run Gunicorn by using commands or integrate with popular frameworks
like Django, Pyramid, or TurboGears. For deploying Gunicorn in production see
:doc:`deploy`.
Commands
========
After installing Gunicorn you will have access to the command line script
``gunicorn``.
.. _gunicorn-cmd:
gunicorn
--------
Basic usage::
$ gunicorn [OPTIONS] [WSGI_APP]
Where ``WSGI_APP`` is of the pattern ``$(MODULE_NAME):$(VARIABLE_NAME)``. The
module name can be a full dotted path. The variable name refers to a WSGI
callable that should be found in the specified module.
.. versionchanged:: 20.1.0
``WSGI_APP`` is optional if it is defined in a :ref:`config` file.
Example with the test app:
.. code-block:: python
def app(environ, start_response):
"""Simplest possible application object"""
data = b'Hello, World!\n'
status = '200 OK'
response_headers = [
('Content-type', 'text/plain'),
('Content-Length', str(len(data)))
]
start_response(status, response_headers)
return iter([data])
You can now run the app with the following command:
.. code-block:: text
$ gunicorn --workers=2 test:app
The variable name can also be a function call. In that case the name
will be imported from the module, then called to get the application
object. This is commonly referred to as the "application factory"
pattern.
.. code-block:: python
def create_app():
app = FrameworkApp()
...
return app
.. code-block:: text
$ gunicorn --workers=2 'test:create_app()'
Positional and keyword arguments can also be passed, but it is
recommended to load configuration from environment variables rather than
the command line.
Commonly Used Arguments
^^^^^^^^^^^^^^^^^^^^^^^
* ``-c CONFIG, --config=CONFIG`` - Specify a config file in the form
``$(PATH)``, ``file:$(PATH)``, or ``python:$(MODULE_NAME)``.
* ``-b BIND, --bind=BIND`` - Specify a server socket to bind. Server sockets
can be any of ``$(HOST)``, ``$(HOST):$(PORT)``, ``fd://$(FD)``, or
``unix:$(PATH)``. An IP is a valid ``$(HOST)``.
* ``-w WORKERS, --workers=WORKERS`` - The number of worker processes. This
number should generally be between 2-4 workers per core in the server.
Check the :ref:`faq` for ideas on tuning this parameter.
* ``-k WORKERCLASS, --worker-class=WORKERCLASS`` - The type of worker process
to run. You'll definitely want to read the production page for the
implications of this parameter. You can set this to ``$(NAME)``
where ``$(NAME)`` is one of ``sync``, ``eventlet``, ``gevent``,
``tornado``, ``gthread``.
``sync`` is the default. See the :ref:`worker-class` documentation for more
information.
* ``-n APP_NAME, --name=APP_NAME`` - If setproctitle_ is installed you can
adjust the name of Gunicorn process as they appear in the process system
table (which affects tools like ``ps`` and ``top``).
Settings can be specified by using environment variable
:ref:`GUNICORN_CMD_ARGS <settings>`.
See :ref:`configuration` and :ref:`settings` for detailed usage.
.. _setproctitle: https://pypi.python.org/pypi/setproctitle
Integration
===========
Gunicorn also provides integration for Django and Paste Deploy applications.
Django
------
Gunicorn will look for a WSGI callable named ``application`` if not specified.
So for a typical Django project, invoking Gunicorn would look like::
$ gunicorn myproject.wsgi
.. note::
This requires that your project be on the Python path; the simplest way to
ensure that is to run this command from the same directory as your
``manage.py`` file.
You can use the
`--env <http://docs.gunicorn.org/en/latest/settings.html#raw-env>`_ option
to set the path to load the settings. In case you need it you can also
add your application path to ``PYTHONPATH`` using the
`--pythonpath <http://docs.gunicorn.org/en/latest/settings.html#pythonpath>`_
option::
$ gunicorn --env DJANGO_SETTINGS_MODULE=myproject.settings myproject.wsgi
Paste Deployment
----------------
Frameworks such as Pyramid and Turbogears are typically configured using Paste
Deployment configuration files. If you would like to use these files with
Gunicorn, there are two approaches.
As a server runner, Gunicorn can serve your application using the commands from
your framework, such as ``pserve`` or ``gearbox``. To use Gunicorn with these
commands, specify it as a server in your configuration file:
.. code-block:: ini
[server:main]
use = egg:gunicorn#main
host = 127.0.0.1
port = 8080
workers = 3
This approach is the quickest way to get started with Gunicorn, but there are
some limitations. Gunicorn will have no control over how the application is
loaded, so settings such as reload_ will have no effect and Gunicorn will be
unable to hot upgrade a running application. Using the daemon_ option may
confuse your command line tool. Instead, use the built-in support for these
features provided by that tool. For example, run ``pserve --reload`` instead of
specifying ``reload = True`` in the server configuration block. For advanced
configuration of Gunicorn, such as `Server Hooks`_ specifying a Gunicorn
configuration file using the ``config`` key is supported.
To use the full power of Gunicorn's reloading and hot code upgrades, use the
`paste option`_ to run your application instead. When used this way, Gunicorn
will use the application defined by the PasteDeploy configuration file, but
Gunicorn will not use any server configuration defined in the file. Instead,
`configure gunicorn`_.
For example::
$ gunicorn --paste development.ini -b :8080 --chdir /path/to/project
Or use a different application::
$ gunicorn --paste development.ini#admin -b :8080 --chdir /path/to/project
With both approaches, Gunicorn will use any loggers section found in Paste
Deployment configuration file, unless instructed otherwise by specifying
additional `logging settings`_.
.. _reload: http://docs.gunicorn.org/en/latest/settings.html#reload
.. _daemon: http://docs.gunicorn.org/en/latest/settings.html#daemon
.. _Server Hooks: http://docs.gunicorn.org/en/latest/settings.html#server-hooks
.. _paste option: http://docs.gunicorn.org/en/latest/settings.html#paste
.. _configure gunicorn: http://docs.gunicorn.org/en/latest/configure.html
.. _logging settings: http://docs.gunicorn.org/en/latest/settings.html#logging

File diff suppressed because it is too large Load Diff

View File

@ -1,119 +0,0 @@
.. _signals:
===============
Signal Handling
===============
A brief description of the signals handled by Gunicorn. We also document the
signals used internally by Gunicorn to communicate with the workers.
Master process
==============
- ``QUIT``, ``INT``: Quick shutdown
- ``TERM``: Graceful shutdown. Waits for workers to finish their
current requests up to the :ref:`graceful-timeout`.
- ``HUP``: Reload the configuration, start the new worker processes with a new
configuration and gracefully shutdown older workers. If the application is
not preloaded (using the :ref:`preload-app` option), Gunicorn will also load
the new version of it.
- ``TTIN``: Increment the number of processes by one
- ``TTOU``: Decrement the number of processes by one
- ``USR1``: Reopen the log files
- ``USR2``: Upgrade Gunicorn on the fly. A separate ``TERM`` signal should
be used to kill the old master process. This signal can also be used to use
the new versions of pre-loaded applications. See :ref:`binary-upgrade` for
more information.
- ``WINCH``: Gracefully shutdown the worker processes when Gunicorn is
daemonized.
Worker process
==============
Sending signals directly to the worker processes should not normally be
needed. If the master process is running, any exited worker will be
automatically respawned.
- ``QUIT``, ``INT``: Quick shutdown
- ``TERM``: Graceful shutdown
- ``USR1``: Reopen the log files
Reload the configuration
========================
The ``HUP`` signal can be used to reload the Gunicorn configuration on the
fly.
::
2013-06-29 06:26:55 [20682] [INFO] Handling signal: hup
2013-06-29 06:26:55 [20682] [INFO] Hang up: Master
2013-06-29 06:26:55 [20703] [INFO] Booting worker with pid: 20703
2013-06-29 06:26:55 [20702] [INFO] Booting worker with pid: 20702
2013-06-29 06:26:55 [20688] [INFO] Worker exiting (pid: 20688)
2013-06-29 06:26:55 [20687] [INFO] Worker exiting (pid: 20687)
2013-06-29 06:26:55 [20689] [INFO] Worker exiting (pid: 20689)
2013-06-29 06:26:55 [20704] [INFO] Booting worker with pid: 20704
Sending a ``HUP`` signal will reload the configuration, start the new
worker processes with a new configuration and gracefully shutdown older
workers. If the application is not preloaded (using the :ref:`preload-app`
option), Gunicorn will also load the new version of it.
.. _binary-upgrade:
Upgrading to a new binary on the fly
====================================
.. versionchanged:: 19.6.0
PID file naming format has been changed from ``<name>.pid.oldbin`` to
``<name>.pid.2``.
If you need to replace the Gunicorn binary with a new one (when
upgrading to a new version or adding/removing server modules), you can
do it without any service downtime - no incoming requests will be
lost. Preloaded applications will also be reloaded.
First, replace the old binary with a new one, then send a ``USR2`` signal to
the current master process. It executes a new binary whose PID file is
postfixed with ``.2`` (e.g. ``/var/run/gunicorn.pid.2``),
which in turn starts a new master process and new worker processes::
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
20844 benoitc 20 0 54808 11m 3352 S 0.0 0.1 0:00.36 gunicorn: master [test:app]
20849 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
20850 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
20851 benoitc 20 0 54808 9.9m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
20854 benoitc 20 0 55748 12m 3348 S 0.0 0.2 0:00.35 gunicorn: master [test:app]
20859 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
20860 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.00 gunicorn: worker [test:app]
20861 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]
At this point, two instances of Gunicorn are running, handling the
incoming requests together. To phase the old instance out, you have to
send a ``WINCH`` signal to the old master process, and its worker
processes will start to gracefully shut down.
At this point you can still revert to the old process since it hasn't closed
its listen sockets yet, by following these steps:
- Send a ``HUP`` signal to the old master process - it will start the worker
processes without reloading a configuration file
- Send a ``TERM`` signal to the new master process to gracefully shut down its
worker processes
- Send a ``QUIT`` signal to the new master process to force it quit
If for some reason the new worker processes do not quit, send a ``KILL`` signal
to them after the new master process quits, and everything will back to exactly
as before the upgrade attempt.
If the update is successful and you want to keep the new master process, send a
``TERM`` signal to the old master process to leave only the new server
running::
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
20854 benoitc 20 0 55748 12m 3348 S 0.0 0.2 0:00.45 gunicorn: master [test:app]
20859 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
20860 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.02 gunicorn: worker [test:app]
20861 benoitc 20 0 55748 11m 1500 S 0.0 0.1 0:00.01 gunicorn: worker [test:app]

View File

@ -2,7 +2,7 @@
# 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.
version_info = (23, 0, 0) version_info = (24, 0, 0)
__version__ = ".".join([str(v) for v in version_info]) __version__ = ".".join([str(v) for v in version_info])
SERVER = "gunicorn" SERVER = "gunicorn"
SERVER_SOFTWARE = "%s/%s" % (SERVER, __version__) SERVER_SOFTWARE = "%s/%s" % (SERVER, __version__)