Skip to content

Commit

Permalink
Merge branch 'master' of github.com:mitsuhiko/flask
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Apr 9, 2012
2 parents ab110d8 + f071990 commit 3249eeb
Show file tree
Hide file tree
Showing 32 changed files with 616 additions and 249 deletions.
16 changes: 15 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Version 0.9

Relase date to be decided, codename to be chosen.

- The :func:`flask.Request.on_json_loading_failed` now returns a JSON formatted
response by default.
- The :func:`flask.url_for` function now can generate anchors to the
generated links.
- The :func:`flask.url_for` function now can also explicitly generate
Expand Down Expand Up @@ -48,7 +50,19 @@ Relase date to be decided, codename to be chosen.
- Added :meth:`flask.Flask.app_context` which works very similar to the
request context but only provides access to the current application. This
also adds support for URL generation without an active request context.

- View functions can now return a tuple with the first instance being an
instance of :class:`flask.Response`. This allows for returning
``jsonify(error="error msg"), 400`` from a view function.
- :class:`flask.Flask` now provides a `get_send_file_options` hook for
subclasses to override behavior of serving static files from Flask when using
:meth:`flask.Flask.send_static_file` based on keywords in
:func:`flask.helpers.send_file`. This hook is provided a filename, which for
example allows changing cache controls by file extension. The default
max-age for `send_static_file` can be configured through a new
``SEND_FILE_MAX_AGE_DEFAULT`` configuration variable, regardless of whether
the `get_send_file_options` hook is used.
- Fixed an assumption in sessions implementation which could break message
flashing on sessions implementations which use external storage.

Version 0.8.1
-------------
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2010 by Armin Ronacher and contributors. See AUTHORS
Copyright (c) 2012 by Armin Ronacher and contributors. See AUTHORS
for more details.

Some rights reserved.
Expand Down
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ clean-pyc:
find . -name '*.pyo' -exec rm -f {} +
find . -name '*~' -exec rm -f {} +

# ebook-convert docs: http://manual.calibre-ebook.com/cli/ebook-convert.html
upload-docs:
$(MAKE) -C docs html dirhtml latex epub
$(MAKE) -C docs/_build/latex all-pdf
Expand All @@ -31,7 +30,10 @@ upload-docs:
rsync -a docs/_build/latex/Flask.pdf pocoo.org:/var/www/flask.pocoo.org/docs/flask-docs.pdf
rsync -a docs/_build/flask-docs.zip pocoo.org:/var/www/flask.pocoo.org/docs/flask-docs.zip
rsync -a docs/_build/epub/Flask.epub pocoo.org:/var/www/flask.pocoo.org/docs/flask-docs.epub
@echo 'Building .mobi from .epub...'

# ebook-convert docs: http://manual.calibre-ebook.com/cli/ebook-convert.html
ebook:
@echo 'Using .epub from `make upload-docs` to create .mobi.'
@echo 'Command `ebook-covert` is provided by calibre package.'
@echo 'Requires X-forwarding for Qt features used in conversion (ssh -X).'
@echo 'Do not mind "Invalid value for ..." CSS errors if .mobi renders.'
Expand Down
67 changes: 67 additions & 0 deletions docs/advanced_foreword.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
Foreword for Experienced Programmers
====================================

This chapter is for programmers who have worked with other frameworks in the
past, and who may have more specific or esoteric concerns that the typical
user.

Threads in Flask
----------------

One of the design decisions with Flask was that simple tasks should be simple;
they should not take a lot of code and yet they should not limit you. Because
of that we made a few design choices that some people might find surprising or
unorthodox. For example, Flask uses thread-local objects internally so that
you don’t have to pass objects around from function to function within a
request in order to stay threadsafe. While this is a really easy approach and
saves you a lot of time, it might also cause some troubles for very large
applications because changes on these thread-local objects can happen anywhere
in the same thread. In order to solve these problems we don’t hide the thread
locals for you but instead embrace them and provide you with a lot of tools to
make it as pleasant as possible to work with them.

Web Development is Dangerous
----------------------------

If you write a web application, you are probably allowing users to register
and leave their data on your server. The users are entrusting you with data.
And even if you are the only user that might leave data in your application,
you still want that data to be stored securely.

Unfortunately, there are many ways the security of a web application can be
compromised. Flask protects you against one of the most common security
problems of modern web applications: cross-site scripting (XSS). Unless
you deliberately mark insecure HTML as secure, Flask and the underlying
Jinja2 template engine have you covered. But there are many more ways to
cause security problems.

The documentation will warn you about aspects of web development that
require attention to security. Some of these security concerns
are far more complex than one might think, and we all sometimes underestimate
the likelihood that a vulnerability will be exploited - until a clever
attacker figures out a way to exploit our applications. And don't think
that your application is not important enough to attract an attacker.
Depending on the kind of attack, chances are that automated bots are
probing for ways to fill your database with spam, links to malicious
software, and the like.

So always keep security in mind when doing web development.

The Status of Python 3
----------------------

Currently the Python community is in the process of improving libraries to
support the new iteration of the Python programming language. While the
situation is greatly improving there are still some issues that make it
hard for us to switch over to Python 3 just now. These problems are
partially caused by changes in the language that went unreviewed for too
long, partially also because we have not quite worked out how the lower-
level API should change to account for the Unicode differences in Python 3.

Werkzeug and Flask will be ported to Python 3 as soon as a solution for
the changes is found, and we will provide helpful tips how to upgrade
existing applications to Python 3. Until then, we strongly recommend
using Python 2.6 and 2.7 with activated Python 3 warnings during
development. If you plan on upgrading to Python 3 in the near future we
strongly recommend that you read `How to write forwards compatible
Python code <http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/>`_.
2 changes: 1 addition & 1 deletion docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ Variable parts are passed to the view function as keyword arguments.
The following converters are available:

=========== ===============================================
`unicode` accepts any text without a slash (the default)
`string` accepts any text without a slash (the default)
`int` accepts integers
`float` like `int` but for floating point values
`path` like the default but also accepts slashes
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

# General information about the project.
project = u'Flask'
copyright = u'2010, Armin Ronacher'
copyright = u'2012, Armin Ronacher'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down
9 changes: 8 additions & 1 deletion docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ The following configuration values are used internally by Flask:
reject incoming requests with a
content length greater than this by
returning a 413 status code.
``SEND_FILE_MAX_AGE_DEFAULT``: Default cache control max age to use with
:meth:`flask.Flask.send_static_file`, in
seconds. Override this value on a per-file
basis using the
:meth:`flask.Flask.get_send_file_options` and
:meth:`flask.Blueprint.get_send_file_options`
hooks. Defaults to 43200 (12 hours).
``TRAP_HTTP_EXCEPTIONS`` If this is set to ``True`` Flask will
not execute the error handlers of HTTP
exceptions but instead treat the
Expand Down Expand Up @@ -276,7 +283,7 @@ configuration::

class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'

class DevelopmentConfig(Config):
DEBUG = True

Expand Down
11 changes: 5 additions & 6 deletions docs/deploying/fastcgi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
FastCGI
=======

FastCGI is a deployment option on servers like `nginx`_, `lighttpd`_,
and `cherokee`_; see :ref:`deploying-uwsgi` and
:ref:`deploying-other-servers` for other options. To use your WSGI
application with any of them you will need a FastCGI server first. The
most popular one is `flup`_ which we will use for this guide. Make sure
to have it installed to follow along.
FastCGI is a deployment option on servers like `nginx`_, `lighttpd`_, and
`cherokee`_; see :ref:`deploying-uwsgi` and :ref:`deploying-wsgi-standalone`
for other options. To use your WSGI application with any of them you will need
a FastCGI server first. The most popular one is `flup`_ which we will use for
this guide. Make sure to have it installed to follow along.

.. admonition:: Watch Out

Expand Down
9 changes: 6 additions & 3 deletions docs/deploying/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ If you have a different WSGI server look up the server documentation
about how to use a WSGI app with it. Just remember that your
:class:`Flask` application object is the actual WSGI application.

For hosted options to get up and running quickly, see
:ref:`quickstart_deployment` in the Quickstart.

.. toctree::
:maxdepth: 2

mod_wsgi
cgi
fastcgi
wsgi-standalone
uwsgi
others
fastcgi
cgi
9 changes: 4 additions & 5 deletions docs/deploying/uwsgi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ uWSGI
=====

uWSGI is a deployment option on servers like `nginx`_, `lighttpd`_, and
`cherokee`_; see :ref:`deploying-fastcgi` and
:ref:`deploying-other-servers` for other options. To use your WSGI
application with uWSGI protocol you will need a uWSGI server
first. uWSGI is both a protocol and an application server; the
application server can serve uWSGI, FastCGI, and HTTP protocols.
`cherokee`_; see :ref:`deploying-fastcgi` and :ref:`deploying-wsgi-standalone`
for other options. To use your WSGI application with uWSGI protocol you will
need a uWSGI server first. uWSGI is both a protocol and an application server;
the application server can serve uWSGI, FastCGI, and HTTP protocols.

The most popular uWSGI server is `uwsgi`_, which we will use for this
guide. Make sure to have it installed to follow along.
Expand Down
96 changes: 63 additions & 33 deletions docs/deploying/others.rst → docs/deploying/wsgi-standalone.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
.. _deploying-other-servers:
.. _deploying-wsgi-standalone:

Other Servers
=============
Standalone WSGI Containers
==========================

There are popular servers written in Python that allow the execution of WSGI
applications as well. These servers stand alone when they run; you can proxy
to them from your web server.
There are popular servers written in Python that contain WSGI applications and
serve HTTP. These servers stand alone when they run; you can proxy to them
from your web server. Note the section on :ref:`deploying-proxy-setups` if you
run into issues.

Gunicorn
--------

`Gunicorn`_ 'Green Unicorn' is a WSGI HTTP Server for UNIX. It's a pre-fork
worker model ported from Ruby's Unicorn project. It supports both `eventlet`_
and `greenlet`_. Running a Flask application on this server is quite simple::

gunicorn myproject:app

`Gunicorn`_ provides many command-line options -- see ``gunicorn -h``.
For example, to run a Flask application with 4 worker processes (``-w
4``) binding to localhost port 4000 (``-b 127.0.0.1:4000``)::

gunicorn -w 4 -b 127.0.0.1:4000 myproject:app

.. _Gunicorn: http://gunicorn.org/
.. _eventlet: http://eventlet.net/
.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html

Tornado
--------
Expand All @@ -14,7 +34,7 @@ Tornado
server and tools that power `FriendFeed`_. Because it is non-blocking and
uses epoll, it can handle thousands of simultaneous standing connections,
which means it is ideal for real-time web services. Integrating this
service with Flask is a trivial task::
service with Flask is straightforward::

from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
Expand Down Expand Up @@ -46,44 +66,54 @@ event loop::
.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html
.. _libevent: http://monkey.org/~provos/libevent/

Gunicorn
--------
.. _deploying-proxy-setups:

`Gunicorn`_ 'Green Unicorn' is a WSGI HTTP Server for UNIX. It's a pre-fork
worker model ported from Ruby's Unicorn project. It supports both `eventlet`_
and `greenlet`_. Running a Flask application on this server is quite simple::
Proxy Setups
------------

gunicorn myproject:app
If you deploy your application using one of these servers behind an HTTP proxy
you will need to rewrite a few headers in order for the application to work.
The two problematic values in the WSGI environment usually are `REMOTE_ADDR`
and `HTTP_HOST`. You can configure your httpd to pass these headers, or you
can fix them in middleware. Werkzeug ships a fixer that will solve some common
setups, but you might want to write your own WSGI middleware for specific
setups.

`Gunicorn`_ provides many command-line options -- see ``gunicorn -h``.
For example, to run a Flask application with 4 worker processes (``-w
4``) binding to localhost port 4000 (``-b 127.0.0.1:4000``)::
Here's a simple nginx configuration which proxies to an application served on
localhost at port 8000, setting appropriate headers:

gunicorn -w 4 -b 127.0.0.1:4000 myproject:app
.. sourcecode:: nginx

.. _Gunicorn: http://gunicorn.org/
.. _eventlet: http://eventlet.net/
.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html
server {
listen 80;

Proxy Setups
------------
server_name _;

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

If you deploy your application using one of these servers behind an HTTP
proxy you will need to rewrite a few headers in order for the
application to work. The two problematic values in the WSGI environment
usually are `REMOTE_ADDR` and `HTTP_HOST`. Werkzeug ships a fixer that
will solve some common setups, but you might want to write your own WSGI
middleware for specific setups.
location / {
proxy_pass http://127.0.0.1:8000/;
proxy_redirect off;

The most common setup invokes the host being set from `X-Forwarded-Host`
and the remote address from `X-Forwarded-For`::
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

If your httpd is not providing these headers, the most common setup invokes the
host being set from `X-Forwarded-Host` and the remote address from
`X-Forwarded-For`::

from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)

Please keep in mind that it is a security issue to use such a middleware
in a non-proxy setup because it will blindly trust the incoming
headers which might be forged by malicious clients.
.. admonition:: Trusting Headers

Please keep in mind that it is a security issue to use such a middleware in
a non-proxy setup because it will blindly trust the incoming headers which
might be forged by malicious clients.

If you want to rewrite the headers from another header, you might want to
use a fixer like this::
Expand Down
Loading

0 comments on commit 3249eeb

Please sign in to comment.