diff options
author | Chris McDonough <chrism@plope.com> | 2011-12-28 10:13:29 -0500 |
---|---|---|
committer | Chris McDonough <chrism@plope.com> | 2011-12-28 10:13:29 -0500 |
commit | 777dd41644bbb5c318f5ccb928f2603c1947e39f (patch) | |
tree | 27087955925d8723ecacc24daabd5f533e22c939 | |
parent | fec87bdc035b98a4fe7b42473fb83ba5e14a823f (diff) | |
download | waitress-777dd41644bbb5c318f5ccb928f2603c1947e39f.tar.gz |
add docs
-rw-r--r-- | README.rst | 180 | ||||
-rw-r--r-- | docs/.gitignore | 4 | ||||
-rw-r--r-- | docs/Makefile | 86 | ||||
-rw-r--r-- | docs/api.rst | 10 | ||||
-rw-r--r-- | docs/conf.py | 215 | ||||
-rw-r--r-- | docs/glossary.rst | 12 | ||||
-rw-r--r-- | docs/index.rst | 197 |
7 files changed, 524 insertions, 180 deletions
@@ -7,183 +7,3 @@ in the Python standard library. It runs on CPython on Unix and Windows under Python 2.6+ and Python 3.2. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1. -Usage ------ - -Here's normal usage of the server:: - - from waitress import serve - serve(wsgiapp, host='0.0.0.0', port=8080) - -If you want to serve your application on all IP addresses, on port 8080, you -can omit the ``host`` and ``port`` arguments and just call ``serve`` with the -WSGI app as a single argument:: - - from waitress import serve - serve(wsgiapp) - -Press Ctrl-C to exit the server. - -There's an entry point for PasteDeploy_ (``egg:waitress#main``) that lets you -use waitress's WSGI gateway from a configuration file, e.g.:: - - [server:main] - use = egg:waitress#main - host = 127.0.0.1 - port = 8080 - -Using Behind a Reverse Proxy ----------------------------- - -If you're using Waitress behind a reverse proxy, you'll almost always want -your reverse proxy to pass along the ``Host`` header sent by the client to -Waitress, in either case, as it will be used by most applications to generate -correct URLs. - -For example, when using Nginx as a reverse proxy, you might add the following -lines in a ``location`` section:: - - proxy_set_header Host $host; - -The Apache directive named ``ProxyPreserveHost`` does something similar when -used as a reverse proxy. - -Unfortunately, even if you pass the ``Host`` header, the Host header does not -contain enough information to regenerate the original URL sent by the client. -For example, if your reverse proxy accepts HTTPS requests (and therefore URLs -which start with ``https://``), the URLs generated by your application when -used behind a reverse proxy served by waitress might inappropriately be -``http://foo`` rather than ``https://foo``. To fix this, you'll want to -change the ``wsgi.url_scheme`` in the WSGI environment before it reaches your -application. You can do this in one of two ways: - -1. You can pass a ``url_scheme`` configuration variable to the - ``waitress.serve`` function. - -2. You can use Paste's ``PrefixMiddleware`` in conjunction with - configuration settings on the reverse proxy server. - -Using ``url_scheme`` to set ``wsgi.url_scheme`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can have the waitress server use the ``https`` url scheme by default. - - from waitress import serve - serve(wsgiapp, host='0.0.0.0', port=8080, url_scheme='https') - -This works if all URLs generated by your application should use the ``https`` -scheme. - -Using Paste's ``PrefixMiddleware`` to set ``wsgi.url_scheme`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If only some of the URLs generated by your application should use the -``https`` scheme (and some should use ``http``), you'll need to use Paste's -``PrefixMiddleware`` as well as change some configuration settings on your -proxy. To use ``PrefixMiddleware``, wrap your application before serving it -using waitress:: - - from waitress import serve - from paste.deploy.config import PrefixMiddleware - app = PrefixMiddleware(app) - serve(app) - -Once you wrap your application in the the ``PrefixMiddleware``, the -middleware will notice certain headers sent from your proxy and will change -the ``wsgi.url_scheme`` and possibly other WSGI environment variables -appropriately. - -Once your application is wrapped by the prefix middleware, you should -instruct your proxy server to send along the original ``Host`` header from -the client to your waitress server, as well as sending along a -``X-Forwarded-Proto`` header with the appropriate value for -``wsgi.url_scheme``. - -If your proxy accepts both HTTP and HTTPS URLs, and you want your application -to generate the appropriate url based on the incoming scheme, also set up -your proxy to send a ``X-Forwarded-Proto`` with the original URL scheme along -with each proxied request. For example, when using Nginx:: - - proxy_set_header X-Forwarded-Proto $scheme; - -It's permitted to set an ``X-Forwarded-For`` header too; the -``PrefixMiddleware`` uses this to adjust other environment variables (you'll -have to read its docs to find out which ones, I don't know what they are). For -the ``X-Forwarded-For`` header:: - - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - -Note that you can wrap your application in the PrefixMiddleware declaratively -in a PasteDeploy_ configuration file too, if your web framework uses -PasteDeploy-style configuration:: - - [app:myapp] - use = egg:mypackage#myapp - - [filter:paste_prefix] - use = egg:PasteDeploy#prefix - - [pipeline:main] - pipeline = - paste_prefix - myapp - - [server:main] - use = egg:waitress#main - host = 127.0.0.1 - port = 8080 - -Why? ----- - -At the time of the release of Waitress, there are already many pure-Python -WSGI servers. Why would we need another? - -Waitress is meant to be useful to web framework authors who require broad -platform support. It's neither the fastest nor the fanciest WSGI server -available but using it helps eliminate the N-by-M documentation burden -(e.g. production vs. deployment, Windows vs. Unix, Python 3 vs. Python 2, -PyPy vs. CPython) and resulting user confusion imposed by spotty platform -support of the current (2012-ish) crop of WSGI servers. For example, -``gunicorn`` is great, but doesn't run on Windows. ``paste.httpserver`` is -perfectly serviceable, but doesn't run under Python 3 and has no dedicated -tests suite that would allow someone who did a Python 3 port to know it -worked after a port was completed. ``wsgiref`` works fine under most any -Python, but it's a little slow and it's not recommended for production use as -it has not been audited for security issues. - -At the time of this writing, some existing WSGI servers already claim wide -platform support and have serviceable test suites. The CherryPy WSGI server, -for example, targets Python 2 and Python 3 and it can run on UNIX or Windows. -However, it is not distributed separately from its eponymous web framework, -and requiring a non-CherryPy web framework to depend on the CherryPy web -framework distribution simply for its server component is awkward. The test -suite of the CherryPy server also depends on the CherryPy web framework, so -even if we forked its server component into a separate distribution, we would -have still needed to backfill for all of its tests. - -Finally, I wanted the control that is provided by maintaining my own server. -A WSGI server is an important dependency of my web framework, and being able -to make arbitrary changes (add features, fix bugs, etc) without anyone else's -permission is nice. - -Waitress is a fork of the WSGI-related components which existed in -``zope.server``. ``zope.server`` had passable framework-independent test -coverage out of the box, and a good bit more coverage was added during the -fork. ``zope.server`` has existed in one form or another since about 2001, -and has seen production usage since then, so Waitress is not exactly -"another" server, it's more a repackaging of an old one that was already -known to work fairly well. - -Known Issues ------------- - -- Does not support the ``wsgi.file_wrapper`` protocol. - -- Does not do transfer-encoding: chunked responses (although handles chunked - requests fine). - -- Does not yet support IPv6. - -.. _PasteDeploy: http://pythonpaste.org/deploy/ - diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..da7abd0 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,4 @@ +_themes +_build + + diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..b265770 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,86 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html web pickle htmlhelp latex changes linkcheck + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " pickle to make pickle files (usable by e.g. sphinx-web)" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " changes to make an overview over all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + +clean: + -rm -rf _build/* + +html: + mkdir -p _build/html _build/doctrees + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html + @echo + @echo "Build finished. The HTML pages are in _build/html." + +text: + mkdir -p _build/text _build/doctrees + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) _build/text + @echo + @echo "Build finished. The HTML pages are in _build/text." + +pickle: + mkdir -p _build/pickle _build/doctrees + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle + @echo + @echo "Build finished; now you can process the pickle files or run" + @echo " sphinx-web _build/pickle" + @echo "to start the sphinx-web server." + +web: pickle + +htmlhelp: + mkdir -p _build/htmlhelp _build/doctrees + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in _build/htmlhelp." + +latex: + mkdir -p _build/latex _build/doctrees + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex + cp _static/*.png _build/latex + ./convert_images.sh + cp _static/latex-warning.png _build/latex + cp _static/latex-note.png _build/latex + @echo + @echo "Build finished; the LaTeX files are in _build/latex." + @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ + "run these through (pdf)latex." + +changes: + mkdir -p _build/changes _build/doctrees + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes + @echo + @echo "The overview file is in _build/changes." + +linkcheck: + mkdir -p _build/linkcheck _build/doctrees + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in _build/linkcheck/output.txt." + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) _build/epub + @echo + @echo "Build finished. The epub file is in _build/epub." + diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..f889752 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,10 @@ +.. _waitress_api: + +:mod:`waitress` API +--------------------------- + +.. automodule:: waitress + +.. autofunction:: serve + + diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..593c6f5 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- +# +# waitress documentation build configuration file +# +# This file is execfile()d with the current directory set to its containing +# dir. +# +# The contents of this file are pickled, so don't put values in the +# namespace that aren't pickleable (module imports are okay, they're +# removed automatically). +# +# All configuration values have a default value; values that are commented +# out serve to show the default value. + +# If your extensions are in another directory, add it here. If the +# directory is relative to the documentation root, use os.path.abspath to +# make it absolute, like shown here. +#sys.path.append(os.path.abspath('some/directory')) + +import sys, os + +# Add and use Pylons theme +if 'sphinx-build' in ' '.join(sys.argv): # protect against dumb importers + from subprocess import call, Popen, PIPE + + p = Popen('which git', shell=True, stdout=PIPE) + git = p.stdout.read().strip() + cwd = os.getcwd() + _themes = os.path.join(cwd, '_themes') + + if not os.path.isdir(_themes): + call([git, 'clone', 'git://github.com/Pylons/pylons_sphinx_theme.git', + '_themes']) + else: + os.chdir(_themes) + call([git, 'checkout', 'master']) + call([git, 'pull']) + os.chdir(cwd) + + sys.path.append(os.path.abspath('_themes')) + +# General configuration +# --------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [ + 'sphinx.ext.autodoc', + ] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General substitutions. +project = 'waitress' +copyright = '2012, Agendaless Consulting <chrism@plope.com>' + +# The default replacements for |version| and |release|, also used in various +# other places throughout the built documents. +# +# The short X.Y version. +version = '0.0' +# The full version, including alpha/beta/rc tags. +release = version + +# There are two options for replacing |today|: either, you set today to +# some non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +today_fmt = '%B %d, %Y' + +# List of documents that shouldn't be included in the build. +#unused_docs = [] + +# List of directories, relative to source directories, that shouldn't be +# searched for source files. +#exclude_dirs = [] +exclude_patterns = ['_themes/README.rst',] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True +add_module_names = False + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# Options for HTML output +# ----------------------- + +# Add and use Pylons theme +sys.path.append(os.path.abspath('_themes')) +html_theme_path = ['_themes'] +html_theme = 'pylons' +html_theme_options = dict(github_url='http://github.com/Pylons/waitress') + +# The style sheet to use for HTML and HTML Help pages. A file of that name +# must exist either in Sphinx' static/ path, or in one of the custom paths +# given in html_static_path. +# html_style = 'repoze.css' + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as +# html_title. +#html_short_title = None + +# The name of an image file (within the static path) to place at the top of +# the sidebar. +# html_logo = '.static/logo_hi.gif' + +# The name of an image file (within the static path) to use as favicon of +# the docs. This file should be a Windows icon file (.ico) being 16x16 or +# 32x32 pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) +# here, relative to this directory. They are copied after the builtin +# static files, so a file named "default.css" will overwrite the builtin +# "default.css". +#html_static_path = ['.static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page +# bottom, using the given strftime format. +html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_use_modindex = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, the reST sources are included in the HTML build as +# _sources/<name>. +#html_copy_source = True + +# If true, an OpenSearch description file will be output, and all pages +# will contain a <link> tag referring to it. The value of this option must +# be the base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = '' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'atemplatedoc' + + +# Options for LaTeX output +# ------------------------ + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, document class [howto/manual]). +latex_documents = [ + ('index', 'waitress.tex', 'waitress Documentation', + 'Pylons Developers', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the +# top of the title page. +latex_logo = '.static/logo_hi.gif' + +# For "manual" documents, if this is true, then toplevel headings are +# parts, not chapters. +#latex_use_parts = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_use_modindex = True diff --git a/docs/glossary.rst b/docs/glossary.rst new file mode 100644 index 0000000..ac17a19 --- /dev/null +++ b/docs/glossary.rst @@ -0,0 +1,12 @@ +.. _glossary: + +Glossary +======== + +.. glossary:: + :sorted: + + PasteDeploy + A system for configuration of WSGI web components in declarative + ``.ini`` format. See http://pythonpaste.org/deploy/. + diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..930c308 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,197 @@ +Waitress +-------- + +Waitress is meant to be a production-quality pure-Python WSGI server with +very acceptable performance. It has no dependencies except ones which live +in the Python standard library. It runs on CPython on Unix and Windows under +Python 2.6+ and Python 3.2. It is also known to run on PyPy 1.6.0 on UNIX. +It supports HTTP/1.0 and HTTP/1.1. + +Usage +----- + +Here's normal usage of the server:: + + from waitress import serve + serve(wsgiapp, host='0.0.0.0', port=8080) + +If you want to serve your application on all IP addresses, on port 8080, you +can omit the ``host`` and ``port`` arguments and just call ``serve`` with the +WSGI app as a single argument:: + + from waitress import serve + serve(wsgiapp) + +Press Ctrl-C to exit the server. + +There's an entry point for :term:`PasteDeploy` (``egg:waitress#main``) that +lets you use waitress's WSGI gateway from a configuration file, e.g.:: + + [server:main] + use = egg:waitress#main + host = 127.0.0.1 + port = 8080 + +Using Behind a Reverse Proxy +---------------------------- + +If you're using Waitress behind a reverse proxy, you'll almost always want +your reverse proxy to pass along the ``Host`` header sent by the client to +Waitress, in either case, as it will be used by most applications to generate +correct URLs. + +For example, when using Nginx as a reverse proxy, you might add the following +lines in a ``location`` section:: + + proxy_set_header Host $host; + +The Apache directive named ``ProxyPreserveHost`` does something similar when +used as a reverse proxy. + +Unfortunately, even if you pass the ``Host`` header, the Host header does not +contain enough information to regenerate the original URL sent by the client. +For example, if your reverse proxy accepts HTTPS requests (and therefore URLs +which start with ``https://``), the URLs generated by your application when +used behind a reverse proxy served by waitress might inappropriately be +``http://foo`` rather than ``https://foo``. To fix this, you'll want to +change the ``wsgi.url_scheme`` in the WSGI environment before it reaches your +application. You can do this in one of two ways: + +1. You can pass a ``url_scheme`` configuration variable to the + ``waitress.serve`` function. + +2. You can use Paste's ``PrefixMiddleware`` in conjunction with + configuration settings on the reverse proxy server. + +Using ``url_scheme`` to set ``wsgi.url_scheme`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can have the waitress server use the ``https`` url scheme by default.:: + + from waitress import serve + serve(wsgiapp, host='0.0.0.0', port=8080, url_scheme='https') + +This works if all URLs generated by your application should use the ``https`` +scheme. + +Using Paste's ``PrefixMiddleware`` to set ``wsgi.url_scheme`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If only some of the URLs generated by your application should use the +``https`` scheme (and some should use ``http``), you'll need to use Paste's +``PrefixMiddleware`` as well as change some configuration settings on your +proxy. To use ``PrefixMiddleware``, wrap your application before serving it +using waitress:: + + from waitress import serve + from paste.deploy.config import PrefixMiddleware + app = PrefixMiddleware(app) + serve(app) + +Once you wrap your application in the the ``PrefixMiddleware``, the +middleware will notice certain headers sent from your proxy and will change +the ``wsgi.url_scheme`` and possibly other WSGI environment variables +appropriately. + +Once your application is wrapped by the prefix middleware, you should +instruct your proxy server to send along the original ``Host`` header from +the client to your waitress server, as well as sending along a +``X-Forwarded-Proto`` header with the appropriate value for +``wsgi.url_scheme``. + +If your proxy accepts both HTTP and HTTPS URLs, and you want your application +to generate the appropriate url based on the incoming scheme, also set up +your proxy to send a ``X-Forwarded-Proto`` with the original URL scheme along +with each proxied request. For example, when using Nginx:: + + proxy_set_header X-Forwarded-Proto $scheme; + +It's permitted to set an ``X-Forwarded-For`` header too; the +``PrefixMiddleware`` uses this to adjust other environment variables (you'll +have to read its docs to find out which ones, I don't know what they are). For +the ``X-Forwarded-For`` header:: + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + +Note that you can wrap your application in the PrefixMiddleware declaratively +in a :term:`PasteDeploy` configuration file too, if your web framework uses +PasteDeploy-style configuration:: + + [app:myapp] + use = egg:mypackage#myapp + + [filter:paste_prefix] + use = egg:PasteDeploy#prefix + + [pipeline:main] + pipeline = + paste_prefix + myapp + + [server:main] + use = egg:waitress#main + host = 127.0.0.1 + port = 8080 + +Why? +---- + +At the time of the release of Waitress, there are already many pure-Python +WSGI servers. Why would we need another? + +Waitress is meant to be useful to web framework authors who require broad +platform support. It's neither the fastest nor the fanciest WSGI server +available but using it helps eliminate the N-by-M documentation burden +(e.g. production vs. deployment, Windows vs. Unix, Python 3 vs. Python 2, +PyPy vs. CPython) and resulting user confusion imposed by spotty platform +support of the current (2012-ish) crop of WSGI servers. For example, +``gunicorn`` is great, but doesn't run on Windows. ``paste.httpserver`` is +perfectly serviceable, but doesn't run under Python 3 and has no dedicated +tests suite that would allow someone who did a Python 3 port to know it +worked after a port was completed. ``wsgiref`` works fine under most any +Python, but it's a little slow and it's not recommended for production use as +it has not been audited for security issues. + +At the time of this writing, some existing WSGI servers already claim wide +platform support and have serviceable test suites. The CherryPy WSGI server, +for example, targets Python 2 and Python 3 and it can run on UNIX or Windows. +However, it is not distributed separately from its eponymous web framework, +and requiring a non-CherryPy web framework to depend on the CherryPy web +framework distribution simply for its server component is awkward. The test +suite of the CherryPy server also depends on the CherryPy web framework, so +even if we forked its server component into a separate distribution, we would +have still needed to backfill for all of its tests. + +Finally, I wanted the control that is provided by maintaining my own server. +A WSGI server is an important dependency of my web framework, and being able +to make arbitrary changes (add features, fix bugs, etc) without anyone else's +permission is nice. + +Waitress is a fork of the WSGI-related components which existed in +``zope.server``. ``zope.server`` had passable framework-independent test +coverage out of the box, and a good bit more coverage was added during the +fork. ``zope.server`` has existed in one form or another since about 2001, +and has seen production usage since then, so Waitress is not exactly +"another" server, it's more a repackaging of an old one that was already +known to work fairly well. + +Known Issues +------------ + +- Does not support the ``wsgi.file_wrapper`` protocol. + +- Does not do transfer-encoding: chunked responses (although handles chunked + requests fine). + +- Does not yet support IPv6. + +More +---- + +.. toctree:: + :maxdepth: 1 + + api.rst + glossary.rst + + |