summaryrefslogtreecommitdiff
path: root/README.rst
diff options
context:
space:
mode:
Diffstat (limited to 'README.rst')
-rw-r--r--README.rst189
1 files changed, 189 insertions, 0 deletions
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..332443f
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,189 @@
+Introduction
+------------
+
+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 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/
+