From 58d803977d3a124dd16d97ed7af1df5a2d352c90 Mon Sep 17 00:00:00 2001 From: Benoit Chesneau Date: Fri, 23 Jan 2026 01:12:46 +0100 Subject: [PATCH] bump version to 24.0.0, remove sphinx docs --- docs/Makefile | 160 --- docs/README.rst | 19 - docs/gunicorn_ext.py | 102 -- docs/logo/gunicorn.png | Bin 21550 -> 0 bytes docs/logo/gunicorn.svg | 119 -- docs/make.bat | 190 --- docs/site/.nojekyll | 0 docs/site/CNAME | 1 - docs/site/community.html | 13 - docs/site/configuration.html | 13 - docs/site/configure.html | 13 - docs/site/css/style.css | 402 ------ docs/site/deploy.html | 13 - docs/site/deployment.html | 13 - docs/site/design.html | 13 - docs/site/faq.html | 13 - docs/site/images/about.jpg | Bin 17551 -> 0 bytes docs/site/images/arrow.png | Bin 408 -> 0 bytes docs/site/images/banner-bg.jpg | Bin 611 -> 0 bytes docs/site/images/community.jpg | Bin 15593 -> 0 bytes docs/site/images/documents.jpg | Bin 17566 -> 0 bytes docs/site/images/downloads.jpg | Bin 15962 -> 0 bytes docs/site/images/favicon.png | Bin 1771 -> 0 bytes docs/site/images/footer-arrow.png | Bin 255 -> 0 bytes docs/site/images/footer-logo.jpg | Bin 2499 -> 0 bytes docs/site/images/greenbutton.jpg | Bin 335 -> 0 bytes docs/site/images/gunicorn.png | Bin 1553 -> 0 bytes docs/site/images/large_gunicorn.png | Bin 21956 -> 0 bytes docs/site/images/logo-bottom.png | Bin 3145 -> 0 bytes docs/site/images/logo.jpg | Bin 10238 -> 0 bytes docs/site/images/logo.png | Bin 7343 -> 0 bytes docs/site/images/redbutton.jpg | Bin 577 -> 0 bytes docs/site/images/separator.jpg | Bin 440 -> 0 bytes docs/site/images/title.png | Bin 3450 -> 0 bytes docs/site/images/user1.jpg | Bin 2184 -> 0 bytes docs/site/index.html | 185 --- docs/site/install.html | 13 - docs/site/installation.html | 13 - docs/site/js/main.js | 46 - docs/site/news.html | 13 - docs/site/run.html | 13 - docs/site/sitemap.xml | 73 -- docs/site/tuning.html | 13 - docs/site/usage.html | 13 - docs/sitemap_gen.py | 41 - docs/source/2010-news.rst | 211 ---- docs/source/2011-news.rst | 73 -- docs/source/2012-news.rst | 128 -- docs/source/2013-news.rst | 90 -- docs/source/2014-news.rst | 228 ---- docs/source/2015-news.rst | 219 ---- docs/source/2016-news.rst | 91 -- docs/source/2017-news.rst | 46 - docs/source/2018-news.rst | 68 - docs/source/2019-news.rst | 121 -- docs/source/2020-news.rst | 7 - docs/source/2021-news.rst | 54 - docs/source/2023-news.rst | 39 - docs/source/2024-news.rst | 61 - docs/source/_static/gunicorn.png | Bin 14398 -> 0 bytes docs/source/community.rst | 37 - docs/source/conf.py | 72 -- docs/source/configure.rst | 118 -- docs/source/custom.rst | 72 -- docs/source/deploy.rst | 380 ------ docs/source/design.rst | 150 --- docs/source/faq.rst | 244 ---- docs/source/index.rst | 46 - docs/source/install.rst | 172 --- docs/source/instrumentation.rst | 36 - docs/source/news.rst | 83 -- docs/source/run.rst | 184 --- docs/source/settings.rst | 1795 --------------------------- docs/source/signals.rst | 119 -- gunicorn/__init__.py | 2 +- 75 files changed, 1 insertion(+), 6452 deletions(-) delete mode 100644 docs/Makefile delete mode 100644 docs/README.rst delete mode 100755 docs/gunicorn_ext.py delete mode 100644 docs/logo/gunicorn.png delete mode 100644 docs/logo/gunicorn.svg delete mode 100644 docs/make.bat delete mode 100644 docs/site/.nojekyll delete mode 100644 docs/site/CNAME delete mode 100644 docs/site/community.html delete mode 100644 docs/site/configuration.html delete mode 100644 docs/site/configure.html delete mode 100644 docs/site/css/style.css delete mode 100644 docs/site/deploy.html delete mode 100644 docs/site/deployment.html delete mode 100644 docs/site/design.html delete mode 100644 docs/site/faq.html delete mode 100644 docs/site/images/about.jpg delete mode 100644 docs/site/images/arrow.png delete mode 100644 docs/site/images/banner-bg.jpg delete mode 100644 docs/site/images/community.jpg delete mode 100644 docs/site/images/documents.jpg delete mode 100644 docs/site/images/downloads.jpg delete mode 100644 docs/site/images/favicon.png delete mode 100644 docs/site/images/footer-arrow.png delete mode 100644 docs/site/images/footer-logo.jpg delete mode 100644 docs/site/images/greenbutton.jpg delete mode 100644 docs/site/images/gunicorn.png delete mode 100644 docs/site/images/large_gunicorn.png delete mode 100644 docs/site/images/logo-bottom.png delete mode 100644 docs/site/images/logo.jpg delete mode 100644 docs/site/images/logo.png delete mode 100644 docs/site/images/redbutton.jpg delete mode 100644 docs/site/images/separator.jpg delete mode 100644 docs/site/images/title.png delete mode 100644 docs/site/images/user1.jpg delete mode 100644 docs/site/index.html delete mode 100644 docs/site/install.html delete mode 100644 docs/site/installation.html delete mode 100755 docs/site/js/main.js delete mode 100644 docs/site/news.html delete mode 100644 docs/site/run.html delete mode 100644 docs/site/sitemap.xml delete mode 100644 docs/site/tuning.html delete mode 100644 docs/site/usage.html delete mode 100644 docs/sitemap_gen.py delete mode 100644 docs/source/2010-news.rst delete mode 100644 docs/source/2011-news.rst delete mode 100644 docs/source/2012-news.rst delete mode 100644 docs/source/2013-news.rst delete mode 100644 docs/source/2014-news.rst delete mode 100644 docs/source/2015-news.rst delete mode 100644 docs/source/2016-news.rst delete mode 100644 docs/source/2017-news.rst delete mode 100644 docs/source/2018-news.rst delete mode 100644 docs/source/2019-news.rst delete mode 100644 docs/source/2020-news.rst delete mode 100644 docs/source/2021-news.rst delete mode 100644 docs/source/2023-news.rst delete mode 100644 docs/source/2024-news.rst delete mode 100644 docs/source/_static/gunicorn.png delete mode 100644 docs/source/community.rst delete mode 100644 docs/source/conf.py delete mode 100644 docs/source/configure.rst delete mode 100644 docs/source/custom.rst delete mode 100644 docs/source/deploy.rst delete mode 100644 docs/source/design.rst delete mode 100644 docs/source/faq.rst delete mode 100644 docs/source/index.rst delete mode 100644 docs/source/install.rst delete mode 100644 docs/source/instrumentation.rst delete mode 100644 docs/source/news.rst delete mode 100644 docs/source/run.rst delete mode 100644 docs/source/settings.rst delete mode 100644 docs/source/signals.rst diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 7fa4085e..00000000 --- a/docs/Makefile +++ /dev/null @@ -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 ' where 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." diff --git a/docs/README.rst b/docs/README.rst deleted file mode 100644 index 9ec55d05..00000000 --- a/docs/README.rst +++ /dev/null @@ -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. diff --git a/docs/gunicorn_ext.py b/docs/gunicorn_ext.py deleted file mode 100755 index 4310162e..00000000 --- a/docs/gunicorn_ext.py +++ /dev/null @@ -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) diff --git a/docs/logo/gunicorn.png b/docs/logo/gunicorn.png deleted file mode 100644 index 8b9e4c9e37d16b2127ed4fb97dbba68c1d974d05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21550 zcmX`T1yq#Z_dWd3-Q6kO4bqJ?f^?U3N|$tpbeDki|Kaofz3(E| zux94Qx##Y)_ddjEs3~BelA;0tfT5%)s|5hCTj1}7$cW%~6p?u`@CTxWvVtt|{POX+ zqd4{D53Y*(9^f_E|j2^YtN{ zndx8SrCV~hV8ljFu0DNz3;m^K0F{hpH{?}gLN!#@cZ#ZzynUmr?1tva`8tLo1OKi@ zPSP>Kae+aj4j*}4((p4oyJ3h(@~1I1Hp6V;H7dg7NVY~Bc~Yg_8&O}q!WNIy7Tc5d zoAH)iTu0niW^EA-kuw=4q3A4sc7(W*CT3I8d

?8|Dz+nSHCguwYKUu1#rsk>U8_C1EBr3T5Qo=EsF z9iF084+*go*Y>LJV1lv;TFdG>FSp~-E?(Onm6i_IVm!?ms_1>rKIplQTU^8O{@;_a zFQk)$<*(Wg^uMjonH^njcWuvQl?XfcQ4LO)`W`PYIQAqpw?sT!@Fw;l0O5;fH4M45Hrj_87cd2#;wHw@Jk}8F^PD{0%ekAbsBVzqNt? z5`u7RJ3U^pGD~}iiXBV@4Ig_rq6ncwkFESnF!5L5FGFsn!six0v5?=R_1U^%?@5SH z;e4=up27_;+5A2_?rgq?bCdYrYklMi>@968V_;^egrBkohMUf&_|ZL?N0Un4xJ{Rw zrAT^wpbE(oHM>`bE|17|$W9-IoeF>L{+HDJ?Z4d(MZOqCxuowzTdy4puXP+03Hdtu zS8#PyMEoe{3e$avi|BMu79lL%||sjX_93D|pabe*3@GhHp7kae;`}Aj{2# z+`b7&VR2I~e?<-3NJ-MQ^7G{E=uFR|2j_jIAI|40zjo8vkNZSnPu*(^kbwVNY}!Eu zRUMBRJ_5dik5%zcEGA>Jkv$Ld|E};_dvzm`n!MyxJ+400tk9LU%YDmTocwjJ>!$O+ zspD)_;u#QYA-%&eLftupNlQ4tfC*WG>~WV(AMA;@`L7fO;lHm8f`dv4Pb(b8wA5It z%~Aa{MleU;RASN=5fW;q3R#K%K~CrYZaC%#x}-2KUdRma4rh`DCPu`)JkpO2yJz)zg{R_Vf+zbu`(iUaqc{wg_`qF^ zl&5t$jaOWAIduSu@mw*i5CnpS;A(a-aRT5QrkWR;*aXEyXV9k(Wr~Q1tP(k(fd>tN zW>Dhm_4p#3KEI2ZS;kmv=Ma<%C4fnCVB6LEk$RT+KE1g@V^90tyE_JzELU`1Bmf>D z&-ikFWNBkk$TZAbTKZ%@StwVa=<>3-zU+g7xH}To>(fRhb#cbmT{ZplE`1*&q^)*F zA^urKz9{mY`A#|82lPNakB2fJX&@>cC?9B^)em0fQ-dF7$!7bXP|gcLNbH<@^;C$GfpL z9yz}IGa@2DeyaW}%rfHo5Au==t`M^O`}^S4sj1X7N__AgFW!MG`&sxi&c8WIvAqGO zyV&WU8}1>=$w~0AABVtceTp6*n{=};DP-EMZ)i{&)_NIb7lJUr$Is8qspfm0^YgD^ zh&OBXlYfn)*6q2a7`YO5dwk`gN7k*pm4y5%Ib*~5 zHtLPzD*f>0n-f;7-8-^*q2GYmDXsEFZvQ`3z$ zU<>;Lo{RfR_Yuf{RT%Z=%^S*3XG~JqQYXUp*=6I_zd8^mQ{(R~JVYjNG6~&LRHqVQ z&+tQdqGIcT`X8l!styi^2iz*C*XBDdfZ8}jAzwd9{%fR9^p6Qgb9Xj2$}`h_OHX1ZM#`r56BWmauw zqZ@u}5ZBnz+>i`MYgt-ax`G*d?oA+9Qcu?p1LcZugPGpyX*SQ^>FP_pcoJTaAQ-EDeRfSelqn5Fa=4YvbfrCkSAl8^x{NE{gCQu)@z@MZz#AD9K< zcM#O@=Lp+}e}7lzL^$I|igP^L+w)l)5+RMmc||*6!$niLt*WY;;q&&1hmX%wJVeG3 zzea-Blq~}v9%oBmp-Y!jhQ>;NVb2)jk8e5}%j2Kb(79iHP7~8#B*s-FAap5;-&PV@ zD~;Q(ZD{X)rA|5TB>l{}$RDA|Y7T4y=YjJU70mqQpQ>^3(CSTZSSeT@E1R3vrA|UU zOe;Q#7fkR=obK<(z%`Gj);ZJ0P)%5B)ok7iYfO(m|}27K4G43_YMxHzB3pnY7ZwTb7d&te9WQ*UKaAQ1UqmapN`&f|r9z*oBvD?*y29m>u(K@3b zn7NLsow7#8gM@W9V~dFpTVXamlL_s|-iIy{<&D=Quw{jWjKVF3f zglk!J>Worb*;xd{PFeGK$Xot^+?qNkbdLr^`@~e!q$qBg0;?Vt;zu|4{yz&tsY6BE z^iY+Eis2D7$g+rpl-X#kK4~y%Bd%KwP&tj<`7iVhd6~$2Z4YK9VH4iRj(n zw|Mii-NrbjXVsqPh}ccjtNQ+*iKPeeWn^Rq;F#Q6m%F>Wbs&yWg-n$w?zD^YqH^=Z zU2DOd!0UbXDE5(7B{pX8IMuBQ5lVI9Y_iW7{Af@dElnn28xdKKu-Ft66B|-#w0ya{ z0KG%4bK1cOP8`fAB=FA^ArKp!%!a0>XVw2+qXU}kdES3U!@zg~FVo`-e}hCU2icLX zS$MN~9mA?le<=%&{B3O#S}FO&UFB@lc!nEF#s1-c15@-iO7 z=DuCg3T%sZ?|!sRzEn!C^8Ttpiz~(9NZ8Be4C9IzG8u07DrT>E^8H_}nq2BFLf=3x zY&@*j!iMZ+?|EqW5wk(0u_K?CH(9JI5K(SlA*NBPzNCY;%WRx5s_v>xie>x z**7~}y{=&zA^rW_CxD75)+AFslpOlmC$5@6v(t69Twg3k_KyLr2nKX3Auts}S6XVa zHamM=q^E){o9vGo;rpvQRb-CUai(6->q+-%b3S+e?UZ3r@b|%shL5fR&ic_Draaqy z9e@4*y2y>H2CR3mSO3u-J&I+=JsW; z1HIQrSG3>bsf`nd0(0FJNELW^ZSy3E^Ek#gHur*waUGl>8cg3RO}m1;b#!j(*c^1_ zG#R)q;Q>5>EVCQDNorm!E{}pjreIZiT$g@}nsy~qBU4k;zmp17$Lg~8u=7#TjmmZi zR3TRO?wzDidz+x9=H`E6160B7oNEtXYHNQBy8ZcyYV(8`QZj0kVeog)a%VSnXlsh{ z(7Uv(?Da3cv0ef>NMnq4!${UGm3YBv`t0oNjcl@u8g-L)7gGO;0Qz4I1$E(<15)5vI*fdj$Lb5 zF?#3K+WW}%T7$?#E+M`mAthhi9Z7IVfFP}Wj+@xMhbGh# z$O)HMR2)~45N@f%35^f&Kz!Z!NW~W9^YYVS2q5~1>kzrt`M&~5gjetz1D%>(MH28p6|x4R>KpWU z-#Qpkp8gSM0rbsbRTULAxyjnmOwx&mgZg>wwP?*uL~v~|`w+LWet!S? z`+*5Mv#uiLB_|Ur>peYXQkzzzUG_cP;16oX!gIBOWIW9(pEuV(Dk{Vpo0_~SL&7Ln zE)FxSAC=~=?sarJ++Qw3!cdB^ZnIZ7#$%&8z~J`|La1W&2qeQguf%SV6$sMT)T|j~ zwY3YErs1bd3MPXlWi2G|5_=)K@`s!{WM4D!J~NRf_}zu{fOkBYZ-tVg$CWoPB1rNz zX0NZVRw7e=88Q+Ym1^sV2@|7_>)>x^D_V{0e@_pfV#+#myfZ-SQrvCLkMl=-zr~xX z!PS#HF2nsqnnfjK63;CyL{1s0Ohy><{yE|=gkg;+p^zBb?QVL|NDRx zcjuR?+&mSAwO@S4WVenA#&b7wd=+`oPthr^l`0(46e#PHtE;Pme5yGqPKMJnGZY}w zGDWBc1a#ji@OlEsIFoDqs)j-yJELOldsHAKej`d5%%sXqsZNhe0r_F8qccNqJolUg z`KlIkj`2YN$GB%S7zHtG3e_N)=*tg^_~2r<{j$7-yo&ueUq2ZWe}v*;@31~~#B4YT z6n69y3oHOSz=3iRpC4alw7B)J{mZhD1#qmj>PxW>4w{Kh408z^W<}wb{!g#JL z-9-RBLfSgJXk~b`3hu{{`v*+m*LS;YOo2EtXQ zj7ksv1|5QaFD)&F@(K3fX|fS|JjZz$8?Wfb#l>avTwc@X9^ z2)c>j1QWaQD&KegSbFEk$Ss>p#08)G`O}>{NRZ$}I3meu=DU~d$;f=sutQv`Y1$N* z{u?67OhSM>XJ#d1RD_kG1uWOKWV$9UoM{1^W>z|jaVoIbvmZK8IHD%t!@8@uF42gU z;`Y-KlHU@@>1*lgdcPMq#6gBz|4)7na-# zYItG5Q^3mv?N1rtXm_aqJDSK<13M{gYK16Aww&&8lGIK_BH6(;rA+0j)1otX} z*Jjk!`XXJ#aw7?7yfM4KX<$3NHRJNpYGhfzyzO+E5>R(`g8N3{=kHI2=qg8e|ASbv zxv0pdI23;iz;@WXqc9Xg{)_;KFPv>FLd9ZB)I6l);UsIbwmxIQ0R1oz8lQz-KhOw> zr)RrDlr6eAz#-mkUmI3gMKWQxW1GJI7=0p_XuVciRmJ%RC2PdP5!cIJNomNUSkCvQ z62lQoWXmHKeKQ>WgI~EYz!vbDauU}9HoMhIOIP))L&*UV&VvVqa&9k^@*0nU!ooi& zVXw}A>sjt{P$c9L)tfFq2^ODBeF&Ok0o;&bC4pxit}1)ykIvVg4(Ub?_V(_9=u>=7 z{=oC5S;{G6>X7e+9zOjVGGbVr$M@Qo!wTll4oV!Zeb@T6)8{~@t<2JW;b(dWr0R@Xn+juuEL%F__3P;Uy>v8qagf- zN5N-dIM(~Nq9&CBJ;gB_nnUt(_7$4RA~&Uv@INE_<_!ta*0UoE4|=AmS0iBTv3xK|b^s zBLlX;pKr9+eIPczkhVL6LZNS6nW=>3$5CC`;Xl9d05*)47^V_`qUoNflcc0PBwbuw z(&t!94)0z89AkKsQ$OqsWLoEAuHp#k(fOi zABmh{Jrbn#$(kbNnGcWc=;WlSD5d`X{+xef&k)bX8CFrmDk>_<&|F1@Cm znf$r2v7t%jP<42hI2w>T(x{hnQKbXSwggla6bqEt#?1gvbEh{h;M`Ut&5trv7`$H< z7Qp@shjidq@{Eqg!7PuD&f!k-13^gZC;%MhnuD$C6y}+ftB2VkQVOy3{BPDjJqH;F zj3Q(ry|=5s>5@b*I>FoO6h>%1!nVTx_F@|i2q3HW=s7{|=;#oH73!wJIWwnC5n77z zL#d1jCyR=TIz2u(FlZ^EdY>(TDJd3G0OQIsedGhE`wwAvo4JyP#2MqRQvm3II$31R zLOt~A>Pik=seA6r8rg3!KO!Iddf{Rg3Hxgy=R1&L$2y*>#>?`hfuAwo^j zd;d+yr-qai*-^fc9l+B>hKggZ`s0R}_VlA<3+R1edSh*9xD=c>i5u4^4*yGAU;lRG z;=-Mi4L5jnR5i9x)Qq^F!Q;zIpn?Y^llwAh-KalrQ!crUc~ANCD z2%lD@0hq?Q|1!F5QphtrbS$VV*hGlj zgf|;)XQH40IFmn6zZ`||-f*d2Mgik+$%!_;!?oqgi%SC;vqB#}6{eEdJRz?aN18jj z;S$EkJ|(1}I~fB(-wyo98+$ImMt7pDk|n%R{_A88&@2qIFjHIZtU8rH z%Xj=BNzG;MAyHml{ud#vTR*$#1NY@x)jugnxAoqG#^E9Wy>8}Edt*-kax>~iu7Y6@yu6vY7T*9#xko-?a{QOuTkE&m_4!5lR-H`^;PvINoXN2g0a5?pk{GrL zkndjJo`Ar!01&4y#DWONq^LTyeSg~byc?2ul{z%_wk9R?<{ueOo;Bm66{nKD#AHb6CwhL)G<@~oaeG6Ly9SFr0zG~J zFcGlLcF|@7*v*>Q6UaVC!KFT^^Gf*Rt|8BHnyECitHS zh@DLu*B6Q2`vbuhA;d`H&66cC1D=cQ{QQUKo|InEmm|6-D+N9@QB9(Ja(P=Dgek>@ z&w_ZSn$w5Q?P1IyQ?FI{fNImp4^g2^Mn!Y`lV^zZdAk3KFogGo6mYLO4mP)GgJ|`q zr=`8;@Sa*aK0ZG6@e$2>p}uq(Q4QL>j;UbE>%Ws&2Y9_T5^gm#WWhB>OiF**(c3 z+oncOiuhhOk+YHtNVYHA*^Co6V!QO=Us<-K;ei z%ZwOr@bp76>#L3`|AtAHML55cIf5SnJ=zWVu|* zZ4x?U-C~Z^VuFWox7ZyKt)-jF2>Z6N^MK2vF{zXqXdUCJM2+gT$^SQ~3B)@6>jl^P zxQs_q2_(;*qMVjTy z8DE~|Z|?CI*G3!*I{lu{&rZZQA>!zh3IoNOq>;Av-yn`9*}1Dn;K=c7v@XaDv6u#g zLy{WYd}$#ntB`#W)>wIZciCquT@$aY%t zC{N}zWYnYyK~}{51VdKtSb!5r=c8Y|Rmg26SbUR3x_R=E8Yhd?Xby_4dRV5e45zc| zLT$t^*gUev4s$Mtl%fa6?Xtwc<1)f)ygOa=bIz&$7MqAs$mB7!+4H3&7cu?;LfQH8 zt4~qOV^KMF-nIgPXb8ezEJsns(VjR&81FP`mb!N@_kmL5b~$pWMAofKY+*afdY>%q zxeCi}O){1Ap^o72@&3M&efBkTNbWQ2skce^!X`ped_0@C~DCz zhN;3ge{XYL-~*qklHlObZ&Ro#pZ9DlH9EAb0!u+6yxV z$6eZ|bKBw^G(d2FDv&TX@w}iPcf>=DnD!CvG;EzKE4@=8EPKvPaPY3I0No1_^Ec|K zPNIsczvh7XcknH{MdtIWgo6kRo%iCa^y?TL z&VS3+rwIqvfNa_mV8Vtkb+Y3lDSMbD%r3>jy~Xh&v10T)TcC6^d?%)yL3LaGY_~XB zT6&!*9Um5*4Z@^XsDc7)YnU`|nl+htt31nkWa~Mij`O_!z_c;1w##d3rsR!PoLXH< zRx8q9aEAnuO+=BAY&>nwbT+b$G@OS(rYNywliO(ecM;U!FGs3V#FelGe0n%hR`6Na z!;28Zy3t@nG0YB_f+!PYX$A3{y`!nAD4dH5M`j4zVY#{!k;fPZ>e$Lg`@bE*VexIy zkzIjB%mf0Cue)e+GC@>{U8TL%*|CLTclX@R*3<8&I+*$`2RyKXb`z!S!jSA`;v`XF zNZpn4Qr$HijAd=vH8$xRSCRrNC=y;)0moL+i2#>e4DPOBxGVKG%u!Kp-TdtUN-V30 zWvSAfvf$CrEwud+_=y$QI2&4AOjHS;!_37hF$0@ome`v>H8mk?dGp;^yWVdTnkKsb z#(!Fx_LYZ+6MYhH>jR@9uf) zcQG&#c!&Jz(Qq>}xjIE@rW{nCq>qO*;il!P{InIW*K&1LRo2nzBq;$wSr$mMpshPt zwv5-7`~I;AvDUXkbEjo-FH!SK{G-;a%_u16p%(O=iJ6(X#^dqq%vCyH(!1b$&AZ-6 z$q%9N= zVd(PiW%~9)oz(!P3HH{~VzXBT+SU0HQQDU;G&ozgvSudhhZ*+bz0iCMjEyd8XS4~- z=eYyPl9y)`0M3GMO6#YV0h_@$U1T5JeIrB} zc~{EyYAh%m9b+5W95Ms^GPHFls?W)t4?i*-S$ySO5n3OrBRc^_TTx+fE7ijed}oTo ze7Hl7`$&5-5e0i>$ez0fBh-Ub;+H6hH`S{04BMPImIlC7g8&_mto?+7$Dl%_4#zf9 zOE=i$_El}vQ6V|_Kt2y&&P|oC4JSAUMa#GD-ZA=D$K}30$fr^*o_#cy`I4Mn(TWt- zod@%+gIPyMM=<~O1V?sST3WMkjGDhFwv@QM{f>?x&ITw_fXj{Y=Z%rC*V|z3a{6GD z``ct?eeQ`dYdCI?FgWXn*3Qn(AHVX(c2HZ$O2!={%CS>ek-YRW_|eVZwmWPte!UpN zKAfw1M&7S-&H$|(fpt3Ga+)khqLk-8%jaUklnZ;U!vD>l>J=yn%YptUv@BN&`qbEJ z{qNDQYDO$%a_-9dFyiJy{@E-wQI8JI;74Z{9iyxxBgKk%f;FK$2xwSclP>?Dw&aZk zId6Mph#}?d1d`2Brm9CO269(>KqmxiuNTcL>)mdbR#sM=zg25@EY6v%gwclv;D>{H z;R!UA%6y$1oa;7YY{Al>deM|zG^okALBBXZJO9AWkBH9wb>$x{lu2Ecc8mPHw&Tlf zAW+2H)Cb=i6XYkqXbfJZ`au@dj&>`Zr(>cU>n8Kld7`b-bdObHKNznuP8^-LCOE+9 zmp9pLE_MxCu47nPPQMe{PfTq*)V-%mvn_)ORZhMrW`Dd&%@n=015H?8(E~<`upNLi z6-&FXG z>HIZ0nR3nY3g>E}#`x{q)Zf$7Tkp~9t@Yb*HCvByr1FP0V)tIz82X<|13@VY4Eh!_ z%ZN7Pxh?;>QB>Xu5u*oTgyhAfAiLvit?q6usplVDmIT9B7wE|l&%pJ?2sX0lg|t|` zO%D5~{aBe=8E^D&YoNsBhFujW5(n=3~pose)TY zXvzbqAv+?OtzlH@=n!NVU2$Jd$^MlL4i2_Gn7aL;2nP3EfF0ImA7{tk-<8!wjn&MC z-#adx^=DB@{6o~cs z7bl+4M;ihKi{jdG1;t3C_YVKi8d@XSJS|*okC^`c@K{~(DAXW4q;?>pa6>yiJ$-~^ zHsHDI__kOrP~C`nb7Ff_pvnam9yax|n{dO`2Y_0D;{kaDUavwP-Zgap6wG7y!E9vr ziNc2WOZTxe#8%cuiZUAU*HKTn&tcVVEqL<|Ly5{P9)sdYadGi?a`zIW5AIyV59dsn zQU*4g@4gHVzZuYKW{Gw0#4x`(dAPmA`+ZMx(;!#v9X)alW^|7_O>g75DlEjX8<3|N zFX4%KpE5=pRA{#dL-PLK8-RCe%E(FuA8+ys#A*|VttOojYwQhfNlMn%)@xpcwO=&e)8c$TP8xm4 z@bul`MzO?J443nFTtH>cgftQ@#Kqe+TrV|M>LjLZRLz?ov$L zw?54b>#?;^Vgm~YH3iQ+yg%lyu4kn4LLFJ4`@}ZsH3icqqUsdKa5Aw36?EmFh59fJ z2wKU}5hofAuM6ek#1YOy#w;*7I59i36S#f*&BfSvMFJ|N`uof?7M zR&aIA#=E&I1KQSM8?h&Pu{??*6-X_zz%^~aP7&}@!z;MjU3xL$Yw@ezGl#UDZHL+R z<4p#FGK_;@cpr!#Fh%PIxIF3`8@&vR7ePiaCBs?_2I@Te#1-QE=N1fGg{x)zJe0W| zyUSG-jQUzPI=s+axBmCN?>KaDG!x}e&Jl$yk~hr1p?42| zjR4LWP|iv_=~!G^@`w2=q;b57FXt_W>m2?H9gX;Kuo|WF=Ndhm8us$zqswW`86DTKNg2&zZOh@y>9g{Un}w zKNX$kO*~_-4h(Y7kv-u|VjXFVeD|Ctb5i_%Z{{LH0OVpfvsTB=VaUj;$NA6qOpKxl z)}W+9Zl#dmpP#`ZXoOu|FoHz$&9RLNbsrt4l z$TyHKQ=Q`jMR`vo`9D*~pR9IF;|BbbLM4c!vvy#z(oT=jC!R#b45*GMGIIrZPYSp@ z-+%r=3~gi>r6qU=QF@+;C;3i z!0RCENh2V%H+X{m$~ec^qGn!$WqAuGDmE8+JriUDNL8l@c`kcp|MtB9lL2nscx<6I z_oWKJ|IgiL_&qU}*~cQgbdWqH^7i(wA{*%gr59yBReyZC;*>=>7*}!LV1=oAXCMyn z1SRP1{=zO0qPz!z0ut;G>m3)vj1QlCjRT|1iCv-xz>*!G|I!AY&U9itUN9Q!dc}zUgTr_Qw%eOGBPYrN|!7&D?LG_tT_OH545S1ypy$*{z{9~dW%F- z8!V0oYPP0#o@1jo&8}5$qwQ3@x@PoA?PQxn?X$D*7S0Ya^mJzYkov!}qx`lT4PXg5 z{SJRR190>z9(lhC$un*~l>$tD^Es*9JAv#35pkP1I{$9=(7=vX6Mk7=2f&sY8~o*K%_d|# zPUQJZ?I}Hy7N)b@!({@$_v{g$$YbIXMHYO#c&{?Z=h0&EUf!Jd?b@3k1u!2m62@V` z{8LSA*u0jDBMhWn*>8!t90Mpv>uih(Vr26bZOuSavIqrqNqG5M@FD2AX?@+I0K7YJ zO0&y~x*>WaswLGo5I1X0&GSldoNI!lgvD;<{OoR(;+_F&9mt@ohB{zfegR$dcA-mQ zS5|^nIS=!`#kHwPX6bYD@F7woTy)ll7~e`iD9uJrzEV;!%|GBxl$ zwcj%shT6IE2ZZj}vl~hXbF31X!p}d6Xnb!_S!36|YXxfx9`wydE1ni2-eAV`PIYNw z`LFNU9R|jbqjonQf2F?$kAtS)UEQsAs6O{LN*&wm+aYk(3aRyBD$6c)p**s%7N^q<>HcVjidU~ z*4Wi7EzB=;)0Nd%LZSIe=%#fIYY8eldulmNZ}E=WxaRUlK=p=}G+`CAOLbZk_p6Nt zu+y))#bp(>EWibTOB)1FeK1)nVWO$&7V+0?Jo*AO=Fd>y2%z7fV_@V_Vn#(#G!9sf z9$i&wxB*`j>3?%jvV|_UadPt%(4K-x64w*&xc}q4yO|etE5%$`lNzR^sgNH*?w&@DF?JCSVUCyJJZT};0|L&hl5JZS) z7s- z`jvHNT;P0$lpmF4t8gZTK`ovzJogKD6}SLJFg`2_r4MCKPfw`>e#F1tzlbou1~aeI zDIM>NN6Gon=~(h}4Dpw{CE*w6o_feQnGFRu{+^|u{FDF_69(w1JQc~xn9QvIBogB9 zQJAD{fHHF4H_2~^#z@LW+1l(m7)%^OXZ${6P3u#aa?HTkZ}7@$1*rsGoDCYXo5k^_ zd=9|Xp;9yxBr2Xj%HSac5*(7U+-_(|!D|Xqw~r=2x{B;JfdD*7I7g}rE7N2+$(Q~D z4JJN1%A_XSQZ>VkZ7ZG@W}Lttr<9U4R!(d<;yWH!%l|7oS{7(DO^pmfI;a&JUI zo5h&4;|lmDT4 zurNIRpAE-f&3&`|H$>)9&+K<($9&J|Rffvm~0 znH@-i6#43bTO}1P{e%@rNd@rRT-#=V*66)_Mf%$LFg&qDSz2?|sYS@` z^fUw*=#7!Zr9+2_=DBPKvwPaovF*-B&qvNHqvoMDKpPA5o~rmYB{pijq{mDzke9JK zCO)(AlE=qMv>mQX+KYX2bf z)JjlSmvVm9!}l}z7L1e;Ld-$M2cOu3odZ(X+%dX0o^mgJfSLD9ufi$DD3s&-C_F^e zDGxuqv?dM3WD?I$ZP;A@Bz>(;Jc957ui$4|KYnzv{9C4;`+2MJ#RWg~E;!$PnE5Sk z%+D}8HAj($pf2#{8Z)Bw28#?rs96V-Xwc<$FWs>R%0OctX!D2~eYgRQN;-d} zBBVAz!WE;a?U%eUf3>?A33NQKeQ`Mwy@Xyy&;yak~UlH3^t;w zt17Ef%==MFLc(-P%d>T_(kq3HzmDUrxVa6u14N@)f}5lS_7pf&y|PiEzUuMe6ppz% zuTTmbotjnz99UVvx;$5rUIh5I*<0{0pwq*{IKJ3t)J_T{+6;ZP~%+#c&y)F<(QuUIHD`z9}4sB@Ca>q}-q=$MfdOsJ&E{oU*<9<35EuDS;kM5w`1 z--934|7ihwl^j%iPJ3eq!yu~%B2ZY%XW4raB6frNy;M;WA4(+Gx;h86dPJ~YQ`$ts zRsS9IP4HbN1JXfFF|?>SG*T9cu?quP-?a7j`AuBFxllAbi7 z@8))%09-3A$;Ir@J!@?XLq3@KjAipjJl(!@ZNvMX2xK|6>-C!)DqxNlKIYL&K$K4QC#QY}ofiR7DsZ7fSTnjI815Jh^zt&OwIEtKlu zi3UeJa7DldHH`Xv3z_6gXPq$}1?$%F7pM(9LWg)d$Qz}9s@d}CZ_^cQ$VzQ2nAbTP z-|hoXThS7@YPoK^@y3_?B+3k_L;zER=1)t|h=g!~#i%=InmL#G-zzUWRa-9(cUNF@ zjLUaeCe$DR`5tOlej<+6Shlw2o+Xp(%QY(-ti53jK- zRgaKdc);$S`z;;c`+h)}DxuXp0kENH}x7orTJFC@@y1eLBg`huH8AZC_2xZ<0VgUf& z*O&hbKpjmzp(EcTVa7NaghO<$v+%=TH*k)O`tHlyZC@eBJ{l>t$=c)LO0NnDjy(h6 zTott@)anH9u_^9$ZL7z>NnBBXX0D`U8BHC)fphI-(;tuz}mc+w$^F#Zce$d}V zSF3pr@^$YliZSum-*(J$gUvv%0P=sZQX^dPbv<<}V%j?|vBD=cv=4CBXsYZ>E=XGE ziyC?%w6yqL9bjF0E-!Sa*fD78zBt3dDS(ldNz*eT5O>C`;;mb+jc?s~VOGF-&JIus zX)LCgpc!h$js|kO$5(fhAo{2s)y^-fO#8a^{^4hO#|PL^HOeyV%FUzlp1RaU2k*LF zCsR<=y21Z1Fhn&l)B;Y#0+3XK_=Gr{J&MYxTF!=&P==WS#N!NW&EId!wg^j*gno4= zfmUEItJ>9?OAA)~#slD6gZmI_K`x{EoR>hAIyDvwh#=q^VE_*wpJrnd37nr3jVkBR4o5L&N#Pao;g9q4_=B2X&ChEc z1;fn5^Gz<@WGO`r%ADF@E45;@fPFAjeO?cGTAhp#T0xkn{U@gN?RNL@@EfZ;^$m z7e%2gNW)nW^-UEX$h1Q193kuG`9D}+Yn0HJv!g6R+Db`(_L5F@#a2K5b+OcR|9>r< zc_38%_s2((A~JYFmKbaHCHtTl9(&oBF_L9UV~DYhJ)yBjlrfglgGaWEb&w^AZ1XS} zkzK~Vrfl)O`u*--_pf`;J@<1ypYu7N^LqESIcbXiYx^_R=Z@uI`!WHvDe!xH@J?`h zu>os-L2D{jmu~G$T>x`{g%oIuFCu}xN=q2`y_MC~M9}enbWH>68yn8zmC}D)ejwGu z+jJG=uMs8mEWrs5)7Qd#>G@i0>w=bB-{Xm`l3zw|d){MmUaBG=Y!><^`}8L$TVW0y zh|;K%^PQ%WQc{`%*f!w2gcme6dGq&eAVe$A1`A+(kZW?)-|-pq?e_QKcIEGV$S)NaAx0ewK65WHzq@RS2Z~0TPHKDRP zIzaZ84{{Fbj;k+neUD)^qnNuRn;5P4ly*H7B>{;9oS>Xxquj>HYcIstDmQKaXG>Kn z>WIj0+Ye^3C+KS2@>%Uzn>V1+yJCv}mP58xyg2li%Z+8Goo_lN=@K8HYlN9LpxP;g zDgUjktb9Zl%o#;4;+F$Z_3MD;XI}X?rt)1RgtA>lvE^vbWBzrt;BQwqZY^@}L0EB|pZ>mNIPm#J;DY3`{6pAW)kO&zHF~2cQK}ag) zp%CJBi%9L85%_;&yU$ZE`t8sTl_-OQ+uBj@ttxKAt^kb0i{_~fpl9<QGhYA{8ziK| zT%!jEwTh28K+4K8HV+h~ROy<9qfVoiYX;P-ikt6t5z~oAtMkjn5W6=}%6q+z!?;)$ z_+^59y*K}6RhIzViO#vom4Te66*^pyL224mcN?5Y#J0lLw-iXJ_x9i%L&t2U-p# zK`z-vbGrxHr$I~xWR+8Qy` z(4JJevu8#MINaxfBZO4@tK?3^UfdhqeCeTJDgKYP%JC9}c{FR@J5^eJr2!EaP$q~Tg3`? z`6M>X^ex^^jE`$SAGG_EshJZW&+6`-PH5JTX{0EooVNNPgUF(F9QPh(Hy9CY^$pEP zf5pEnDAHX&pMtoBzKea7W_TNCY>(q&gXuzF`=zM9tHiGKos@t<$>GwRqq zDTHB@Yqj1vI5 ziad#aKb9;;CMWsh?sK2Jn52+~TarldPZzm%%ZzA)#^cU`EnqeFRq~&mB^?mPOCyFS4mrQe(qsf+`Uti4tE;wexy=0O@rzPX(6K>BZ{Kp0u|c^dn}rgQ0m+ zj@|k(1_lNnC!2y8tE;QQV200G&+&Rl)_4iQg6BA06nZIVo;fxf=aNLX8}=CO>0Z4! zW8xHsHph(y=vVTZWfx1ibQ&Qv*zaJa&vRP@AJyR7{C+@GlUAPVTvFJG^w<-mrw1nApDLHA~xgt%KAE* zVQVsAEKCsc>s&)UAZEhS7qs)65v;|lKlr7+{k9d^;EDj0J1IFi{94;Ob3U1F$*ET} z1{d*{{@^c0Mn)MZfThpJHVd%wYkaDo3PJf&D-f~E%ge4LrBt zVBpZVZ{G@Tk{Mf1O}@4F5i~Rqsjn+)_gk}?gWo7- z@UqJ{$I!*uXV=ZCev!ZwAKALua-^Lm@&y#dSg|#y&N>4IwN_Y5+Wfx_oinuj$P-{c zrQO@7886|rGXC`EE;k~H`oeA%08C0#-axo`CF^XzCB!yI&6W0tT@P5`pNG}VNnl_3 z=c406jbRB8BK$_c1VFK+)J~lMUiK=q#Im(3LiEck$606Q&1219<7)sj-&uBa_wj-(4yEN8x$2>wl&B+~3vjvjTPD zmgqpCanGJb&I-?+g}cM0MBguigBFtj&y`2RKEwF~-6Pp7mEYImOTTV}EPCAFRe;k9 zM^D%Hed2N&b`nIm`8H9c-BoHFHLp}$4ux%2QnU(D)uAB1FX+UfhYK+18<+frTH-2r znyd-i$qnKw-_arSf;gSPGKntu86T16>tg?^4%OFqZ zGWYa~_WpYd4vxJaKf)6juoe{#TWVNa9 zMV?3@A0$k~!Z^2nH1A5sR#@%*8MuQ(l_i-;51&+x^}> zNElJA&mSKn0PqDRnx6>E8IZGk|4fBKO} z%I=HLanVrnTL$cvEOmOendmQx&Cf%HT8CnsU@n-I?yDDconU=XwqF!XJixHB+gjmQeICsCY3C8h7m5EWXc{JF_ z=)E63lFZM^=~Hp52A?G{!BA9h5#IB`ZNH&da)P@565F(I7e8ND)p%oolqRiaG`py% z$e&Z6FHQ)KvU%xImNC?4>Y4qhTp5nyi9#aZ{q854N)?W&cY$hf!|wNF?2ffogDUM& zsDjm+QQNbGEK5CTARf2Cj4lJ-Kk6vOJhzsEQ88k-li)0?9lhoT9B|8+q{D`8);gl< zgEpO;e5SQcU=bSd|Ff?Y!xhOin)>$d)OQsXvge}IQbyL+q|e`i!+BrzdgNtg-D0Ev z)E5$ODl5zD7Co-0v?@Y6emvRdRBGrHn41{xljIN~V~#SS{2&VXp~~sozZcilk0#*k zLEXE@I-{zerDg3(N1B~vdq0K*dV8CLUN<#O1O^1CgMwE|igQv`LjU}guSv(uJMlg1 UDTUz|0cB5+k-j;sLf0kwe>b0C>;M1& diff --git a/docs/logo/gunicorn.svg b/docs/logo/gunicorn.svg deleted file mode 100644 index 073f2029..00000000 --- a/docs/logo/gunicorn.svg +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - g - - - - - diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 705fcdcd..00000000 --- a/docs/make.bat +++ /dev/null @@ -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 ^` where ^ 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 diff --git a/docs/site/.nojekyll b/docs/site/.nojekyll deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/site/CNAME b/docs/site/CNAME deleted file mode 100644 index b9f0ffbc..00000000 --- a/docs/site/CNAME +++ /dev/null @@ -1 +0,0 @@ -gunicorn.org diff --git a/docs/site/community.html b/docs/site/community.html deleted file mode 100644 index f6fae4d4..00000000 --- a/docs/site/community.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - Community - - -

- Redirecting to here -

- - diff --git a/docs/site/configuration.html b/docs/site/configuration.html deleted file mode 100644 index 88bcf302..00000000 --- a/docs/site/configuration.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - Configuration - - -

- Redirecting to here -

- - diff --git a/docs/site/configure.html b/docs/site/configure.html deleted file mode 100644 index 3028eb9c..00000000 --- a/docs/site/configure.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - Configure - - -

- Redirecting to here -

- - diff --git a/docs/site/css/style.css b/docs/site/css/style.css deleted file mode 100644 index aec17c99..00000000 --- a/docs/site/css/style.css +++ /dev/null @@ -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; -} diff --git a/docs/site/deploy.html b/docs/site/deploy.html deleted file mode 100644 index 97568d2e..00000000 --- a/docs/site/deploy.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - Deployment - - -

- Redirecting to here -

- - diff --git a/docs/site/deployment.html b/docs/site/deployment.html deleted file mode 100644 index 2ccee4bb..00000000 --- a/docs/site/deployment.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - Deployment - - -

- Redirecting to here -

- - \ No newline at end of file diff --git a/docs/site/design.html b/docs/site/design.html deleted file mode 100644 index 38f04705..00000000 --- a/docs/site/design.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - Design - - -

- Redirecting to here -

- - diff --git a/docs/site/faq.html b/docs/site/faq.html deleted file mode 100644 index 5dbdc0b1..00000000 --- a/docs/site/faq.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - FAQ - - -

- Redirecting to here -

- - diff --git a/docs/site/images/about.jpg b/docs/site/images/about.jpg deleted file mode 100644 index 4aab4d50f53ffc2f77e8ee20667b3e4d648bcf06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17551 zcmeIZXH-*dw=Nt(ML?uUZz8=*@1Q6k9Rh?73euYa>FrUPLMTE4(xrsZLJutz1p*S9 z^b(2?iuB&w=d;gw_u1cmpFd}uaejT@${1^8t-0@(%l5DpBgk&kTqjioFJNr~qx>f6lGir4je~KJ?u1L(;+?r-XMkEghGU zU0%WP%{1UX;h)>5B%}l=1GX1le|t)C`xfATXLswsqEU~{v|eNysri*-B?vUYKNe1Y z5#y~%z#KLvE6yvG)a%SO){@AP87&TulIr89^X#6MdZ67w(%U`2YUj&B2eoul1Qru|C-Gz}MFGNi2AbI*BE zX%F0Iv(R0-vs1WB=xiD5MpnhSaoF{}*B7lvS9%l*ILvaboY%Cv{_+igXmrnP=4nva zxUbh2tWPxC5yeo#wNZABYO^oJl8bYEH>oXSNkv4YhB6Q_#|{{3Dg9Addj>*Q0y?xFcNrvE*dSXV&v(+ay=z z%gi`(T2KW*hL(o*NIQ7!`$8-(4Kwrai4SNG-W@e`Ul2xqxI4ICXv34htz{!DuRg+@ zbUT0)e2aC!uqHq=&>7&4QMO$$T&D!)nux`!?N+E1*WJ9Rl zY-+nIDbz-BKIz&GDSNFmI=$pR*1iHTHZ@uah(4A(iBWJLaA&B%`&@`c^&woNj064`1eJ(abnZUBv9%%#0& ztjE$&$zCY}%j;wdqQr;KESXH`W|UxAUs-n!+=Bsq4G`pp&gl&R%&78l$w0kbjCvvs z6g4wCYTcV1ySdanN9R+2d|#R9Sn&ohT5TT2?Rd?D?OclN^#`a?qd{2)3un&(d{3HN zt($ikGq}v%pNyV;IeS`P@ns}3|8Dba1>bmzSdJ&#!&D)sOS@s`ci8oV*3LMQh0EsP zFdKrv@ngt?*|;bR>mEWbO)oH3CE&$aKkFd>i2zNmE&O9mmoDjJ1_dsHTFW;P%Ra58?Wg}7Z{*arlVG`W)@?s&7fI34JDYrLJ7OC1oyHppn=3W15-0(p z7kx<%7t(&tj=b%{K>wF9X8dfAJwuC4`gRUO9gIGoM`d(&=LG8lyx1aHq7(Cpn75b7 z2q?aN!wNkDedbFy=JB0xuPim`D(P!#kM56#mYnrmu?c01qh2((^{?(;!>y*IAlLKB z+%~p7lRa~pAz=2UKDh;FO)wJJ%=oC-Ts(7?@hD0(h+9R$GJ+HCD2w$>_Y^rA`5qE6 zOMdI+i~o4C^WXDmNFC`ZF2%{ZRN3AYI-oiJRCi#`R>q#-fmPPx4uiBm8go6cnU|r* zS342o|EhXgnmxy%Z=zmzjLZg_^UV(ZYs|+(chA|k-R+R@kx_njjjZxW_19Nj{o%Tm z*NSa$73p{DjlFzDpo2A%d64TH#GyTY#1Z>);w+42=PFdSYxqQtDMexR9$6d~FWAdc z`N~5fG&cfE)T{&QkWQ$jf;t>-w^Pzosm^z*v&4M+VOUfm@^GXx?;LZcymSM|1{RJh zfBsSu@sG$rkh?PzY5jfE)Avdmh4kbOR%dWM4igNWtv8PNo;2$ofBX7^2s!ZLffU9M zdM}Lr?lJ$?hi}I;E{Oe#2NeGKM8gFW<_QB&cDoZG7IS<V$xiv**{5qCHDHD_(SB zjarjrEDVXhOyX%&4L3R7{%|*fdfPY04 z!6f+Pk#*1ex?e$Co^r;#t*d5m-1$lT)7@L1S()4fitQ)c#)C(r9 zaN{<$Z;SC@qX{vrzCZNrC|963F$M?e%<)bSf;c;;eJ<<4lST~~-@0$`6wDz8( zgOKavPvOc8;+n#{8GaFI2%;T^8jY+JRY}hDSxM*>hGW~{A0{Kp1Oa=IaLWfRkpj`L zX7`PK6bxQ7=&W^cES}hJl<_f^bS*RO`Ro%t+L8LPBti?=MfAkiF+1Qv!$%S zyBbE|bTpW<(sri)3Xw8t7u~K^SBd~d)gWUyBRb6+R*x)t72Z!bZmyJf*2e}CGPp+> zhg=&{%VEZoppAB$hL(vZ@NsLiCnv8J1x z8F{Ko=vr@2-k=c(@lN}iYKsHJY*T-5;&H?xTg2CJVxwMvk$6I1QuyLf^h;Ta!w3)q ztV*oI^R+4({3tlO`#|M0o^6pZTpp`;d;<_!o`Pb9^(b}P-YUJk-N{pA%SSS2)qM;5 z!t<_Q&H`;f=>38Hi%`MA`BQzOrLP2pk4KNSrlYz)PKgd)4eNi1t3oF8N~`r|uT<%2%4 zdR1NzPHg;udEM!p8FOCnWg(bTj=wv`ZnWDZYY%=Dfi~({aw5@lfZJXzEje;di~B)Y zU>zNZUO8O}->$3Q6?cbcDfX}-J0j#CPATSPf1yZ%XtN@^7kK{aB!PiiYJe4wjkyJf zo#Gbg#p6dyx_=Z@YMj-lCd{$MFzI6bx7i|xn3P@+k|ASG^Az8){K6@+)!>ly3 z@*#Vg|LQ)k$YU_~RG#R5W5NeFAIK*FsSlEDDS&3_CG}#P-2-uttLwo95zGys$9DZ^ zu~vW`!+MTQWl4I-J(&Ju3R>L9IyP&O*!==QcEvEiJ}|23$nI)(Q};+~y}@otOBUT? zE`JX}L6-j5iRkzj<~^syI`wqyxg?h=zBEp?pZNk>^FjTfWkcC-jqcN%m}mc9k3LM! z_!aoB(S(FA9W$&wz=$ z;1+-F*Bd~GR>pzrmg>vXV5W;Heb{^bNB2mNNf*TtvyJnKZ9PSW*$wg7VmW|(m71l zOeVRVDVDl+>pjq6;{g6BT7dY!AQIO6ZadbRW>{aH<1yrkZr5ANtyfseoYg3|?nivA zOW8VHw!R%qr!91FzUPQTd(vC6((6i0@6md^F5jT)Uh@7))G#1VL#*8&!xZZEWLYW! zg;*ihq=wjYJNSmbm{M*M>qA*cf0)HJe`b>Iu_5#hn2jw4eAxFns)q!!h(U|2+J;K=2as~5{jMhxg*7_DuNyUWol+I!scXLzV<|o%L}b#?vMg}Ai|=MuJCefoyghEoYmm@4 zdus`g>q=E#{gv4;$Z_A{eb3n~Y|T>Tl(5L);xA95J`Ovn_8<=s^9?}i=moyqn>eF# ztCEL1E()^k)M{>=Ju~#qo~=40j9EFM8Fpmjx#X5+kNpG8|DDo2jLssV>)dC3+>kBS zK_*M3yCHTGRZuJ5LIV4c?Vx&Y5-)P%6-!OdC)0}$)P&KDn z)fE=?A54g0kLYF5%XGGvjFV=u5%3t;O6;+9+El^d%ZYgSAz@6yOf?8bV4CgF{^2BN zK2ZiHZ*zMhyBbd7nsyv-U}&JD;J*V2@K4%5$;SDI)z9gk=>P(@@=3D?-Z&=0%e&rm zE)s)kNLOf@?H$gnsbFc}(SeI|4HEgwGFTfQuQhL7F=%z}W;d&n`)QK5dv%w#%63A{ zE8@Cd)5*6@bELM7c8X#AmO;H75uC0V2!GY5XrS@(`mx^^E6kE7+YiW=&Pb-bu7(O_ z@``7w|5h8CEoEs+kD=GzV!+$iL@0Op(5;Fr^#|4EUu0jnTq^5hi7#qcEAezWO;0YQ zeIb!jwzXMVW|}KN1ix2sf179F)Y|zj_p(_JKmhpauSeYR@|{=e31=>^7|1?n`X7+K zeCxNRjP$tW{QP^`+>6g^Mz4=A>Q~v$E>IZW6P5 zy}9bOX<(do8(eiewJrIm5vatvn$R}5#T(N_^LIHXSg(6guFO#Rb8O4iNGM0(ZGwp+ zNuMQLe1HtkKxL2`DFtE4w)21KDZIb$cwudBr0Md2_&^aJzkdTzF%yav?K|Ijv?){e zs#ZI5txwwAZ{zO7H^q;C*ihC;5R08`gV^w?<d(6roK8DBda;7FUDW`?dY8U+Xe7t?@7PVIka0vd_Jl|N5 z)FE@*m@wq^nUtGL07WlDJ+Pdir!;_?-gGvtOnQ@?ayUq_})h;#vYy%>*ml?7;=q~1L0n)t}ICun+K zkqQkORpnD-nWq6UCp!lzzPkK%5<4)3bBwD_Ggi0(D1VA5d7}dOt5;%cL^5xg_{+DJ zm)2ask%M}3sr*|Ei~Ha%-MQO4_s}{ymuPtftEqLvVt&1JnE}zJo(J$8yhrY42Vr%u zUz_>3I)lmb0ta_o5QBN8UyUX-x0I@6j&=?JNtA=e|_ZXQCRbc?t+mOrVSx*698b0acSZ z$y}zdL96m`C#_FwEgnCe45NLuq5cZX3b|@vA*8m5dqNcc^3ji_@1pk7kkK{jsdbd6 zOsFc8m zNpjH7Xj@cbQp;bA_n*<<4Tt0jat<;;!lAh`8d-2UU*FB&CsT*73UKo*jGe^Yx=T{u zkrU|j#YdcmJ$>HYzfQTBNMb@687sFEw};r9OS1Nc&?7@ zAujdTn=T)x87s4qvw8E&*I?$v93gqz!?E>_j-E9&HCIzp*8_u>0#x3o|A`s|UEt8t zq;`{ThYhlYmhH-_Pk3yE^Pd>r1F7>*&E5dmZ(T13zNC0dA zEb(6;gd}C9r=f4D{Jv6uK}Z< z?#l5S&4gLFO?kR8yGNZFdUwho;kK4NGt?4mo!w4>tn~wp2rYWp3tT8hBuhEy{Kg8qvb|AGDg(&W2u=REp0 zDDK`+-#8R*nZv>Kxx~yEyRf5P6U`pesytilcKfehBF{%jDiLlG3)_4ea^RvWkr-D; zx|N)qwa+@`k>I)0xyxTSfbj+`bPEaouXV2nnG~S;-zH2d1P}Tv2C?NoDbXL$)}@487C|}tVHNMK-S+P4p7waF^e+Su zv5ICM&_3?apIjTiy(r>g2CaRvO^b7>X8MoEcCRx8t zVH}JSKcjXW^z7Z?a4RR5{vhGHvU{d2yUHd*#FtQ?Ah>V?2v&Df$;`hlbo9I|(G`my zj*UGjY!kEV1%_|HRgN{k72}I7+T2Dyc7R~s=9NH=3pD}&yBL*MSgjpB8hw=p1-dVA z<9?@XQt7a=&NzY?gg(&EvQbJ4T5vVJxfAaEP-p1~6VFrgM2jRQ`@Sb}+#;sk(yQ$AqmtBZ z{e8Fyo(m~2o5wBMa7tP(3NmijbfeT`uvgf;k!7Xz`MdKT{GdH&_7sdZ( zp$Ql=qom!tMz>!M*79xA_xjq?*9P11E~(nppO$H4gEL!V&A>=w>5;UO&o*z8FAsJ& za!OkJA+Ij2+RW=Fw!ETP$5s+o56bqWzPe^V+k4f!^y7M-UE)zkvb+ML=%{=l+}8;Db@Y;>Y_rzWgN_9te#Md}97JqS@A zn%_oj7LM~+=U?Ap3`_FdV}~u!9B&6UlnV}lP3&QA%wmm6f!uBb7>5;1vd~|?dky2_ z>gYWrR%cagIMTCsix$E`uV$~79z4@LjBAlv*>Cn1T)2GlJnaTh#m-;wPr&&9pZl*k z_5aCVgPiE~)X^0XQf)zNp3R*R;6E@FM6n+m@X}b|8Ny-VGE5{vpIf|sHfj@|iNBN9 zqZ)JrNLs&c=ac>!eXQ$L^PI}<$Wn<1IJzLBwNEF!DIr0o|3WYXid1QR`nhMmd!8J! z&ZP@E|W#1aB z06lb8KP@o=NBEuVJVXRvsWu3hK(FCrN_D{~*_X6FbF7Oq0|zR7kvs=NEEQrLzuaoC zhdyQSGmZqPz51k1rPGX=XL6$LFW!(S(Q#XwvM_Fn?H(%o`nxT`IYDsSzjQ~VnH6!dE}>YRU%p6v{Y7Df}c=UGhCC-@NO<) zP_0{#u8jqPptm+l{)_h_X>eHR5je8j4e=8W;zh-(tavIOfbQ!#&5lRo>7 zs97Q&{cAS(w-&{7TsL>CM58us(P=M3rYgr9sgQ7K5Be+VryU;}-KP7tWWAc7io{vI zsM<|;=LJZ)n|;BX;HT=4R?qZc7%$ZUxJHi}j9%5juvogypP_^<+9<&&gu7u5wOJM$Lew7k_6)k6{K<2he`ECvPuWVM1LmIN+u06%0- zs-nA1oj)(JJ{gKz&_%iM>{dbgmhu_%B(}#N@Ce0lX=xd|UMCje27J$%?fk6#9E)eV zC2TK4fKfB2L0w4gX9|m1rji`0;IKk-sp{g_?X_!Gqw%j5flbM^;j>y}yngmx6On<{ zareu*U>K308yd*F_SmeB>;j ziZ%ZV&Ka@3f0a_&Hd=8c*V3BnXT4o`>QlH(@90}>IGx3Nr3sEO`5_%d^7A2iWdxvG>^n!kf!5x73OobA?daJy0Dj*JVXp4%}uo} z%_AFXD_!f01BWPf{>|Cz#q(>t$tEvbFb)~ZM#pib@68r5P3;<;7fcCnzETx7GI z?s3do`saAQ8CCxU!_qCCrjd4O8LiKH$U( zipDiGfk$a5>QDv8fiIckq*eoFxF;49Y+Ig`>k4h<3WQNj&f;yu()WX!NlP{XVbhhQ zugku3=(hX>RXyi4*k)2xi5w#_dFa7si38bi_-K@C1a#$X=oVNHLz2MG#hiGKyfV)+ zl!d0rxqH6=+I(*n0fIntxrQoaup**avRpD6GP2_Sf`HFtFM5{YBcw5dS!h5bi zhdiDE3t_B8v`XdV?lA1vvpVS+Wpbt?%_JGrrp01>kGBNzb!A!V_w*+ScB2sglY9`2 zA0oz5_J)sVTxEVs4RxVq2@R8EdO1B$geN}T0EV+-=D-}bQZBcku~CDdaC##8@4j^4 zu%d9H zm@W*VX~Sc#)LW{h+}IQm5>wTlBj`MCh^Ss~`>Qd?VhS~@%z<>{oR+CbbbWbgRg1e6 z#tRbSNN2ojJ29VmS1Y4#Iq4J6*>L;x>ZT?9;z!Bx=!^>OxFfgSOOD4=4OZ$(7n`|M zN`kuJvOGj|O-bP0_RSD+!|L(c3wJ}^veIcQLu0;v_eDG}R>a>3A<1iu5I*E#P_sa8 z*<$H({|!1RZWFz)-8Ax13=*kY%DK?i5i`$Z)M1zune-_k0bZI;xNA$^T0XsqBj<5C z@ey3fWzac{89cOcos2Q_m)*J2lS}MfXPgWS=zL?%w8Id*WiAML4Nf`)iV%Bq*~ww(oOA0;Ts zYgPpn@w*DsyosY+OO0K2Rm&lnG+Hk9(Um+h`@Ta8x>gzFTb56y12tQ-y((63(Oq;J z5*tBCMf@j&U{b!4IETc;+ENkyt3tMIjNZbUaQD!qL8%0`{X@8Q9lU<=2EeOXTis1# zXDtV?WskS&x za{1^XHo8HzvGGVhZ7R>2to8+25T)+aJDr?$wzc#a$N5r&IJA zJXHLt`vEYuFp_^^d+V+xs(5~EbZ7hM4}We(SI8k96+U||t??W>8yX@HT0O8C{`o2*U9^YBauny#MRop8OvIhBg$LmQgGEY@r)2%&`4+|A zJqhqE(4RmAs|>jDR4g1xcM~tKQ~&&QcaNs$t{*GVj9(Y*d z`!;U{WyH@~BQDm(1n~y4mLiQk!kny={0^d|7b$s#rNGRqc=zgU}87-qdD?L$yWN&S}up}G1n0V*ZOMOa14y!0J)(UiB@24$zIAAGXu%)Q&<_^yW#>EQZQXE~p7*)0UkoOe8k z>o#6!c$UgW<%({pDPj3CrQ*l*_6hR$B#XDGr)0)m;Vzy9#~J+xL`)7{nzfALqCYIW zOJpuqZNo&N8B=}}U8T#$(yfcgX5sHysnL_Z;K zQ+$YTiYI$Kt_qmq$CH87_9aV5e)aX6B%d~6BqV}Ztj`Kz-qz&x-a=A+s1UwEN3y>X zNy;x;%4=zO<^nS^e0wIS+U>rYiTCdoxqp~)9VH3#^GA{5T&<+$Xx4$v1y{C6|L+!x=RB4tRUu!f6_KncYD{oza+x)jPuW3|M~CZZRFWpub}|`De|Sp&$638f4yn zq)qiS_X&a>s>+;h_o#=+`CDR!M6L{4Q_R8F*VjM?Q>=>O9MMsb7+))_*HMC`i$S>< z+I7WZfsnju=$mY#yzwjO^fa;j`6|UDBcTuIa`Z=lmXG znRbWfL1of2%^XN!_64MXvAf(DGM}l;-|A;_eG_h_*aRVqQQlmBP`o^E|2skD->dao zC1Im>0U?eb(XTN^#kky~@`Znk;5pz8mMC3}Pot*xJ;ge{@Bmed) z!4xHdxbm!e@(r;yIp|hdF{<8orHsaYr=Q1gP*Ki4n{L?spz>FU%Ul1fetwX_JcCK9 z1akcbaJFi;;L{~#<_bL;h^CLYb!%jm`rVaxu1Ah6HDC8-x1rDAzC(AR%h55vcZHDj z%c`uNXo8EUr4h%STBf_RLAPrhz@C%keBI*%^<6pny%C2&JyYwN>!>4F7n17kl4&eb zRlVK-m|}l#P}Z|uiO670K~aftVN0z%tE~MTZ`4?gG7()q5}>m#sXs!|@L{m&IpUeE z5W43yWP*2B@kt6B(=&ur^qh(oN@oMxS*PS#$?nXV&V&RPA?YuQ` zswtz%W8COjkj*02!Z!=!hq2)ntQ+~O%XE^@)`wsEzHH3+_s@W0ZF0*FS#4_OxW)Al z&lip3`L8>D>yzt8i`MoU>qb`c4U8J{b;jf5oqEbNYlmY^otLFd7Off4i!Ysn?d*yM zMojC6U;8=2jSNZ|Cwvd#U=pds%oHB50k6z{kH#O(j-Au($+|0(sGbH#$sDBD1Dv`IFc!yKJmP z@^Zj&!ERFMV5}q&JYaV$J6DlMYlzRn#h{oJ-LIDXZt=pY?zdV@aD}`su+zwTXy9~| zWPBy-9@+JEau5ui$X{OQI=(J2i;;kduyy1qI_q^DvU@~92 zyS^3f22|peb>7z}2ll?I^qAZ43S1qQPg*#`ue#J#rOb<3jDmZ2=gIN)pGrc+v0CA_ zc^5Tff_92Ev&)UCDYK{DKJlL%$wM7eB4s5W-6NX_&9qD%No6~{8Z2BL&_A}T>4bmm z1v@<3qFjwUlv!IsZ3a=P_t@{4@e#<&3??W9O)yd7Wxn;-`g32X)(jm5xSU*J%O%#G z54^&-dOr?86iZ-^+`~}Oo&?4I+21(Bg%D(#-}Ga=GDNBdT#pluPC#&aq^?CkIRBOtB(uMn#6#{)-h^G zbFk~AhY;r(Jlysi2DcK?ZD?9#Q8!$OZK|spsh!kEZ1@eADp*X-OvJ>w9KIT{jO(CG z2z|jm_D4RjlbJD2PFSyV8QtWJt3(y!rNj&|4yqMM1UtM=O! z-dI8wACq|6G-1HpIesCX>3W+MxC~eLvvzcxTvmLR3Lo5Hvv|Zi7AntLgJYr>79I9H z(iQs|wmY65qs*88hPJf5S<7QCo#skVBYpA{LlCG?Jsf91wHluQK?9a_Wnf8H0s(IiRm1$}}J`<$(T zrr~W=E)pdZ!#h?jd<*BZV|4Ub8oOu0fmJCsf(t|t4e42(mBR;u#kpo1b(wahLlr)G zF5-3h2AI-|4L@BPzVXOvE2L9T&;Doxqoz2}KgzPP>8KY&?*XlgFO-QwSq)OgG)$I! z;SP5#pq&c*$*)r9o7+hWQ{V>Us(8n_N+p?aATDQ#40az(V2Bc1!-T|AdGSc9LviTx zd1pahzPS*ex-VRihld59EE?1usKZK)UJPM<(vq(k0&%h%n?@J&epg#09yU6 zW%<3dGEwSLQEg>mJu05T#<(`^JBT!FQRk@IsIJzI@3-!`Blopu;M=dw`*si9wLLko z54_Qo`P>oj5-7o3x{qNf^JA&;vEORoEEk0VAH1Mf@j>vk|2A?jwe5Ysf=!pCOslWY z_Pbtr`BGC|8e#XwEUls*1dVZz@Rpz-tv#eS*v$~Wl0Z+v1i2DGzFEjS3euN+t?;b! zlEZ6jhxkIk-f3H&^T|;jNKpMAuEJZ)x&1X~4?iK4gcnk&GcWsLbBvVC<_!hOn1?P+j+0NhUxO#iTP04-6E1{RRnX!T}3v8@R#i5Y8zmh*jw8%`)=pMJR% zVYR@vk-JoM&G||jSi4BR*392nAl5ky9S|Kt2CbP7n*@`U$OvM`L8;C`#nuMK%Drkn zJgp(w*#aq;K_2G6NvKC`ZoKsBcFEzj?3h=`i;d}>`@3C7@qKvzmADY!HjeQWz)-8e zmkxX-?3nF?ooUu<%RYxPW;hcl&VhJaU*_L38%Gmt690q>IkRO(ci5; zyfVNz4-ih%$EC-oeR4LKxNwh%)@-c~CKEr6QyubLn?Mw{OYMy=ZY@vq4a4{;8#b4g z77^yn`CG5;Iee^)jzTbsk8LG4=T74LmaEY|^N7W&z$3XOtT|HW>xrjXqZ8~q$>`l@ zJ--YaW5r&)VlLRhIqnfrnZ8|?lk`{s6>Qu0>Soa+WO?!Fx(KNNSRAVCxsu7WeS*_Hk<#usqFr1!4r}8}`VOZB$Q}P1jEf zVVzp;l^I%UVoob|53;WK;lFtd&uYv@r%$4^a#7L6M;0mZ&Nw$|@aT~&r&_`57~5BB zqUGujZ5y-C>5eDpXiqAU?jU1(5ULqktX>Pv@Y<}47taQzhz|W)oYl=nIQ#jz77bT8 zTl-O0fSqNq5P7o!ox!SU`hft>WXn=Ye-6o4c7LLBZgowx%zuwa@=diQ`C+-<3M&=f zd>qeE%VTF!lRQ=ZGa~1QH_Xkqi-*&k5PVss9g%5G5syD~^o%6~q4iSMkFjIQAn#{|ch77vTJxN^_U(wz#-%$r$kiqL;vCkZiS+53Yi$zTK?m98Vd`~O{-GW>lRbFW zwJokhDE5n%^vgT4j&O0mZ564=nEGnFt+~;Pk=$#sCH60I6{-olAPJYxv42E`f*x>Z z-TgRMmxj#>Wa;FnyJKoy1eA;B5Snec>+F%u;9N90JSKs=l4{$oKne@FxToZTHI3k0 zIazmvoeo_zBnAY1k&cpZw+q^=su6DaS7Y93R^GBtk-SOS7Nq{Cn{m#ycm_YRCJfu0 zsNdesRI0#?eyJTdhmwijK84#+1JRcOP z0W3V$YS*KJJZ0tjKHV5R!Pp&zU6)+ml|^3Oj|&>g;K z*4_i#KQeN`Yg+zOB&o>xkUHs>Ap{rk^wwp23x={GA(>n$ z2|mBqSGu}CZFwG%nak;*p!^eA8s4@WFs^ma)b?_VfPsJ~sp9Hd&;u5Zqm5kJ@5+T| z&rL>a$UJ^|y{$@ULoT_t+uK?kz_g&QQ>9C0=+s4vqMhx1h&}xd{piA+P>uUB-SP2J zKmp>5X2fDfUrjGB56j$TbwcgC8G*OaY-`(kV<;^PxtS4TqvFxJVw%ieh2#i(n$$MV zg$bUx0Tz{wCP(cVMCD;m6?o-))?(j%(Zi~SzVatuu3kxgB#C&mhvzBp+#8)q&NWDT z@3aeH^xlJVX&H_4;+)JQ-APbcE=?hNG86 zjC`3U@VuNZPA)r)vGSSGvvL5@q~5KM2C)Hcxa~%q{-~#UhikNxpNh52R{XwD4J5y}27=l3cv~m8H0juCw&1sB zxQ>d3VFCemU7u?tHxg|BA<;g11`ZziB4O>23iGo&O#ZGvIU;Js-w`u?i4Cu!*Zz8B zeb01>P&B(No>x<8U_Hy!yWL=KgKn9t*=GKfQt$ps^pW~6SIU8frht?g*Y<7tW2-(YTLhrX;89f}g+E*CYKwC94DyOB-P61TueX-HdI}fk zuEr-mWezt)8xA3TwB#A95b7p%M;6VP#^azJO-+NP3?S5E$Irra=A*!p$mpFWlm`xJ z!G4eAD)3mF!ipZgB8sC}rJVX}Wk=@eQ08l%{aEobm&`>tJ=OqnoUQ}sY~tgp>2B^& zgTL$oLsscWHH;u{MjcYtba*~-o@lHRb-_9RJl4)Tx{)GTd^+FK@pSpjGmHVU#VhXM z)3VyQJgc7+n{GhRdZWj78h?Kbi{`3pO;@*oL%}_ls)!a(A}5@0=9zB2OgD96l(InmYU!nWLhuiD`M}!6J~s#cTXF8*w>4^CES+2Pa|FmfWumBY z`H?`!$*MP0YrDIyg)2Er-?tG{Ua;Pwu3BFHRmZt(`j3*Vvf!;Q^J`b?x~a)0GX(O9~@HL>4XtBnke)^7zhOV%fB?fgBS6FK2T{u4!he6Kr8I)>pA`oJe zC>guNfP=)hnXX+8&mHQRhcd8M@cX`OEX3+7tKzA_Zxnnvm}P_9%|zz(Hjt*i!jnkT zDHai}=5Y}|)5&2U0i&Q+=$fJRnECJ;$y+NM&>nrUu0d>{lR0gEr+FNUxc1leiIM}^ z<`StxLn}B2qb;c$Cvg(;=FE8nvOYkO3YryqH&qCZ`W%iIdK8z8-_jGDYQevid>zv* zvF{Z8I5<3>vzl+Mf$mOV!@Bi8{s;eKRM`WJ)8m&>8d(dcc>+s?NhR?=o zYY?O*vV@PMf1XyfQRd|BXT_YJN0Fv2+ro$-9sn9q^QbiUAWzWv%AB+mtS!h>xGFW$oa(rE zEZVd|lJhtrN)V+eqBp+j>O2ic$(NdMP)Dlb4;+aFHM2~Wj^rw#j>Mh}JQLZ%d0{#p z&xZ4%v*#hg>glHgjrS}X0wrz$i*+9dAD?t>nftRdHR{E&(~I`L;%8cxbfqJU$y`T+hmD+ZeL$V`-*9>hnS9rRJtpfWQ~sEh+c{0{d`_c{Y*=HT0C!$ByW#`OwXUw z4%urt>F;^}G(zsotxbGwbz1$)80Te#$5=ic;Fw=#S+CkV-7tEyx*sC{z!8}=D-2uD zZh5w7E;BXjWK;tyu~iW}YNETl-Za7G{A|*B=YdK66EHA*udd+C(QEEWW`MJ!qp@OK zbbEH3fAlA~W=+13xK^q_VC1r_>S*D~N=;obOt`uwJq_WxY9j#sU0>Lmav1t#L^miA#;B+iA322JtqBkctJ3HkN@M88!F9{h5A|b z&{hbjD;c2~T)w!7xSZY0hr&V5!sbD}Nt6Z=hQXgL4;&5O&XcY&^VqGMTiw?Tu5N59 z{WNPe`oY<#p#L{$f~kfLn<-&+ak`ejraH(; zE_54ROq*vo7I|ehnY9;we0X->JC3$P>}K-Xd4z#bgELYs#mh)TzfR%6q>BS;?aM>xNduAma5cKcU+Q5>R_gVDd@NAsaH|g0D^xHSjwkd(ELas44#t93{ibv8sgE# zzH%3aYgTOf*;6^+v8++W(Q8w_MB1oG7~E;zq4q$<_`sKy>s-R}G`>Y+1lN4HK9sEx z6tk%1d1u;lmHO@#p{4htg4TbS($xI-wuRLGhl$F3tWBep`3e%Ro+;}G1t(U^Sirk1 zd0frv*-!j3?NX-1f`r9t;pF$KIOWB{YY}^^4B{%+^Fvu5I!o6l>J0|ghp|#SY#0!{ z&t&HME^zRtZidbcV4d-5t9?+*!Xk)vJkSBD^Sp!g&kOd<0y~|G1iPz@nY4%TIjHYT z-|%0g=Ysm5f370{RnBP#nj6yzS48#?ZI2MMn=l%n10iNqhPy}Senh|1-$A!(n}DUv zws`#vbm?9kpR^hjzk2W4#bw=txZej65`1dNa+qdIpJ;69s=zc>t6%|lV303T;i(CU z9g4x<4|*fuSbx9#dGO>qnyO`HgAJY|Z{=vkLrIfOgyHcK#$IrS@ q0u)dp4GQ)8-4?~dak?F(>nW7F(V0AEtN)+q{NG~z|N7z0)c*rOlRKIK diff --git a/docs/site/images/arrow.png b/docs/site/images/arrow.png deleted file mode 100644 index 754d3091963e5732e509ce7914c6a021a87ec9c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~g!3HGv?z=Y!NU;<zo7-q&JnvO(0TEc)td-$wI-PP4EAvE+TxSAF+M9ho8jh~stUt(um& z^}9QY?>taxd9(JC!m&RL))Dg#7|grAq4RM*o8hx!i=#|om$&>3T6+6+Y5MWydz1BB z-dJjO`7vLAkz6ljM3& tdw#xe6wpooxa#93@wBi1-=zMN;lq^Zk4qO`%>eqH!PC{xWt~$(698>8q}Kod diff --git a/docs/site/images/banner-bg.jpg b/docs/site/images/banner-bg.jpg deleted file mode 100644 index 0ba44ffab74b351732f74137593e3caf861c9222..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 611 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 HH~T*TOk(2@ diff --git a/docs/site/images/documents.jpg b/docs/site/images/documents.jpg deleted file mode 100644 index d96d8ca90217e6df4e7cb8aa75970ce685c571e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17566 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 Pk8A&5EZLO3o&LW7$>xZ$ diff --git a/docs/site/images/downloads.jpg b/docs/site/images/downloads.jpg deleted file mode 100644 index 9c4f93734aaf6a1ab0512e63b07d84cb3d9ebdb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15962 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

YbStsWba#$`zVc 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 Jx)5?j`d_V&u)qKS diff --git a/docs/site/images/favicon.png b/docs/site/images/favicon.png deleted file mode 100644 index 63bef255b39f70d9ad144a76b16f1340178077a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1771 zcmV;P)Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RX2Nw_q8Tip@^Z)<`eMv+?R7l6Q zR&9(GR~deuGc)(jUGDAzyTAeqwLqXPx>_QLVq(OaGze+>qXf|cEv3PxYMNLR5)(C5 zYfNlN6Jyf;Xwnp@5>nbo3lfcy+F!5=f)r?>eC znVECmujhT9_b`eFJbI~3Ndh1Z0m%u3B!Yq{0t5x*%l`Mvoa;aT;(^~)N)-S`eE;(M zM=u>K2VvPO1%BYcfS?E%cjwjtFiD0!ymscde|uqG`@FS_*7Vo=9(-w4TeYpV+|pic zUova)rllLJr3oYf5yTz(U_GhR+wJ>$K5=DnwOJq;Q|NVzf9;(^`kcP^TBf0iYpxp6P)@-+Y@kQ@o@1`J4o zBx#*pzTlgmpV8%h;dq}H(I`)~Y!q-aQykn(>{G7|GAN$1=+Ame7}taU{ZNC3td z0QD?6bnZ~GNJW)$R3rxokl;uoj_2U!ngL+uvLuU1I43}<&0g!?k(*sSG-TwH++C>1Axz!+}c%ZN>Rm#;3+aKR|V(+Of$9o5QSHHS8P7|@HS;MAtC*R$$ z$(7-2Q5yTkGsYMi>ukVa%L70D&f;}ZG*HlHWS4(qPsGXa#w8m%CQJ>yprhJR^2>>B z2t7?egE)}yhsKiT`!l3#jg;mS;w0#(rdlMF`jBWUF$yW-`CFArbJ zo9xq@T@qn@&)c=`_0HB#QUXXb7K2=c9Grmw10y3sx3>;JP(7*d`OiD0pd^qm`FC^6 zQp!mnAW9-Y-JY)^pui8d9(d97LqTG}BQp-UNrJVwHr$Ac#N;H51gfI%rTn9qOB5S6 zwa_c?y&U@GoTs;xh(*v=_L(=I9Y|`qeJ4XWz{ycCfK!o|02v2DQ5tPt`b60)?>Vv0 zNf1awa-0mpu;uApKkUBnPmewT$`#54j}Ty8QM00Uj!0d0@6-hkbv;}O!k${sP-A#h z6USl@_`%NZ*AJZihwu9iF0+|H&{X`UB#VaAC~CxUmNc>ia0UcmAc75>&Y!wqTJw}z zT*K2dy=6uw5q5FLImuD{?Cj$aK1HC7%oFKVn`Lp{r@BQ|owV_u^ zWlvxI&_m!Ek08OW>0JT+%%wm2`ZH_pU!7zP-}rAF+x^wMmo>8F;Dv)D-FpkjgUOI{ zwzb^4VabNfX3ar3scEv6J<@wrR8DDy|vWpncwv zo+GI&#}zvgsch%O=`cQs_G;T_+GZP?fAtSw@UR(Q$4~xFDpl^8x-cJQhGt9`p}jh}qq!rt(F=dy3LtaYBa7C|XrA65 z_1B`BA#;*mt6!D$#m+@tGd?HDN;}tWuSK=qfnL&(#Y7wja;W<1HEV6x%q~Mi0&vacYG>=r(|udZKf;w%9$I5^bSHkrfq>v;weoO9M%N!HrjU!GQy zCaFt9FC59zIXOtA8I3Fm0xMT3mp#ufl}f(va>a+Qj#vNx|1UYgP?%ZFf%jnh zeYsaj!7qP*xb0k+b8E4DUG<4Zy%Pry91!R|tMm~l`%B>I67NqjpQ2}6V4Vr(fz~j1y85}Sb4q9e0GH@hApigX diff --git a/docs/site/images/footer-logo.jpg b/docs/site/images/footer-logo.jpg deleted file mode 100644 index cf6e5e399db2676ca79e0691690a06d6e26f443f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2499 zcmbtVc{tQ-8~)A0vBt=fZRTW#$* zK!E*j06TAi<3CUT2tP&sk-*R5ogM%t2IvAuAs`q4hJhe3&<+Ps1po->=lUN+e-Q&g zMI?4feOUku27@3_5Evr<_l4aADgqM)^Jw+Fyq56`tE9YERBq$7YsS-#3)X9oz}j>@sBNtLnhKZ zuj9%cY{9d`>d6pSapg9MI}ZDyw)VA;bCl^~mp5GV*1iv|E|v~Uz0s}Q1Fx>q7t+Q~ z(vDP~@w$_n!m1w4KmQob;CysS=4{wM9~iCA^ybz(X+y7oObhs;g<}oak&eaoOAl`7 zc5_<%e_;0Z>cpD_o6BdvR$ZOAD82GRHQ`Q??!K27b=JD*-LYz+MarEX$^}_1*b}J@ zf=Bm#{}^Z8@07Ji)s z$?`qwcJ-+6OuCh)RdPIO_M7_+C1FasV_@}wZa?)VR#JVkv;_V;>oB? zIjF2=BUPxm0=>>i*GBl{zh#QFNz?mLBS@;#!|sAGN^L;62y~((+}nL@4~}bLJLyDG z>PY7sUn^}Z;#y!IIlrA9l0t3EDeK(XifWuW(rYB05gF6_R`c7_OOS78U7os9n0HBP z)9kN1Kxeb?Uv(kI%Q715tbW&C*BEN6HG1KMvc_?OOptUSa-_lH`;E4gfULfSGkz10 z9RI5H1I=rBR`lDZ@Mz4?A(>~S2A(Ln=*`C(6l_`8p%|uy3U9DPgh-C8QwB;}j_&+*2@9t+)fY&Lcjv{`y9aNwRD9>F!H9 zwKCIiH0{_PMtD@NS3H? z=#T#hx-){|L(>dNP9>7OcZ*Kfm#zsTFL!)B-Cgf~YC~{y-1MBxhM@()+(y?@GGY+) z(6fE3?{n3ccM#jIGvelI_H`UBX9bS?U7uF}rVBUGB9YbM9*g95W$$M*wmjRzi=R|p zU7|ZYNx(K0VvyPI>kTns*2eJklkH5Gh{T(feq&KN4_N8@0)Y(jqoLSvMX!E-Q3mSB zC#lGgr*kg%{8ipAc!otGtjsSTf3NE(Y-EObe#nt|JQ$2;)3$@QTn4R`5}HCJ;luiA z)QQKEM^%h86MEKxXErJ(N?9|gzJ9gbWj*E25+%a$AJu~2NXg767VD{@&hoj@)@Grz z9j$R{B2E@5^vYbz(So4Zg|dAq72aiCS1g08_j4<(_FS!lX%a`Lphd+O2fo&PH;qzc z5rR~H3B2G|LdtokC=dM9qJN45B|T z`#FwZ*cet&(pca&Is_#Q)Q}1{K^vH`$E8Dtb(4nOhTX*^fA} z9}#ATEyzSFo9wviyxOGFYj=2$gT1<*WHF+&Rca{SLEl25EkLTu|b+WJ82hL7XcnoPoi%F0V<%%U^zG5U^SUu9| zN&fqrI2I|3IX`~NC|YUSez{jiw@@d?n^EGbpt`m)>89@{{Jo`zFEBRCSWn%fS`WSl z#L3g_NU=wx=WxGIcHD2o*Thy~*PB%DNzpI$rR?DlH~%nZE(K71 zSwu4evhTG5p|9-Q<5GWrKE0xm$7yMn5Fe|RoG%S6qxbmD_Hw2r0!O}twHovFEZ&6- zilcm5x~*&ok`Hi9lJ@G8gW4SG)bbQq5fK;^@!2)8UM9PkQ!$uPtVZ@WdGMO@=-snB zo%(ByH(=%N>iw)YwHSVnoP)Xfe7-<$%mEqWxVi(J^^ck^|LO`r>Y5Fzh{QYtM(Bw~ SXC~Dw&sm5@vAUCXxc>p~s!|jH diff --git a/docs/site/images/greenbutton.jpg b/docs/site/images/greenbutton.jpg deleted file mode 100644 index 0f8d7ac3bdb0c3edf4b6d33cdf4fbdf46b867044..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 335 zcmex=i3*BJ!6k`h{6D}T z$ia}qz{Jcb$iO7X$SlbC{|JL50|PV2u}FZCg_VgJC?zYv$iT$FjwHh%B+SSnC=$Hz zB2Zcas102w6Du1~MpO{hK%fbN|8FtyFaymKWENzwXSlZUL?z2Mj#&qV&&Ub0d}h9x ZZt?r@g>0@T+<}~u3lfw?l==VP1OPDBGjIR^ diff --git a/docs/site/images/gunicorn.png b/docs/site/images/gunicorn.png deleted file mode 100644 index 98aaf382c1e58d9cc7eb6b6e49f15c0e2ec0e914..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1553 zcmV+s2JZQZP)#d>2 z=nOG2NKrHb5^=D)-mu=V3SMFWK|=+cK%*!hXcY@+W+2f@^aJ&hWhq`zgBn^$vD8|j zmhSe<@x${@cXr*`w$Nxl_)jM9c`xU^JkS66Kku2WEKAjTCBw^c5;iny%`Me> z{AQfis5KuugnP)b81wKOY<&iEorw!@9(F(Doy~x}OZ$Ue+K<8Q)q3TKL$v;j@en?T zOYksm!>yS0H0FB;&c;g)(f+!k8{_8S3GBpLyl={o+eAo@<9K0!xtNU>RyS(R%?Ggl zPjNDiLO=eQ)_fQ4KEN{!roF<^Sd#YFi6Q)>%liY^HBEbtBTQ!QzO}kBZWr#r8ymG| z4cn*mzYUx4d)$t%VwGUcN<3JtS3X~@S9-e4-^R=EB+9hGtwIj&#!JOv-;>6^BGu1I zWize6Lojp@7h#QXB79IVdPkafxMS_J@N?m;jW{*6ufYZpbzj3Z_#3`0ocaKk_D*-2 zMy*-mtsPB&$8+~%gig%HW$7>@sGlFz#k?s7Hk6+=Oju%+aYlCY9|2?MY>6!Z>a0P2-k| zuq8tLS?PI;2;JGK{_511x6hiq)TqUjzqe3&*Hfqg%9;wzV$BDbsD6YkKajr1xI$Tt( zS1xbVnw_bAq0qM_COj?8vrIVPy=ktMfF#C;bQSgd9iTHSembm@oDONW(w5>X_9LjwPx9FEZm* z9q(M7`d)w&Oz7}=cwxu5;WU36E73m_<3>c>UyTo>wkw4Z&K82&#*0#UCp2o!FIMZ7 zC3ttE*1QzIo@V|BL^iuoB#G_9XzTHbDPy;J`e>Of^qtr%GVej7E8`lq<{Eqji_^a+ z8nxyI{MF<;9uZ!T;>R6rcZu)MZYafF>s0(uu<3Nc($);`9Tvz&Mn?LIq8PwHtJNAP zilVk-}KmxKj_Q)9$G$l&Zmo_Xca}#TD$w!=3q9s z{)}?jb*)ybRhDJz7x~6FY|FM?@w(RQPZ=__y(o%ZWm)bT9v&Y1UmyBVptq-|2eP6l zva&4mvMh7K#5~XQyicFK<=&pMEVDe%^Lex8eP>bMqR}kN@+`|_S?0vvlRmVdod0mv z%5o^n(h23_d;1-E;oNfWSgUMhS(atJy$5>VKK$`--W<8I2hTpX00000NkvXXu0mjf Dt!fN< diff --git a/docs/site/images/large_gunicorn.png b/docs/site/images/large_gunicorn.png deleted file mode 100644 index 403301fc0610ea6699749b5c14916e23737fd49a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21956 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 M);G~B({X(If7)*~H2?qr diff --git a/docs/site/images/logo-bottom.png b/docs/site/images/logo-bottom.png deleted file mode 100644 index 9264bed93577d581d2b8d72898e97197c019fb48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3145 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 diff --git a/docs/site/images/logo.jpg b/docs/site/images/logo.jpg deleted file mode 100644 index f96c50cf5291d8d93ba80a4a52e774b77ab812ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10238 zcmd6NRZtv2x8~r%f(CbYcXtL4u7f)a1P_EjLU4DN;I6~q?l4Gj3lKDTaLvHxuUlJt zA9kPa%btEX-F3RpS6y|w`}EiSy7Kx9fUBycq69!dKmY*$6~OB{K>k0i|B?L1$^Xc~ ze+Iwy0r1`clmQP&2zUTQJOm^>gx4VeB>(|{i1Z&j;C~AmI_et?6eMKKe`Yyc00J^1 zA^-&u2?YTg{a=@VHDpu-G{75lJbVJecSOXrbQmNI{6bdrj7+?Ig2J+feji&}MMULP zw4<8F7XAbA&o=_fe@FO-h>U`YhVTacpIH&_9|Qs-G7=Ih2HJlR0EhqtBxF1kd{hEj zUNl*4LOMP*jqm9Bb#y(G`e!fR5HrXtY+n*7THAztD{2~eT?1et{hJ6L5*|Pr zaK4-At%)b1uuTy9|Fu#)$oR&PIR1l{gx(^JOFXv0RbGyYiFbH+obOljN9~4bpvzxy zNn!{df5E}97j*_LP10Au*oPz`GNUzNp5SSsbWs~W_lI5HTVlNf#B};trsVd_POOV& zMh?wa00-HS?!exr*@`WWwoi#TwVUsJU0jEGe|fQQtKpzp{3P_q%(}dz`hrx+3|8)g zV2pyeY4HkREKUBtig+NGdsN&6`HDyfv$F3SPYh%69F~+j>Q> zKZ?%hbKEjl(?(bb4-C1rdY^EZv z==lX*?rs8np^sz}dBA38;i>0^3R8o8y|?`+Nc7ufGM;X_?pV>&G#UNK^n5GKl1n_( zp!~3X4f?e8OBel^_pPUbRWs!h?Nwr7PIT?Kt`sBgCiBYYs(1Vjmhxw?Z*V=kUZlO$GwFL zEnaNU%-3WSFRbtnF}=Id;y5&@>U3%A>2ON99IRB4P-V3^iNJ?Rjc;NEXQ~lG6lKYO zoje#CN+EOt;RX?zpVMl~vrWvvs&b9FcS*Fo1c(GkL^QO%w6siPi7DP5zQ@xWlpRe^ z@39yF$^4}Bi3)vvnP2*HK4jwVN2=uIs^qP%UTqK`@1>^v*AjV0?Ta*`M8Vakd>pLW zT(Y@%e*bo=W-@&vUeNk0?nTSKnC*uF7pHw{8RY()9K3N|mv_8a!%4hEba=%orou>Q zon0`?`^U@Yo&}RvK&OOBm#mnfb!Btiv6E4E5*H9HyVFFRqKypVqN5z&qK(W-BW>zfh5~R ztFxXVDQJ=WLJ|Wgj011Q_>{%UnPEz{2OLaHlQCENnv@G46C!;irM@ZfD_j4)%1aj6 zj-+ppe;9bP&qSXX&O@1y!qur58SzVug0}iHf!HNLGnohZ(sZ#_i*q2I>_Qp49SuMC z!=$yRsuh+EEN~3m>4=_r6qnp(U2H9_+bH|NE~LS+^yA@jQ*M_;pYco_Gs@3GRVA}1 zA^uZt7M+x1cd0Z7>H@*6?c}a`!%Q=#5M$a@>NXWT5t80%hUu9bPPQqh%GE}lF$n{< z8BV9&pvx)bFv9N-M~S?&fdO2Jf7vAT1k=d%Wlvfi>O?Ep!o!pn*O9yYuMwsy9=ElR zlDHZ%aKX!AZ?%ba~wG;q8(vcftO+8 zY9ZUYU<`R%s+pek!=T%9 zl@8CQ=VXF|KXixtjs7bj02=al0$QuFUl3R5806OEAT7UJzIpj=@L2M8wk5c@So19R zX4=0NRQ)7GWgpnX`=jNgDKMbJA~}*eJHv7wPfd={LoZu-Ze4YKVBvU8b4t6Wu+)L0 z9y`*s-9r?n(Y9Q=Xw_TWL%Ic7y^ZTFy))?~FAx0WCtU76{#!C@y=v(dP=Aho&>S>6 zWXd-+b4Mmo26N!r3KM;Bn~4NnujX}BE6hs9&TXVuSpO;I?srEZ*X2ld!`O(m@8!K= z9T{C^zg~}aMBXoLC4!;Qj68ycvv|^&xZXdtPBELz3r=hcUH);x1r%NC&i&qkx1CqcR|8St^@s=+$PAi|4!um`xd!zTU??xX zx|4AP?ZMt(CoJi+XU&#U6Op!i2lvv(`=Zh7mCf$54ZG#z%_k?}3CnAgI>OvD3?=3K3df)9Mx96{|8g43RRt8JUlQoJQ3u4=t8Z=-3YENpCCMg(aU*sh8n-tfHI3QXHj(okBX^O<6dwp zEF0)H4gZ8~--#O}qZ)&rEOqoVRai*6lZ>8Us@_X<52b~`=i1fZpYBlC%h#qp?_(UQ z=EcwKKZbDaRw@FFEk`1jc3)$|!r$M%`TWgdgJHsPx}>nuSIl)H^ukz0rmE422c};E za@;eeoyyDRBf^pa!rm_3xew`Ak5*}FJV(D3mF`n02`~(sP8`r={cjm7=F4!bDa!ee zVxQZ8eTmp1b}vm*Y0bH%Hd?{}wFve=70Sb0aEKu5aq;zt6l-bW>yLIAV=>ri5xHYnZQm8DlymOpBtf|J?$H= zwcEt>LCA5^^SY7x3Ssu8sog*)*&6F|)$I@7B%ULi`S&l1(XnsIBhwuYrtSK*^`i)8 zDGQdzT_qe`b{~qa%kJeX5*-hObUGyqncnx|+KRfo2R8zxsAwyBGx%6I#!(#;x&myK zex_kD1d17$`7WJ0#uu^~kmHD~7~c#QO?l5)2?SdMrkW1V%2n48!e9#cbIxdVgx&(n zIy)=T&PXo(fGdXP`Gg_IT%+m?O3@_pw~hZo8aMH;`q@oU<|E<%Id~PrmTyP8Dyf@I z*_zqx?B_owFRa(5_Zp&-zi)6A7y(&St&!=S zOi4!Hvdc;qSwkgw6bYA9AR+lOc%o6QQdG*!uD#XOY)@`^I>XgIEIQTBm%JMg^BUZh zHk-V1XU9I<2KlxIoup2;KxsoWe7|&=sJ!tr!ahDLbz=Tcr$?@86wjVk6TTYF#n%kH zv}tYgD*;}~X1Z~;K;38q-2!f|z=UBfQV*^!ZIMKx+Q7`O_voTVN#m>Q9FNR?N3($l zqju<*t~PQCJx9#VfvMdI~re!yhE2}zkMEx9`i zZ!fT@YQso{dHDWT^X%uIOjE|Qk~W;eWf~dW_y8oo+q@!gHHj8oj@L9o!W~uG8{L8w zC!VwRtDU9hWZ8u%3pQh0U<9GFBQ{$>@#~AA#|r4(ZmHzCq0l>fln`=N4;(2WwQ(5Z zR}GIYtFDxK66=q2neJ4fc$BPfrgd^1q(M$5ai1+T%PaK*2R#9qrX1&Q;S7p;SOjJp6&Io(GT&Qc10e`nxg|sQfZYV~IBa^>a zIS0eluSh+DGks4ngGk=lUcrfXQ*|v!{EQPU0jtn;Ybm95($UZLqG^J~bXsU_EN-$C zIZ_cmcNu@K)SKEl{h&R`*AZcnN4CDp(Q$FM>Y5kkO|*-$RWXTnL%QE*8|yrr?+Ter zrX_j>_*zd6&KC#nU+<3poi#Sty4bs<{&UF&bi4M&QFhsoSK_>_XwE~%@3Z}?ixIyk zYG0z%fP*Co;l}d6q{B*XC`hny_E-MC_#rE0gu*;P>LY7KSbRSlUOYm5Efndz!r<~{^BMqg< zVOnNUg@VpZ_-S;TwEfo0#Pj?Mjrl8}Tp&mvdWm!Va-$FDez}*%cYpYNP7NoRVTKP` z)JZ>!v1s)_4{FA334lKd9W`&DIB!_-h?#h%kEsGlV%J2y@yW%&csCy#~0+2 z{5qw|%j9@t?P(K{MEN+wJ{nH-=j1Tj5MXDTv?&5xnd0FnPTq`YPE>HhE)@MuLm*ze_xGuv8^ zFFC2h1nghT7McnUv^IY@fA_32ZYl61yT!8C`%iAK$uppqC4V)FReo`1g>qE5t#&r z?kMh5njgk_&ePS``kX~&Cobg;WemooGG$iREw7dgY(F$kto*`q{l&K6kH0G{#8ODN zJxzEPnR33E;QIbrV(Vc$ix{#){0m$!*0}`P2swF~TaB1JZW+$%0jwlfU0vwW523|o zdgh5WnpSn7T9SJH0QHwFc=0I;v*S(hOJQQCC|gaor0_em@IO;`upqU9N?Y$b`|oRn zK8LHSoV+xjX@iBqO&a(5LNK<<%1KgG$IyuMT?lNve9Z-%$8u69p|^`11vFq#^+8WW zLLQBuChv8kYYT$jSeP8S#ksky!TRyLV^7P0EnzT6a!(PSw3WBu4i0#YNv~e%(jZ#> z0*y@WLsC2r3K>rq13T~=28F|i-X9aQG1W4-?&Fntk-uDJ2+-(!vNi_a94#{lqW0&8FgF>(P>`U9PYazM!VQ<$M zs}jq!+VZlzNQU~!2J-t33i4xd-{=Jn&M68s4gF*$L>8vwr+^_pv_}2}eFXPn9Cj_` z%f@n#n*nPk3}mCl-er=`Y(>kkMhp2f9AMGyOtGt6yT?k=9Dl8lM*6TUSu=sBTs8In ztr{e6C3Ji4DArX+m=E1X9ECt)uB*_Dg2aK;iP^`SxEbWPK+|fzyL>iR<%>yk+y&&< z49{_ll4vWk8|kpbZTBj`rc$sXFfn=4P8BFx=}hs!Yw@|HI>R}TzTR=o+oY^iYt?0n zM}|&kNH=PnbPR_BVz&o0sx8( zR{OYvdb}(-2A&*iWm3QeJ^+s|@2PcLrAyquY~&oI-{jp)n|z8^9V%lM2SUwyqd;&d zA3HUMA(+qH&BYMONDui#YoSStxBnZ%YkkC2_Tm+wzauFiC@FQGNu#TVK5TDF%b`rr zDz~?g>nXS6y83`+F@q^R(1U-{WmPm>>m-&RiANdpuB6`gQ{xnJA_0HYvn08E3SzuA z1>|ZEG3dd#XaB;3E^Pw{Rs`I04S&mN0L zFYibJJ2AUm1kX&{ePQW_a}dcTYKGiqv0xsXqmzs;V|;gv9se-7TT*{%@f)ch4$KaT z0sOn%;h#2K`nfoN+*Cge$7EwiKlwO;SE5Th_pP=={U)?ypFkg@`bgqdN~ygqNCWwo z1gQ;NDbr9Nlwu5+?V@TbJ?|*D`zyf1h~+YD3=-GweC4<|=`<69=tr&t3R&7CG+!f( zfQ5`q3bW2X+CPHxfNwpD_3BJkBlZo@=_B`jr&U5riJ6G#NLKcJ_eW`QxC={;#WJ1o z-&b=c&K*$|`|sNOh2(k;Vx@H2k`@gcS=OGG8((b+n4_1z8A7>N9`Gwb&nHhf zT7VQ;8hxYOd^1xyHg!Sr`-+Y519c9E*$D9l0~(j{05eE=kWyG}N0L15!N4-%VyU!z zp|>cv0MBTyyH55^+$(@dL*l|qf!ceqG;cgw1e1vM7kw|IwCQ@cVe?pkXtau=Yk*~w zRGGsluBIBzpRXxIa_a&7G&SHby0*-?6SsfioJ<%NpglD|pkbDett``^Ij1iTu0l%} zikEY&9fdx{C`z;3?TViQ&pV{QP{=5n8f~lD?h29yqw7R#`O1dtIC2m4X%2Csq=)>Y zRh&3g_v2wj`M!2H0WSf%0g#Pa)(!Hd>XYqfyH`N4PQFBd{_i?NpJe_U^!Y7&4^x%s zM*9O@+YDGOuT3Q=pHOX&AX+5yNS%nRNK|q*kv~H=nBIN&zGw}xIhZ?VaApm{kjON(Wi%6boo^&7rxC^?>N&T+fuP{%U+`%kDQh z=(I5ZWT~BD%c^6e&~!$2DQLj@7T+|eA0Nr7f>WZ*l9eQU4==`)w=gYaK8gnk*Z-Uv z(!q`h&+fgUUUk2()&0kwn(eb&;J(!VQ6#hy(K-`roD1s{P%hXf~89o>#49h%9w83A5xv7AVHZU3$sGmIE#{`UUU{vqf^=)0kMh|u#*X4$$@Uqrb>WR(4GZ1_U0>~dLVng^C@Dz+uetdQk?b~CKw-rg}=AJcZ!4Pve)nRn)n!-@K)U&R=9*M6argkO5TLdm((0!81>;3(jsH- z$z@_y>>YOd;d;{9`(9nadn&38huGe(T&!P$P&Pm4s~CK?YkUgU_ z-d56+*d6Y=P7i74yz}FuS50`!`W}T|iQ$k>dv`Gbe-L)uxX zhuan38Rf?8isMSRq`B_nxx1)^w%NGkOVe)2{mcy=@q1SXk$el4g3!%WsfVDF#QMRx z2H2*QDnZG%E^$1EO;_dEiCg25*YWD;(Ke&@sP3%~9b5&{S9Py|_4`*qT`uJ1{^j>8 z09aLj=llxz5p37H3DtVh_DZV_lz-~&CIrH;l;P!Ot(57RV9lPVM3|!!Mv$QlMGE6- zDTyZEX%x3O?LB{j=}gCNot-A9>g0b##bN@-?EiTRB4($AvUwG6a_u~W8V^fmj-I1{ zXoy+iqFKEHu5eRK3)2sHt6U9|#AL?8_V}@kkC%+V(3MIq@wcpH1@2!i36n4CBO5PK z){-^KRudVcWl=eQd86jV>vlGL(lDloEB3r2$6&__uC;L1tpArl9O|A2cRiq(BQqcUx-za!>m!Y&I4qMn=5aG`!S{kl4Jb&7I zl${?1Vp_`cax6UVD@<7>e;`ddaRq$|tcXjA=12l=4kEu#aIbY))1%NIoLfNpxOVmt ztdlLn^RcXN#%M1#A`=TvpGjdN8@orrd-tcyuuy-u2fwjAG=acb-(_?D-_12Cm54NC zQIs)sxHK+?^IhZ^nRc{_vg6oPH0XkRWfU5|b()}AUugtsu%Cj;V?5VBp=?06gB$K- zS{BkA@R?zDeV8|`zY}8g((m|F8I4EzF3L_9d??++&kjUoqWgxcQO1|`Vi$*c_I8x-KhUCqw4my8*`3Y=%i!N=J%-b>Fv8;^h*OpC#J%X z(Gt5x;R=YLplZ*aUS)ETLJEn&jCJa6rH*+t1do0>qG{{sK72*WT0bFbf4YldmLVQ< z?X*7fEXwJ2+vCt<#ERjXpx5Kz%>dS>mC&E$wpYLx3VsfKs3vQJQTRiCl1^uWidDE# zDb#l3Ic5^coY!6C)cq0D_|xuE+Y2eYc@|zV+f+bZSJR0PO6HUkH+B-(q223C@+chk zuXieUT6!99`u1($mX`}REfb@(GSh=uI%H=GuZ=p=yE|BwnM`+sb)=z1GIN)PT@Ym* z>$aw!rSV#6*q?+D9!u^i2Z8EzcB*sdm0!2rSLhCLk~h z+Vflwi66fm5i*no&r5Dg3{K&P&H)RSpgwC}v^|i^$eHX;w)2FfN3=S-KA9&cPgnBg z-hp2G&`DDnkp7Is<22natM)GQqn~_&-d{=cM8!(r$RB4?S0%pY?H0M@HdVnAR?>Ss z3I>IbX?~1zMrDkSr z3 zat8k7shkvBZ=7pBeGifNn!gI4Nq~YeT3!JT_(6?+wc=&C!DYuYk0_!EL2_ zR8=7w2=~NcRl3lnNT%Z-d+kT^Olj5zc(D_M3Hs2ysmHdXo5!NVWcAF8;;}3~d0sjN zyH&nY6(20+ILc7g8$+)S)H)jQ|wL_7#GaTxvF*bY)xptNA{E2@1%Y!$} zl)X|G4}4tp!f3#NgkINPe>bY`6U@bKbwM)4l3F)@A=1m;=5;({7F)joI^#B1fpy$u zO@%HwJE;W=yRJ&nCQ_^bUU5EFx7sp6Mrx3BMPY7}j=xLj z-pyr>OqQ4fM;h}%6;oH)0 z1n+kfo(-QZ9kvSQUIDhR0G&_NIxmT@0Mu7N!HfM1(j#?o+;FR#g?o8MApEe03{nFR zoIOZbxw*?;4p_LYOdV+=F4G_Wn(rxQSLJEU%!Gt3%Go?=vbW8(Z!|aoE7*64;Ny#z4jc>80!SH5NqsNY3bK# zJXgO65@4WQK%bl6mUEQXAw0X_rC2(JW~5cj%4BkF*U4v zU&isJ6KU|kh#4ur)XsvhJx5@d(_jyJtYg!KUU;quR(0mfc2ZTczZyG>5FTK?20M0( z_JqXMx#iiZuF=S+_BYCL{X$z&PT-DArumf$93u5Ev$v*b*Y3Vy#=Nr?+bSsaAEjfE zzvyiJ5ySP&RD5T#J+p50GWcw9TF@+oN$n0VzNs(#+ZYWe8Vx71(50mx+{wY}$FqS0R%tsh! z#{pkS>l1GQSAc@zrFidL%w^Cy8Np@Dedu4B<*j(>GmEpY1wp}T@D#Yp>1VYk`M=~Z z!H+o)ID0|y!bBVGpL_B_*Y`!)?f;uEHa9CtpGdm|g{KB@5BxZwxO(~d`=^o@yhmm9 z&gQRK3i#SVakp!+Tq-DHedhOLfD~WwqfqW+@X_xADV1DFY4@wcV%SngLSx85cLST? z$&^3AHgTV+V+TA`RV6AIe!SW`XoqsGd4#L>7~>C`MIt$Hmi zmSNvGlsO@b{2XbOCh?s3cqX=~xwCwBq3{l@lxMoQ20Yj^3t{KEw&uK4fn}--fAzs1 zF%E#aZ9hI)WWftYA+LbLeHb`sa;p(k6?d#0k$yN2YS`#5U0WhkNx9$2DDq)hunx=f zB-}`HNwaDq;QmGz!h{@NR7p=OA3+1t6i|=OPu{dq){A!-_)F}ix}#wc>0?UhkbIgx zUE)LKxnfw8dOc3BhRlIX|L`5)Z@i|$r_t=^QHOD{uKVL*)M97DZ7IhdtOSxX;dR=# zZC9?`U^lSKDz8UUkfV-@rDt6oG4=#E`+`|*41rnx1#9&CJdwf0c0AVoXNam2ey=5Bk^uKvDjss$5o zWxYXD_&%EUq_a$%b2nbZ&5dijvjbUJS?g2z`}qF8JCu;xHt^|wY(sC?hX@dycXdg5 zi4)uJBtLdJKpnvlrc@Z7guSB;0Vr5AsAkXwj-x7x=(y4DI3+_$o}_fo9k}-0#7b)e z>j$6IO^D*;RY=L)ZKC?h95=aKlYw4pOjDz+-c1C%{?g{h*I@#H?I5bT8al^%R|=M+lsE*5BYO>ap^tKK-&^pO$`3|Hq{^%vpl7|FOP(u< zBt5}bXZLhtzaP~6B7AVB)SB~|p2??zrzq)tpo}_KPIH82_&2r2w3F1< zw!AUru%O~QIN$>%U7*UvO8{aga&9bl8-)z0zS}E3GCy@CfvIW!>mSL7|C@SU{a?%v BgQWlf diff --git a/docs/site/images/logo.png b/docs/site/images/logo.png deleted file mode 100644 index c162d6ae18e1f433c5950aebc0fdbb36dbcd35b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7343 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 diff --git a/docs/site/images/redbutton.jpg b/docs/site/images/redbutton.jpg deleted file mode 100644 index 735f73040151f9924bd4432af7a6a45a89c7eac1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 577 zcmex=rI!if`Eg#tgYun8(AH7>mPkex%+ z$kZ{cux!f4%hw+Lzs0}u7+S&+e=;j+-PnE8d$C%!b#x;kAby}RPo>ZLu+TDLZ< z{n*~O((>~x35I(gyU!o_y>)YP^a0V1Ij71N9bhznUQz11t2z7%Y zLb~tj&S5A|D0g?6Tm9r;Lm`OOePe5F+SQ~p$7d9r(0reC_3Ny*SEYwNPOe-rnb)k} z;M9Dx7&XmMxy3xfN-fr*3~y|2F#Kn54A1H~crjG&q2$!yb;qw2?_5{*XYr=X9#iyG Qo@EAa&b;^ZtK$Eg0BT>LlmGw# diff --git a/docs/site/images/separator.jpg b/docs/site/images/separator.jpg deleted file mode 100644 index 6e6cbb8b49fc80774bd36a2d2bf7542531a51eb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 440 zcmex=``=7@3(_k>nUfm=Y%j1}zd*XLeuH%#2Jd ztRU@zj0}uSY)s4uIYz-iCZWWM3ojOKESmK2|1Aa{W=5bhm<1W^8Fop&ETUSASr#x*}|-^F7&=HD)KzAri{pjLI~lef(a7XRh(IS)8r#VHEZ9e zT+_ZPu7@`hr*l2LJ#ouyzk@N>HcC4SZr=#yJI(WMo_XJ)9c53#=F6{t5zcp> YR^6w#S?6UHW0mKfT6lZnn)?4Y0e-+`8UO$Q diff --git a/docs/site/images/title.png b/docs/site/images/title.png deleted file mode 100644 index e257bf20673385998fcd4c0bf4b8dabf0297ca6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3450 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 diff --git a/docs/site/images/user1.jpg b/docs/site/images/user1.jpg deleted file mode 100644 index 6373b77f6d8c13e00ceee6b5ba6d1f9752a061c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2184 zcmbuAXIRt87Ki^a5I_YCEfEMRAVp9CWra|zG${(9X(SRUq9h=Z5)A=Eks4S;SeGIi zkw6q7Nbe#@Kt+KhKuDx3MVc%{6j1Dgt{l(ftqU0K!R_IhG4xQhO!TITPZ ze*u3)p?{Lc{JzPl#;>TS z>MTXq6cwsbZL48cCzX0;tm8~QE9Yt)?hPA9LPEUVem zB<=eV2@P{$VU61-04e>pz8u$`;CSTNaF|(f+{v2?5=M2u4;xJPzJ~sx=VkaAJ`8pT z$wMsl8YJ``rzZ+RT?Yk+9SO=b8jT+4h#Ajsh&Efd53iN1{JB#l%o6n(iO}#y0*3*+Z(-Xv%(s#H?nlMI2&C}fNgs<_#q4LzZyotKDlsuzyf?e zrUrLHEmID`4!EF{cQwnaD$RR2G*`Sp{>2VUIb)pq9U%!T#b-C;X={@yo)}a_{f!owK?-tu;sX)qj z(CjVCn^wXleYgnK*w}^gB*!OF=U$SAN)s^4RtB8L6&s(<##0grgFi2eyB*#C+2YK$ z(Vge{Rtx@gwq8VuiRX3etdY+SBVARU6hx6xd!y~4n8~YkMdo!z#IL&v>k<4hcuB(u z%-VJZMSgljORIlwR1?zb*5dpS9_c{cwQl=GUVk9HDjdEO<~3T_op3nmH{AFhsSmX9 z9cV88W>Bf-b^W(_xjp1u&WB@*GMALaI$WR2TvXG#Kk8g>xP6N-g*newje+IcWeXEC zJ~D4O1u=c}9$C9pBpeudBh!#9d%r?{7NvFXVx;L&mMSsHQT;A9?UG0kVW&h_D0|U#Hv;TR96iRhw34elU6ju8luhxxY2R$f{Gp)U( z%`}TN)hslzF-SW4y*Yh&AGN)+to=jB=Ss!=;f_<2^z`Y=5c==INOH(UsdxMkbR?&R zyNK)-Bh!oTo?g;PMZi7xlihP>T`Kquib|J#{G!%F*getufsz^oeG~H182%x9A&}|V zUbBWt#4Jt2((EEqdR$6Vr;}C+Z)-xQ&Ppj!oKS!<-oB~_=v+^ub1oxU}X7eiMDGonRUkfRN)^M1j0|e}ucp^$g z);L;O`=NmpV7>upYhdQ#Gsxzw{8E2}$ry?!2b(4|1sqclcSgWif%_+YcwKhS zd45}CN$6gwumqG&GA^L}F#9Y1TGH;~S;VK#0fb7;!6#WqbSvi9x1BA*4DfE4gqM9= zFIN6yWrInp#$qM+4$JoJ6Q_kn7;DadzEpm2&F?1dyS*_jmXT8q71dRNulGvv2bR@?>pK^Ib*nv@B zGmRxlHnwh@?6p7&=^JO*LxK+XWDeW;c%*#U{!6t^kjQ^a0>$%-2x5Z&sPHv=`KD`6 zU{~7X<1iLsPy4R$Q>$M+oLP}bBqKk!l_VPbOrbXFi|z|rZ9!-HD+#&W5zK)KNb{tf zd8Gg@cra9uu>#Yn-!<{_9ta72C&ubQTJ=eeN>;DFFX$Ue46eWXwP`kjXmLEIkfYX0 zzerHbj#BTPjFA$uZezZ7_O`x)X^T_EkvPm>qa{7BoabPA6@<~9R6h=VF4{s1o$_&b z8q<`-i#&g*|6HgQH{67}w{53Vqb}r?4nbJXKwO2Dh+{sV9;%TkO_Lw9C5wyWknvaZ sY0>C&7|^R22@O;;77(I($mgW3&V16kzj&ShNyF*qr}zII$&J200cb3{Gynhq diff --git a/docs/site/index.html b/docs/site/index.html deleted file mode 100644 index f8f811ca..00000000 --- a/docs/site/index.html +++ /dev/null @@ -1,185 +0,0 @@ - - - - - Gunicorn - Python WSGI HTTP Server for UNIX - - - - - - - -

- - -
-
- -
- -
-

Installation

-

- Here's a quick rundown on how to get started with Gunicorn. For more details read the documentation. -

-
-  $ 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
-
-
-
-

Deployment

-

- Gunicorn is a WSGI HTTP server. It is best to use Gunicorn behind an HTTP proxy server. We strongly advise you to use nginx. -

-

Here's an example to help you get started with using nginx:

-
-  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;
-    }
-  }
-
-

Nginx is set up as reverse proxy server to a Gunicorn server running on localhost port 8000.

-

Read the full documentation at docs.gunicorn.org

-
-
-

Project Management

-

Gunicorn uses GitHub for the project management. GitHub issues are used for 3 different purposes:

- -

Project maintenance guidelines are available on the wiki

- -

IRC

-

The Gunicorn channel is on the Libera Chat IRC - network. You can chat with the community on the #gunicorn channel.

- -

Issue Tracking

-

Bug reports, enhancement requests and tasks generally go in the Github - issue tracker.

- -

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 security@gunicorn.org

- -
-
-

Documentation

-

You can read more comprehensive documentation at docs.gunicorn.org.

-

The contents are:

-
-
-
- - - - - - - - - diff --git a/docs/site/install.html b/docs/site/install.html deleted file mode 100644 index b3dfbd47..00000000 --- a/docs/site/install.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - Install - - -

- Redirecting to here -

- - diff --git a/docs/site/installation.html b/docs/site/installation.html deleted file mode 100644 index b3dfbd47..00000000 --- a/docs/site/installation.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - Install - - -

- Redirecting to here -

- - diff --git a/docs/site/js/main.js b/docs/site/js/main.js deleted file mode 100755 index c285c8fd..00000000 --- a/docs/site/js/main.js +++ /dev/null @@ -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); - } - } - } -}; \ No newline at end of file diff --git a/docs/site/news.html b/docs/site/news.html deleted file mode 100644 index 318dcdf2..00000000 --- a/docs/site/news.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - News - - -

- Redirecting to here -

- - diff --git a/docs/site/run.html b/docs/site/run.html deleted file mode 100644 index 236fc3e4..00000000 --- a/docs/site/run.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - Run - - -

- Redirecting to here -

- - diff --git a/docs/site/sitemap.xml b/docs/site/sitemap.xml deleted file mode 100644 index 6411a24e..00000000 --- a/docs/site/sitemap.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - http://gunicorn.org/ - 2019-11-27T00:02:48+01:00 - 1.0 - - - http://gunicorn.org/community.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/configuration.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/configure.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/deploy.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/deployment.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/design.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/faq.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/install.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/installation.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/news.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/run.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/tuning.html - 2012-10-04T00:43:15+05:45 - 0.5 - - - http://gunicorn.org/usage.html - 2012-10-04T00:43:15+05:45 - 0.5 - - diff --git a/docs/site/tuning.html b/docs/site/tuning.html deleted file mode 100644 index 5dbdc0b1..00000000 --- a/docs/site/tuning.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - FAQ - - -

- Redirecting to here -

- - diff --git a/docs/site/usage.html b/docs/site/usage.html deleted file mode 100644 index 236fc3e4..00000000 --- a/docs/site/usage.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Green Unicorn - Run - - -

- Redirecting to here -

- - diff --git a/docs/sitemap_gen.py b/docs/sitemap_gen.py deleted file mode 100644 index 29c7ca02..00000000 --- a/docs/sitemap_gen.py +++ /dev/null @@ -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() diff --git a/docs/source/2010-news.rst b/docs/source/2010-news.rst deleted file mode 100644 index e58c4819..00000000 --- a/docs/source/2010-news.rst +++ /dev/null @@ -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 `_ and - "egg:gunicorn#gevent_pywsgi" worker using `gevent.pywsgi - `_ . - **"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 - `_ -* Added an example gevent reloader configuration: - `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 `_ 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 diff --git a/docs/source/2011-news.rst b/docs/source/2011-news.rst deleted file mode 100644 index 3bc2a1a2..00000000 --- a/docs/source/2011-news.rst +++ /dev/null @@ -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 `_ -- 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/ diff --git a/docs/source/2012-news.rst b/docs/source/2012-news.rst deleted file mode 100644 index ce4f7cc4..00000000 --- a/docs/source/2012-news.rst +++ /dev/null @@ -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 `_ 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. diff --git a/docs/source/2013-news.rst b/docs/source/2013-news.rst deleted file mode 100644 index eb8cf556..00000000 --- a/docs/source/2013-news.rst +++ /dev/null @@ -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 ``.``. 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 diff --git a/docs/source/2014-news.rst b/docs/source/2014-news.rst deleted file mode 100644 index 3eec18fc..00000000 --- a/docs/source/2014-news.rst +++ /dev/null @@ -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 - `_. - 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 - `_ - 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 `_ -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 `. -- 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 diff --git a/docs/source/2015-news.rst b/docs/source/2015-news.rst deleted file mode 100644 index 61ea225b..00000000 --- a/docs/source/2015-news.rst +++ /dev/null @@ -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. diff --git a/docs/source/2016-news.rst b/docs/source/2016-news.rst deleted file mode 100644 index b7a4e66b..00000000 --- a/docs/source/2016-news.rst +++ /dev/null @@ -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`) diff --git a/docs/source/2017-news.rst b/docs/source/2017-news.rst deleted file mode 100644 index 0fb201e6..00000000 --- a/docs/source/2017-news.rst +++ /dev/null @@ -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 `_ 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 diff --git a/docs/source/2018-news.rst b/docs/source/2018-news.rst deleted file mode 100644 index 3b412cf5..00000000 --- a/docs/source/2018-news.rst +++ /dev/null @@ -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 `_ - (: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`) \ No newline at end of file diff --git a/docs/source/2019-news.rst b/docs/source/2019-news.rst deleted file mode 100644 index 28b69216..00000000 --- a/docs/source/2019-news.rst +++ /dev/null @@ -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 `_ -- 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 `_ 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 `_ 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 diff --git a/docs/source/2020-news.rst b/docs/source/2020-news.rst deleted file mode 100644 index 1d91ef7e..00000000 --- a/docs/source/2020-news.rst +++ /dev/null @@ -1,7 +0,0 @@ -================ -Changelog - 2020 -================ - -.. note:: - - Please see :doc:`news` for the latest changes diff --git a/docs/source/2021-news.rst b/docs/source/2021-news.rst deleted file mode 100644 index 3057600d..00000000 --- a/docs/source/2021-news.rst +++ /dev/null @@ -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 - diff --git a/docs/source/2023-news.rst b/docs/source/2023-news.rst deleted file mode 100644 index b685d80d..00000000 --- a/docs/source/2023-news.rst +++ /dev/null @@ -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. diff --git a/docs/source/2024-news.rst b/docs/source/2024-news.rst deleted file mode 100644 index 376699b4..00000000 --- a/docs/source/2024-news.rst +++ /dev/null @@ -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 diff --git a/docs/source/_static/gunicorn.png b/docs/source/_static/gunicorn.png deleted file mode 100644 index a3a78e0e8cc7d63e1cca0a03833185840320aa03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14398 zcmWk#1w5R696#N0I)~F8lhd5;?qQgz>6-4EIx*cbQ`6HnOfysCw9~_M^FFWpa6CTu z-2Z>iufFlbX=^IsVN+p)Kp;F7WvDI)gp>mOZj6Zz{DgZJ7Xwe|Z`72apy&S|MctKY zz!5ArWfM=}6$}4=BgwJl`T++qyi_z4FqW~22(jr0cyoaN(}Pr?vig2YM?wC9=63DR z*Zx!Lu=nYWEq|-`NXb!Ug&DXs-oiX#$avxOb{tt!;Dht&dP# zlY%Yhh->UWqtl%_JgMxOb`Oma(%9y?I%FMoRVmuSTt6ua81M?zKX_QEAV>1q7j?M) zc?jIF(DgO*gFC{Hm#6+%^D3L9wyVN~k4JLS#ZRS%sZseYrB#NYXMI?jK{H=YD7p`w1NTPtgoP5St6#M^U{fQmcJT;b;^s#`C*i(Grr`fA&`iGAxp`nE8%-e$Hwl2-w zjqFQ?owkQN+`Bhx_3cgQ;&Zs~kuXXz<6>>o*;0Ef4Y2tle&{J|iKNaCr=|VYW5MW` zkeZ&ICGnCA1=&#OPJU7dG4CZbFRD$HdHe~g!KhZbfEKhK@HKQ2prxnzI1h#DZ*4SCf-x8@$nndEb6EBY+L-X z`PkuWi-kuGB_$=TU;RkPxODnrmh*Fe17t=#PcsMN81kiz>3NZttCD2a;dxLu7AOlY zqraa5HmEMK`KYU($jS?xs2Egi>5#MYDQ(176&j4U{^psc=8uNv)j7n2Y=ozuuR~+z zq1etu52>i3fq(A;xHbY|H}85IX)kMq+;(aM4bqfS4*KPeho!jaNbM5*s6cPmM8qj> zbrdCDC%UQLgsVw)V2w>s5EXuA^n`SrNH@6L$6Iw#5he^;Bpx)Qy? zQ5^h;#_$?EobN44`j0z0IszM6?>JUlL~J-Yfxaj|O*hs=KvI?YMo^F`-B;{4Ka=L4 zjxLETQMF5~5)r)p&S$edn(@nYZS3QU@|j}{NUr#o*z`M+q%?8dBp3KsE}W#TJRZo& zg@_8C&V6WX7k|jpgQU-RM@Pr6U%%WWL%ThB85u@8iQ}L^7HNMRWspHs>d+6mAgfb# zSIl&Z)K{>WZkmNx@dff}oI^m@qyiSHk-7&TfuwrJe&YJ>-Me3=yq^SUzxZE@3X>%~ z25HeYMMtAgn^r=hq%dOBLx-cIBUg-8(LHea|FR%>TFKL{L?_alm%2jZJ zNWkCf?qf`v-jY6Uz7vc$<|0GUzVOei#Jb&S^nE=2>Z0|6ueK$my=|RYvwT)5g1yHc zB1jcQ66Sjn%YX=9Qg|utC*%0D@TB9Q&Pp*IyjvI|WxgP3=@ewl-!FT%e|2?r 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 - -GitHub issues are used for 3 different purposes: - - * `Bug tracker `_ : To check for latest bugs. Tip: See existing issues before opening a new one! - * `Forum `_ : Stackoverflow-style questions about Gunicorn usage. - * `Other Issues `_ : Discussion of Gunicorn development, new features - and project management. - -IRC -=== - -The Gunicorn channel is on the `Libera Chat `_ IRC -network. You can chat with others on `#gunicorn channel -`_ - -Issue Tracking -============== - -Bug reports, enhancement requests and tasks generally go in the `Github -issue tracker `_ - -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 `_ diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index f000c2db..00000000 --- a/docs/source/conf.py +++ /dev/null @@ -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'), -] diff --git a/docs/source/configure.rst b/docs/source/configure.rst deleted file mode 100644 index dc9ba62d..00000000 --- a/docs/source/configure.rst +++ /dev/null @@ -1,118 +0,0 @@ -.. _configuration: - -====================== -Configuration Overview -====================== - -Gunicorn reads configuration information from five places. - -Gunicorn first reads environment variables for some configuration -:ref:`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 `. - -.. _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 ` 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. diff --git a/docs/source/custom.rst b/docs/source/custom.rst deleted file mode 100644 index 90f74209..00000000 --- a/docs/source/custom.rst +++ /dev/null @@ -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 diff --git a/docs/source/deploy.rst b/docs/source/deploy.rst deleted file mode 100644 index 5f868979..00000000 --- a/docs/source/deploy.rst +++ /dev/null @@ -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 diff --git a/docs/source/design.rst b/docs/source/design.rst deleted file mode 100644 index 6796e969..00000000 --- a/docs/source/design.rst +++ /dev/null @@ -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 `_. - -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/ diff --git a/docs/source/faq.rst b/docs/source/faq.rst deleted file mode 100644 index 8c52a486..00000000 --- a/docs/source/faq.rst +++ /dev/null @@ -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 -`_ 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. diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index 6c3d51f6..00000000 --- a/docs/source/index.rst +++ /dev/null @@ -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 diff --git a/docs/source/install.rst b/docs/source/install.rst deleted file mode 100644 index eb3e9aba..00000000 --- a/docs/source/install.rst +++ /dev/null @@ -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/ diff --git a/docs/source/instrumentation.rst b/docs/source/instrumentation.rst deleted file mode 100644 index 60cde416..00000000 --- a/docs/source/instrumentation.rst +++ /dev/null @@ -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 diff --git a/docs/source/news.rst b/docs/source/news.rst deleted file mode 100644 index 2a61fafe..00000000 --- a/docs/source/news.rst +++ /dev/null @@ -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 - diff --git a/docs/source/run.rst b/docs/source/run.rst deleted file mode 100644 index 108956b8..00000000 --- a/docs/source/run.rst +++ /dev/null @@ -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 `. - -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 `_ 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 `_ -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 diff --git a/docs/source/settings.rst b/docs/source/settings.rst deleted file mode 100644 index 04677061..00000000 --- a/docs/source/settings.rst +++ /dev/null @@ -1,1795 +0,0 @@ -.. 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 - -Config File ------------ - -.. _config: - -``config`` -~~~~~~~~~~ - -**Command line:** ``-c CONFIG`` or ``--config CONFIG`` - -**Default:** ``'./gunicorn.conf.py'`` - -:ref:`The Gunicorn config file`. - -A string of the form ``PATH``, ``file:PATH``, or ``python:MODULE_NAME``. - -Only has an effect when specified on the command line or as part of an -application specific configuration. - -By default, a file named ``gunicorn.conf.py`` will be read from the same -directory where gunicorn is being run. - -.. versionchanged:: 19.4 - Loading the config from a Python module requires the ``python:`` - prefix. - -.. _wsgi-app: - -``wsgi_app`` -~~~~~~~~~~~~ - -**Default:** ``None`` - -A WSGI application path in pattern ``$(MODULE_NAME):$(VARIABLE_NAME)``. - -.. versionadded:: 20.1.0 - -Debugging ---------- - -.. _reload: - -``reload`` -~~~~~~~~~~ - -**Command line:** ``--reload`` - -**Default:** ``False`` - -Restart workers when code changes. - -This setting is intended for development. It will cause workers to be -restarted whenever application code changes. - -The reloader is incompatible with application preloading. When using a -paste configuration be sure that the server block does not import any -application code or the reload will not work as designed. - -The default behavior is to attempt inotify with a fallback to file -system polling. Generally, inotify should be preferred if available -because it consumes less system resources. - -.. note:: - In order to use the inotify reloader, you must have the ``inotify`` - package installed. - -.. _reload-engine: - -``reload_engine`` -~~~~~~~~~~~~~~~~~ - -**Command line:** ``--reload-engine STRING`` - -**Default:** ``'auto'`` - -The implementation that should be used to power :ref:`reload`. - -Valid engines are: - -* ``'auto'`` -* ``'poll'`` -* ``'inotify'`` (requires inotify) - -.. versionadded:: 19.7 - -.. _reload-extra-files: - -``reload_extra_files`` -~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--reload-extra-file FILES`` - -**Default:** ``[]`` - -Extends :ref:`reload` option to also watch and reload on additional files -(e.g., templates, configurations, specifications, etc.). - -.. versionadded:: 19.8 - -.. _spew: - -``spew`` -~~~~~~~~ - -**Command line:** ``--spew`` - -**Default:** ``False`` - -Install a trace function that spews every line executed by the server. - -This is the nuclear option. - -.. _check-config: - -``check_config`` -~~~~~~~~~~~~~~~~ - -**Command line:** ``--check-config`` - -**Default:** ``False`` - -Check the configuration and exit. The exit status is 0 if the -configuration is correct, and 1 if the configuration is incorrect. - -.. _print-config: - -``print_config`` -~~~~~~~~~~~~~~~~ - -**Command line:** ``--print-config`` - -**Default:** ``False`` - -Print the configuration settings as fully resolved. Implies :ref:`check-config`. - -Logging -------- - -.. _accesslog: - -``accesslog`` -~~~~~~~~~~~~~ - -**Command line:** ``--access-logfile FILE`` - -**Default:** ``None`` - -The Access log file to write to. - -``'-'`` means log to stdout. - -.. _disable-redirect-access-to-syslog: - -``disable_redirect_access_to_syslog`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--disable-redirect-access-to-syslog`` - -**Default:** ``False`` - -Disable redirect access logs to syslog. - -.. versionadded:: 19.8 - -.. _access-log-format: - -``access_log_format`` -~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--access-logformat STRING`` - -**Default:** ``'%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'`` - -The access log format. - -=========== =========== -Identifier Description -=========== =========== -h remote address -l ``'-'`` -u user name (if HTTP Basic auth used) -t date of the request -r status line (e.g. ``GET / HTTP/1.1``) -m request method -U URL path without query string -q query string -H protocol -s status -B response length -b response length or ``'-'`` (CLF format) -f referrer (note: header is ``referer``) -a user agent -T request time in seconds -M request time in milliseconds -D request time in microseconds -L request time in decimal seconds -p process ID -{header}i request header -{header}o response header -{variable}e environment variable -=========== =========== - -Use lowercase for header and environment variable names, and put -``{...}x`` names inside ``%(...)s``. For example:: - - %({x-forwarded-for}i)s - -.. _errorlog: - -``errorlog`` -~~~~~~~~~~~~ - -**Command line:** ``--error-logfile FILE`` or ``--log-file FILE`` - -**Default:** ``'-'`` - -The Error log file to write to. - -Using ``'-'`` for FILE makes gunicorn log to stderr. - -.. versionchanged:: 19.2 - Log to stderr by default. - -.. _loglevel: - -``loglevel`` -~~~~~~~~~~~~ - -**Command line:** ``--log-level LEVEL`` - -**Default:** ``'info'`` - -The granularity of Error log outputs. - -Valid level names are: - -* ``'debug'`` -* ``'info'`` -* ``'warning'`` -* ``'error'`` -* ``'critical'`` - -.. _capture-output: - -``capture_output`` -~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--capture-output`` - -**Default:** ``False`` - -Redirect stdout/stderr to specified file in :ref:`errorlog`. - -.. versionadded:: 19.6 - -.. _logger-class: - -``logger_class`` -~~~~~~~~~~~~~~~~ - -**Command line:** ``--logger-class STRING`` - -**Default:** ``'gunicorn.glogging.Logger'`` - -The logger you want to use to log events in Gunicorn. - -The default class (``gunicorn.glogging.Logger``) handles most -normal usages in logging. It provides error and access logging. - -You can provide your own logger by giving Gunicorn a Python path to a -class that quacks like ``gunicorn.glogging.Logger``. - -.. _logconfig: - -``logconfig`` -~~~~~~~~~~~~~ - -**Command line:** ``--log-config FILE`` - -**Default:** ``None`` - -The log config file to use. -Gunicorn uses the standard Python logging module's Configuration -file format. - -.. _logconfig-dict: - -``logconfig_dict`` -~~~~~~~~~~~~~~~~~~ - -**Default:** ``{}`` - -The log config dictionary to use, using the standard Python -logging module's dictionary configuration format. This option -takes precedence over the :ref:`logconfig` and :ref:`logconfig-json` options, -which uses the older file configuration format and JSON -respectively. - -Format: https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig - -For more context you can look at the default configuration dictionary for logging, -which can be found at ``gunicorn.glogging.CONFIG_DEFAULTS``. - -.. versionadded:: 19.8 - -.. _logconfig-json: - -``logconfig_json`` -~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--log-config-json FILE`` - -**Default:** ``None`` - -The log config to read config from a JSON file - -Format: https://docs.python.org/3/library/logging.config.html#logging.config.jsonConfig - -.. versionadded:: 20.0 - -.. _syslog-addr: - -``syslog_addr`` -~~~~~~~~~~~~~~~ - -**Command line:** ``--log-syslog-to SYSLOG_ADDR`` - -**Default:** ``'unix:///var/run/syslog'`` - -Address to send syslog messages. - -Address is a string of the form: - -* ``unix://PATH#TYPE`` : for unix domain socket. ``TYPE`` can be ``stream`` - for the stream driver or ``dgram`` for the dgram driver. - ``stream`` is the default. -* ``udp://HOST:PORT`` : for UDP sockets -* ``tcp://HOST:PORT`` : for TCP sockets - -.. _syslog: - -``syslog`` -~~~~~~~~~~ - -**Command line:** ``--log-syslog`` - -**Default:** ``False`` - -Send *Gunicorn* logs to syslog. - -.. versionchanged:: 19.8 - You can now disable sending access logs by using the - :ref:`disable-redirect-access-to-syslog` setting. - -.. _syslog-prefix: - -``syslog_prefix`` -~~~~~~~~~~~~~~~~~ - -**Command line:** ``--log-syslog-prefix SYSLOG_PREFIX`` - -**Default:** ``None`` - -Makes Gunicorn use the parameter as program-name in the syslog entries. - -All entries will be prefixed by ``gunicorn.``. By default the -program name is the name of the process. - -.. _syslog-facility: - -``syslog_facility`` -~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--log-syslog-facility SYSLOG_FACILITY`` - -**Default:** ``'user'`` - -Syslog facility name - -.. _enable-stdio-inheritance: - -``enable_stdio_inheritance`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``-R`` or ``--enable-stdio-inheritance`` - -**Default:** ``False`` - -Enable stdio inheritance. - -Enable inheritance for stdio file descriptors in daemon mode. - -Note: To disable the Python stdout buffering, you can to set the user -environment variable ``PYTHONUNBUFFERED`` . - -.. _statsd-host: - -``statsd_host`` -~~~~~~~~~~~~~~~ - -**Command line:** ``--statsd-host STATSD_ADDR`` - -**Default:** ``None`` - -The address of the StatsD server to log to. - -Address is a string of the form: - -* ``unix://PATH`` : for a unix domain socket. -* ``HOST:PORT`` : for a network address - -.. versionadded:: 19.1 - -.. _dogstatsd-tags: - -``dogstatsd_tags`` -~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--dogstatsd-tags DOGSTATSD_TAGS`` - -**Default:** ``''`` - -A comma-delimited list of datadog statsd (dogstatsd) tags to append to -statsd metrics. - -.. versionadded:: 20 - -.. _statsd-prefix: - -``statsd_prefix`` -~~~~~~~~~~~~~~~~~ - -**Command line:** ``--statsd-prefix STATSD_PREFIX`` - -**Default:** ``''`` - -Prefix to use when emitting statsd metrics (a trailing ``.`` is added, -if not provided). - -.. versionadded:: 19.2 - -Process Naming --------------- - -.. _proc-name: - -``proc_name`` -~~~~~~~~~~~~~ - -**Command line:** ``-n STRING`` or ``--name STRING`` - -**Default:** ``None`` - -A base to use with setproctitle for process naming. - -This affects things like ``ps`` and ``top``. If you're going to be -running more than one instance of Gunicorn you'll probably want to set a -name to tell them apart. This requires that you install the setproctitle -module. - -If not set, the *default_proc_name* setting will be used. - -.. _default-proc-name: - -``default_proc_name`` -~~~~~~~~~~~~~~~~~~~~~ - -**Default:** ``'gunicorn'`` - -Internal setting that is adjusted for each type of application. - -SSL ---- - -.. _keyfile: - -``keyfile`` -~~~~~~~~~~~ - -**Command line:** ``--keyfile FILE`` - -**Default:** ``None`` - -SSL key file - -.. _certfile: - -``certfile`` -~~~~~~~~~~~~ - -**Command line:** ``--certfile FILE`` - -**Default:** ``None`` - -SSL certificate file - -.. _ssl-version: - -``ssl_version`` -~~~~~~~~~~~~~~~ - -**Command line:** ``--ssl-version`` - -**Default:** ``<_SSLMethod.PROTOCOL_TLS: 2>`` - -SSL version to use (see stdlib ssl module's). - -.. deprecated:: 21.0 - The option is deprecated and it is currently ignored. Use :ref:`ssl-context` instead. - -============= ============ ---ssl-version Description -============= ============ -SSLv3 SSLv3 is not-secure and is strongly discouraged. -SSLv23 Alias for TLS. Deprecated in Python 3.6, use TLS. -TLS Negotiate highest possible version between client/server. - Can yield SSL. (Python 3.6+) -TLSv1 TLS 1.0 -TLSv1_1 TLS 1.1 (Python 3.4+) -TLSv1_2 TLS 1.2 (Python 3.4+) -TLS_SERVER Auto-negotiate the highest protocol version like TLS, - but only support server-side SSLSocket connections. - (Python 3.6+) -============= ============ - -.. versionchanged:: 19.7 - The default value has been changed from ``ssl.PROTOCOL_TLSv1`` to - ``ssl.PROTOCOL_SSLv23``. -.. versionchanged:: 20.0 - This setting now accepts string names based on ``ssl.PROTOCOL_`` - constants. -.. versionchanged:: 20.0.1 - The default value has been changed from ``ssl.PROTOCOL_SSLv23`` to - ``ssl.PROTOCOL_TLS`` when Python >= 3.6 . - -.. _cert-reqs: - -``cert_reqs`` -~~~~~~~~~~~~~ - -**Command line:** ``--cert-reqs`` - -**Default:** ```` - -Whether client certificate is required (see stdlib ssl module's) - -=========== =========================== ---cert-reqs Description -=========== =========================== -`0` no client verification -`1` ssl.CERT_OPTIONAL -`2` ssl.CERT_REQUIRED -=========== =========================== - -.. _ca-certs: - -``ca_certs`` -~~~~~~~~~~~~ - -**Command line:** ``--ca-certs FILE`` - -**Default:** ``None`` - -CA certificates file - -.. _suppress-ragged-eofs: - -``suppress_ragged_eofs`` -~~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--suppress-ragged-eofs`` - -**Default:** ``True`` - -Suppress ragged EOFs (see stdlib ssl module's) - -.. _do-handshake-on-connect: - -``do_handshake_on_connect`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--do-handshake-on-connect`` - -**Default:** ``False`` - -Whether to perform SSL handshake on socket connect (see stdlib ssl module's) - -.. _ciphers: - -``ciphers`` -~~~~~~~~~~~ - -**Command line:** ``--ciphers`` - -**Default:** ``None`` - -SSL Cipher suite to use, in the format of an OpenSSL cipher list. - -By default we use the default cipher list from Python's ``ssl`` module, -which contains ciphers considered strong at the time of each Python -release. - -As a recommended alternative, the Open Web App Security Project (OWASP) -offers `a vetted set of strong cipher strings rated A+ to C- -`_. -OWASP provides details on user-agent compatibility at each security level. - -See the `OpenSSL Cipher List Format Documentation -`_ -for details on the format of an OpenSSL cipher list. - -Security --------- - -.. _limit-request-line: - -``limit_request_line`` -~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--limit-request-line INT`` - -**Default:** ``4094`` - -The maximum size of HTTP request line in bytes. - -This parameter is used to limit the allowed size of a client's -HTTP request-line. Since the request-line consists of the HTTP -method, URI, and protocol version, this directive places a -restriction on the length of a request-URI allowed for a request -on the server. A server needs this value to be large enough to -hold any of its resource names, including any information that -might be passed in the query part of a GET request. Value is a number -from 0 (unlimited) to 8190. - -This parameter can be used to prevent any DDOS attack. - -.. _limit-request-fields: - -``limit_request_fields`` -~~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--limit-request-fields INT`` - -**Default:** ``100`` - -Limit the number of HTTP headers fields in a request. - -This parameter is used to limit the number of headers in a request to -prevent DDOS attack. Used with the *limit_request_field_size* it allows -more safety. By default this value is 100 and can't be larger than -32768. - -.. _limit-request-field-size: - -``limit_request_field_size`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--limit-request-field_size INT`` - -**Default:** ``8190`` - -Limit the allowed size of an HTTP request header field. - -Value is a positive number or 0. Setting it to 0 will allow unlimited -header field sizes. - -.. warning:: - Setting this parameter to a very high or unlimited value can open - up for DDOS attacks. - -Server Hooks ------------- - -.. _on-starting: - -``on_starting`` -~~~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def on_starting(server): - pass - -Called just before the master process is initialized. - -The callable needs to accept a single instance variable for the Arbiter. - -.. _on-reload: - -``on_reload`` -~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def on_reload(server): - pass - -Called to recycle workers during a reload via SIGHUP. - -The callable needs to accept a single instance variable for the Arbiter. - -.. _when-ready: - -``when_ready`` -~~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def when_ready(server): - pass - -Called just after the server is started. - -The callable needs to accept a single instance variable for the Arbiter. - -.. _pre-fork: - -``pre_fork`` -~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def pre_fork(server, worker): - pass - -Called just before a worker is forked. - -The callable needs to accept two instance variables for the Arbiter and -new Worker. - -.. _post-fork: - -``post_fork`` -~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def post_fork(server, worker): - pass - -Called just after a worker has been forked. - -The callable needs to accept two instance variables for the Arbiter and -new Worker. - -.. _post-worker-init: - -``post_worker_init`` -~~~~~~~~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def post_worker_init(worker): - pass - -Called just after a worker has initialized the application. - -The callable needs to accept one instance variable for the initialized -Worker. - -.. _worker-int: - -``worker_int`` -~~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def worker_int(worker): - pass - -Called just after a worker exited on SIGINT or SIGQUIT. - -The callable needs to accept one instance variable for the initialized -Worker. - -.. _worker-abort: - -``worker_abort`` -~~~~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def worker_abort(worker): - pass - -Called when a worker received the SIGABRT signal. - -This call generally happens on timeout. - -The callable needs to accept one instance variable for the initialized -Worker. - -.. _pre-exec: - -``pre_exec`` -~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def pre_exec(server): - pass - -Called just before a new master process is forked. - -The callable needs to accept a single instance variable for the Arbiter. - -.. _pre-request: - -``pre_request`` -~~~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def pre_request(worker, req): - worker.log.debug("%s %s", req.method, req.path) - -Called just before a worker processes the request. - -The callable needs to accept two instance variables for the Worker and -the Request. - -.. _post-request: - -``post_request`` -~~~~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def post_request(worker, req, environ, resp): - pass - -Called after a worker processes the request. - -The callable needs to accept two instance variables for the Worker and -the Request. - -.. _child-exit: - -``child_exit`` -~~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def child_exit(server, worker): - pass - -Called just after a worker has been exited, in the master process. - -The callable needs to accept two instance variables for the Arbiter and -the just-exited Worker. - -.. versionadded:: 19.7 - -.. _worker-exit: - -``worker_exit`` -~~~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def worker_exit(server, worker): - pass - -Called just after a worker has been exited, in the worker process. - -The callable needs to accept two instance variables for the Arbiter and -the just-exited Worker. - -.. _nworkers-changed: - -``nworkers_changed`` -~~~~~~~~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def nworkers_changed(server, new_value, old_value): - pass - -Called just after *num_workers* has been changed. - -The callable needs to accept an instance variable of the Arbiter and -two integers of number of workers after and before change. - -If the number of workers is set for the first time, *old_value* would -be ``None``. - -.. _on-exit: - -``on_exit`` -~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def on_exit(server): - pass - -Called just before exiting Gunicorn. - -The callable needs to accept a single instance variable for the Arbiter. - -.. _ssl-context: - -``ssl_context`` -~~~~~~~~~~~~~~~ - -**Default:** - -.. code-block:: python - - def ssl_context(config, default_ssl_context_factory): - return default_ssl_context_factory() - -Called when SSLContext is needed. - -Allows customizing SSL context. - -The callable needs to accept an instance variable for the Config and -a factory function that returns default SSLContext which is initialized -with certificates, private key, cert_reqs, and ciphers according to -config and can be further customized by the callable. -The callable needs to return SSLContext object. - -Following example shows a configuration file that sets the minimum TLS version to 1.3: - -.. code-block:: python - - def ssl_context(conf, default_ssl_context_factory): - import ssl - context = default_ssl_context_factory() - context.minimum_version = ssl.TLSVersion.TLSv1_3 - return context - -.. versionadded:: 21.0 - -Server Mechanics ----------------- - -.. _preload-app: - -``preload_app`` -~~~~~~~~~~~~~~~ - -**Command line:** ``--preload`` - -**Default:** ``False`` - -Load application code before the worker processes are forked. - -By preloading an application you can save some RAM resources as well as -speed up server boot times. Although, if you defer application loading -to each worker process, you can reload your application code easily by -restarting workers. - -.. _sendfile: - -``sendfile`` -~~~~~~~~~~~~ - -**Command line:** ``--no-sendfile`` - -**Default:** ``None`` - -Disables the use of ``sendfile()``. - -If not set, the value of the ``SENDFILE`` environment variable is used -to enable or disable its usage. - -.. versionadded:: 19.2 -.. versionchanged:: 19.4 - Swapped ``--sendfile`` with ``--no-sendfile`` to actually allow - disabling. -.. versionchanged:: 19.6 - added support for the ``SENDFILE`` environment variable - -.. _reuse-port: - -``reuse_port`` -~~~~~~~~~~~~~~ - -**Command line:** ``--reuse-port`` - -**Default:** ``False`` - -Set the ``SO_REUSEPORT`` flag on the listening socket. - -.. versionadded:: 19.8 - -.. _chdir: - -``chdir`` -~~~~~~~~~ - -**Command line:** ``--chdir`` - -**Default:** ``'.'`` - -Change directory to specified directory before loading apps. - -.. _daemon: - -``daemon`` -~~~~~~~~~~ - -**Command line:** ``-D`` or ``--daemon`` - -**Default:** ``False`` - -Daemonize the Gunicorn process. - -Detaches the server from the controlling terminal and enters the -background. - -.. _raw-env: - -``raw_env`` -~~~~~~~~~~~ - -**Command line:** ``-e ENV`` or ``--env ENV`` - -**Default:** ``[]`` - -Set environment variables in the execution environment. - -Should be a list of strings in the ``key=value`` format. - -For example on the command line: - -.. code-block:: console - - $ gunicorn -b 127.0.0.1:8000 --env FOO=1 test:app - -Or in the configuration file: - -.. code-block:: python - - raw_env = ["FOO=1"] - -.. _pidfile: - -``pidfile`` -~~~~~~~~~~~ - -**Command line:** ``-p FILE`` or ``--pid FILE`` - -**Default:** ``None`` - -A filename to use for the PID file. - -If not set, no PID file will be written. - -.. _worker-tmp-dir: - -``worker_tmp_dir`` -~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--worker-tmp-dir DIR`` - -**Default:** ``None`` - -A directory to use for the worker heartbeat temporary file. - -If not set, the default temporary directory will be used. - -.. note:: - 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. - - See :ref:`blocking-os-fchmod` for more detailed information - and a solution for avoiding this problem. - -.. _user: - -``user`` -~~~~~~~~ - -**Command line:** ``-u USER`` or ``--user USER`` - -**Default:** ``os.geteuid()`` - -Switch worker processes to run as this user. - -A valid user id (as an integer) or the name of a user that can be -retrieved with a call to ``pwd.getpwnam(value)`` or ``None`` to not -change the worker process user. - -.. _group: - -``group`` -~~~~~~~~~ - -**Command line:** ``-g GROUP`` or ``--group GROUP`` - -**Default:** ``os.getegid()`` - -Switch worker process to run as this group. - -A valid group id (as an integer) or the name of a user that can be -retrieved with a call to ``grp.getgrnam(value)`` or ``None`` to not -change the worker processes group. - -.. _umask: - -``umask`` -~~~~~~~~~ - -**Command line:** ``-m INT`` or ``--umask INT`` - -**Default:** ``0`` - -A bit mask for the file mode on files written by Gunicorn. - -Note that this affects unix socket permissions. - -A valid value for the ``os.umask(mode)`` call or a string compatible -with ``int(value, 0)`` (``0`` means Python guesses the base, so values -like ``0``, ``0xFF``, ``0022`` are valid for decimal, hex, and octal -representations) - -.. _initgroups: - -``initgroups`` -~~~~~~~~~~~~~~ - -**Command line:** ``--initgroups`` - -**Default:** ``False`` - -If true, set the worker process's group access list with all of the -groups of which the specified username is a member, plus the specified -group id. - -.. versionadded:: 19.7 - -.. _tmp-upload-dir: - -``tmp_upload_dir`` -~~~~~~~~~~~~~~~~~~ - -**Default:** ``None`` - -Directory to store temporary request data as they are read. - -This may disappear in the near future. - -This path should be writable by the process permissions set for Gunicorn -workers. If not specified, Gunicorn will choose a system generated -temporary directory. - -.. _secure-scheme-headers: - -``secure_scheme_headers`` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Default:** ``{'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}`` - -A dictionary containing headers and values that the front-end proxy -uses to indicate HTTPS requests. If the source IP is permitted by -:ref:`forwarded-allow-ips` (below), *and* at least one request header matches -a key-value pair listed in this dictionary, then Gunicorn will set -``wsgi.url_scheme`` to ``https``, so your application can tell that the -request is secure. - -If the other headers listed in this dictionary are not present in the request, they will be ignored, -but if the other headers are present and do not match the provided values, then -the request will fail to parse. See the note below for more detailed examples of this behaviour. - -The dictionary should map upper-case header names to exact string -values. The value comparisons are case-sensitive, unlike the header -names, so make sure they're exactly what your front-end proxy sends -when handling HTTPS requests. - -It is important that your front-end proxy configuration ensures that -the headers defined here can not be passed directly from the client. - -.. _forwarded-allow-ips: - -``forwarded_allow_ips`` -~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--forwarded-allow-ips STRING`` - -**Default:** ``'127.0.0.1,::1'`` - -Front-end's IPs from which allowed to handle set secure headers. -(comma separated). - -Set to ``*`` to disable checking of front-end IPs. This is useful for setups -where you don't know in advance the IP address of front-end, but -instead have ensured via other means that only your -authorized front-ends can access Gunicorn. - -By default, the value of the ``FORWARDED_ALLOW_IPS`` environment -variable. If it is not defined, the default is ``"127.0.0.1,::1"``. - -.. note:: - - This option does not affect UNIX socket connections. Connections not associated with - an IP address are treated as allowed, unconditionally. - -.. note:: - - The interplay between the request headers, the value of ``forwarded_allow_ips``, and the value of - ``secure_scheme_headers`` is complex. Various scenarios are documented below to further elaborate. - In each case, we have a request from the remote address 134.213.44.18, and the default value of - ``secure_scheme_headers``: - - .. code:: - - secure_scheme_headers = { - 'X-FORWARDED-PROTOCOL': 'ssl', - 'X-FORWARDED-PROTO': 'https', - 'X-FORWARDED-SSL': 'on' - } - - - .. list-table:: - :header-rows: 1 - :align: center - :widths: auto - - * - ``forwarded-allow-ips`` - - Secure Request Headers - - Result - - Explanation - * - .. code:: - - ["127.0.0.1"] - - .. code:: - - X-Forwarded-Proto: https - - .. code:: - - wsgi.url_scheme = "http" - - IP address was not allowed - * - .. code:: - - "*" - - - - .. code:: - - wsgi.url_scheme = "http" - - IP address allowed, but no secure headers provided - * - .. code:: - - "*" - - .. code:: - - X-Forwarded-Proto: https - - .. code:: - - wsgi.url_scheme = "https" - - IP address allowed, one request header matched - * - .. code:: - - ["134.213.44.18"] - - .. code:: - - X-Forwarded-Ssl: on - X-Forwarded-Proto: http - - ``InvalidSchemeHeaders()`` raised - - IP address allowed, but the two secure headers disagreed on if HTTPS was used - -.. _pythonpath: - -``pythonpath`` -~~~~~~~~~~~~~~ - -**Command line:** ``--pythonpath STRING`` - -**Default:** ``None`` - -A comma-separated list of directories to add to the Python path. - -e.g. -``'/home/djangoprojects/myproject,/home/python/mylibrary'``. - -.. _paste: - -``paste`` -~~~~~~~~~ - -**Command line:** ``--paste STRING`` or ``--paster STRING`` - -**Default:** ``None`` - -Load a PasteDeploy config file. The argument may contain a ``#`` -symbol followed by the name of an app section from the config file, -e.g. ``production.ini#admin``. - -At this time, using alternate server blocks is not supported. Use the -command line arguments to control server configuration instead. - -.. _proxy-protocol: - -``proxy_protocol`` -~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--proxy-protocol`` - -**Default:** ``False`` - -Enable detect PROXY protocol (PROXY mode). - -Allow using HTTP and Proxy together. It may be useful for work with -stunnel as HTTPS frontend and Gunicorn as HTTP server. - -PROXY protocol: http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt - -Example for stunnel config:: - - [https] - protocol = proxy - accept = 443 - connect = 80 - cert = /etc/ssl/certs/stunnel.pem - key = /etc/ssl/certs/stunnel.key - -.. _proxy-allow-ips: - -``proxy_allow_ips`` -~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--proxy-allow-from`` - -**Default:** ``'127.0.0.1,::1'`` - -Front-end's IPs from which allowed accept proxy requests (comma separated). - -Set to ``*`` to disable checking of front-end IPs. This is useful for setups -where you don't know in advance the IP address of front-end, but -instead have ensured via other means that only your -authorized front-ends can access Gunicorn. - -.. note:: - - This option does not affect UNIX socket connections. Connections not associated with - an IP address are treated as allowed, unconditionally. - -.. _raw-paste-global-conf: - -``raw_paste_global_conf`` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--paste-global CONF`` - -**Default:** ``[]`` - -Set a PasteDeploy global config variable in ``key=value`` form. - -The option can be specified multiple times. - -The variables are passed to the PasteDeploy entrypoint. Example:: - - $ gunicorn -b 127.0.0.1:8000 --paste development.ini --paste-global FOO=1 --paste-global BAR=2 - -.. versionadded:: 19.7 - -.. _permit-obsolete-folding: - -``permit_obsolete_folding`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--permit-obsolete-folding`` - -**Default:** ``False`` - -Permit requests employing obsolete HTTP line folding mechanism - -The folding mechanism was deprecated by rfc7230 Section 3.2.4 and will not be - employed in HTTP request headers from standards-compliant HTTP clients. - -This option is provided to diagnose backwards-incompatible changes. -Use with care and only if necessary. Temporary; the precise effect of this option may -change in a future version, or it may be removed altogether. - -.. versionadded:: 23.0.0 - -.. _strip-header-spaces: - -``strip_header_spaces`` -~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--strip-header-spaces`` - -**Default:** ``False`` - -Strip spaces present between the header name and the the ``:``. - -This is known to induce vulnerabilities and is not compliant with the HTTP/1.1 standard. -See https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn. - -Use with care and only if necessary. Deprecated; scheduled for removal in 25.0.0 - -.. versionadded:: 20.0.1 - -.. _permit-unconventional-http-method: - -``permit_unconventional_http_method`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--permit-unconventional-http-method`` - -**Default:** ``False`` - -Permit HTTP methods not matching conventions, such as IANA registration guidelines - -This permits request methods of length less than 3 or more than 20, -methods with lowercase characters or methods containing the # character. -HTTP methods are case sensitive by definition, and merely uppercase by convention. - -If unset, Gunicorn will apply nonstandard restrictions and cause 400 response status -in cases where otherwise 501 status is expected. While this option does modify that -behaviour, it should not be depended upon to guarantee standards-compliant behaviour. -Rather, it is provided temporarily, to assist in diagnosing backwards-incompatible -changes around the incomplete application of those restrictions. - -Use with care and only if necessary. Temporary; scheduled for removal in 24.0.0 - -.. versionadded:: 22.0.0 - -.. _permit-unconventional-http-version: - -``permit_unconventional_http_version`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--permit-unconventional-http-version`` - -**Default:** ``False`` - -Permit HTTP version not matching conventions of 2023 - -This disables the refusal of likely malformed request lines. -It is unusual to specify HTTP 1 versions other than 1.0 and 1.1. - -This option is provided to diagnose backwards-incompatible changes. -Use with care and only if necessary. Temporary; the precise effect of this option may -change in a future version, or it may be removed altogether. - -.. versionadded:: 22.0.0 - -.. _casefold-http-method: - -``casefold_http_method`` -~~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--casefold-http-method`` - -**Default:** ``False`` - -Transform received HTTP methods to uppercase - -HTTP methods are case sensitive by definition, and merely uppercase by convention. - -This option is provided because previous versions of gunicorn defaulted to this behaviour. - -Use with care and only if necessary. Deprecated; scheduled for removal in 24.0.0 - -.. versionadded:: 22.0.0 - -.. _forwarder-headers: - -``forwarder_headers`` -~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--forwarder-headers`` - -**Default:** ``'SCRIPT_NAME,PATH_INFO'`` - -A list containing upper-case header field names that the front-end proxy -(see :ref:`forwarded-allow-ips`) sets, to be used in WSGI environment. - -This option has no effect for headers not present in the request. - -This option can be used to transfer ``SCRIPT_NAME``, ``PATH_INFO`` -and ``REMOTE_USER``. - -It is important that your front-end proxy configuration ensures that -the headers defined here can not be passed directly from the client. - -.. _header-map: - -``header_map`` -~~~~~~~~~~~~~~ - -**Command line:** ``--header-map`` - -**Default:** ``'drop'`` - -Configure how header field names are mapped into environ - -Headers containing underscores are permitted by RFC9110, -but gunicorn joining headers of different names into -the same environment variable will dangerously confuse applications as to which is which. - -The safe default ``drop`` is to silently drop headers that cannot be unambiguously mapped. -The value ``refuse`` will return an error if a request contains *any* such header. -The value ``dangerous`` matches the previous, not advisable, behaviour of mapping different -header field names into the same environ name. - -If the source is permitted as explained in :ref:`forwarded-allow-ips`, *and* the header name is -present in :ref:`forwarder-headers`, the header is mapped into environment regardless of -the state of this setting. - -Use with care and only if necessary and after considering if your problem could -instead be solved by specifically renaming or rewriting only the intended headers -on a proxy in front of Gunicorn. - -.. versionadded:: 22.0.0 - -Server Socket -------------- - -.. _bind: - -``bind`` -~~~~~~~~ - -**Command line:** ``-b ADDRESS`` or ``--bind ADDRESS`` - -**Default:** ``['127.0.0.1:8000']`` - -The socket to bind. - -A string of the form: ``HOST``, ``HOST:PORT``, ``unix:PATH``, -``fd://FD``. An IP is a valid ``HOST``. - -.. versionchanged:: 20.0 - Support for ``fd://FD`` got added. - -Multiple addresses can be bound. ex.:: - - $ gunicorn -b 127.0.0.1:8000 -b [::1]:8000 test:app - -will bind the `test:app` application on localhost both on ipv6 -and ipv4 interfaces. - -If the ``PORT`` environment variable is defined, the default -is ``['0.0.0.0:$PORT']``. If it is not defined, the default -is ``['127.0.0.1:8000']``. - -.. _backlog: - -``backlog`` -~~~~~~~~~~~ - -**Command line:** ``--backlog INT`` - -**Default:** ``2048`` - -The maximum number of pending connections. - -This refers to the number of clients that can be waiting to be served. -Exceeding this number results in the client getting an error when -attempting to connect. It should only affect servers under significant -load. - -Must be a positive integer. Generally set in the 64-2048 range. - -Worker Processes ----------------- - -.. _workers: - -``workers`` -~~~~~~~~~~~ - -**Command line:** ``-w INT`` or ``--workers INT`` - -**Default:** ``1`` - -The number of worker processes for handling requests. - -A positive integer generally in the ``2-4 x $(NUM_CORES)`` range. -You'll want to vary this a bit to find the best for your particular -application's work load. - -By default, the value of the ``WEB_CONCURRENCY`` environment variable, -which is set by some Platform-as-a-Service providers such as Heroku. If -it is not defined, the default is ``1``. - -.. _worker-class: - -``worker_class`` -~~~~~~~~~~~~~~~~ - -**Command line:** ``-k STRING`` or ``--worker-class STRING`` - -**Default:** ``'sync'`` - -The type of workers to use. - -The default class (``sync``) should handle most "normal" types of -workloads. You'll want to read :doc:`design` for information on when -you might want to choose one of the other worker classes. Required -libraries may be installed using setuptools' ``extras_require`` feature. - -A string referring to one of the following bundled classes: - -* ``sync`` -* ``eventlet`` - Requires eventlet >= 0.24.1 (or install it via - ``pip install gunicorn[eventlet]``) -* ``gevent`` - Requires gevent >= 1.4 (or install it via - ``pip install gunicorn[gevent]``) -* ``tornado`` - Requires tornado >= 0.2 (or install it via - ``pip install gunicorn[tornado]``) -* ``gthread`` - Python 2 requires the futures package to be installed - (or install it via ``pip install gunicorn[gthread]``) - -Optionally, you can provide your own worker by giving Gunicorn a -Python path to a subclass of ``gunicorn.workers.base.Worker``. -This alternative syntax will load the gevent class: -``gunicorn.workers.ggevent.GeventWorker``. - -.. _threads: - -``threads`` -~~~~~~~~~~~ - -**Command line:** ``--threads INT`` - -**Default:** ``1`` - -The number of worker threads for handling requests. - -Run each worker with the specified number of threads. - -A positive integer generally in the ``2-4 x $(NUM_CORES)`` range. -You'll want to vary this a bit to find the best for your particular -application's work load. - -If it is not defined, the default is ``1``. - -This setting only affects the Gthread worker type. - -.. note:: - If you try to use the ``sync`` worker type and set the ``threads`` - setting to more than 1, the ``gthread`` worker type will be used - instead. - -.. _worker-connections: - -``worker_connections`` -~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--worker-connections INT`` - -**Default:** ``1000`` - -The maximum number of simultaneous clients. - -This setting only affects the ``gthread``, ``eventlet`` and ``gevent`` worker types. - -.. _max-requests: - -``max_requests`` -~~~~~~~~~~~~~~~~ - -**Command line:** ``--max-requests INT`` - -**Default:** ``0`` - -The maximum number of requests a worker will process before restarting. - -Any value greater than zero will limit the number of requests a worker -will process before automatically restarting. This is a simple method -to help limit the damage of memory leaks. - -If this is set to zero (the default) then the automatic worker -restarts are disabled. - -.. _max-requests-jitter: - -``max_requests_jitter`` -~~~~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--max-requests-jitter INT`` - -**Default:** ``0`` - -The maximum jitter to add to the *max_requests* setting. - -The jitter causes the restart per worker to be randomized by -``randint(0, max_requests_jitter)``. This is intended to stagger worker -restarts to avoid all workers restarting at the same time. - -.. versionadded:: 19.2 - -.. _timeout: - -``timeout`` -~~~~~~~~~~~ - -**Command line:** ``-t INT`` or ``--timeout INT`` - -**Default:** ``30`` - -Workers silent for more than this many seconds are killed and restarted. - -Value is a positive number or 0. Setting it to 0 has the effect of -infinite timeouts by disabling timeouts for all workers entirely. - -Generally, the default of thirty seconds should suffice. Only set this -noticeably higher if you're sure of the repercussions for sync workers. -For the non sync workers it just means that the worker process is still -communicating and is not tied to the length of time required to handle a -single request. - -.. _graceful-timeout: - -``graceful_timeout`` -~~~~~~~~~~~~~~~~~~~~ - -**Command line:** ``--graceful-timeout INT`` - -**Default:** ``30`` - -Timeout for graceful workers restart in seconds. - -After receiving a restart signal, workers have this much time to finish -serving requests. Workers still alive after the timeout (starting from -the receipt of the restart signal) are force killed. - -.. _keepalive: - -``keepalive`` -~~~~~~~~~~~~~ - -**Command line:** ``--keep-alive INT`` - -**Default:** ``2`` - -The number of seconds to wait for requests on a Keep-Alive connection. - -Generally set in the 1-5 seconds range for servers with direct connection -to the client (e.g. when you don't have separate load balancer). When -Gunicorn is deployed behind a load balancer, it often makes sense to -set this to a higher value. - -.. note:: - ``sync`` worker does not support persistent connections and will - ignore this option. - diff --git a/docs/source/signals.rst b/docs/source/signals.rst deleted file mode 100644 index c22ea036..00000000 --- a/docs/source/signals.rst +++ /dev/null @@ -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 ``.pid.oldbin`` to - ``.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] diff --git a/gunicorn/__init__.py b/gunicorn/__init__.py index cdcd1352..347557ce 100644 --- a/gunicorn/__init__.py +++ b/gunicorn/__init__.py @@ -2,7 +2,7 @@ # This file is part of gunicorn released under the MIT license. # 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]) SERVER = "gunicorn" SERVER_SOFTWARE = "%s/%s" % (SERVER, __version__)