/usr/share/doc/python-werkzeug-doc/html/request_data.html is in python-werkzeug-doc 0.9.4+dfsg-1.1ubuntu2.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dealing with Request Data — Werkzeug 0.9.4 documentation</title>
<link rel="stylesheet" href="_static/werkzeug.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.9.4',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Werkzeug 0.9.4 documentation" href="index.html" />
<link rel="next" title="Werkzeug Changelog" href="changes.html" />
<link rel="prev" title="Unicode" href="unicode.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="changes.html" title="Werkzeug Changelog"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="unicode.html" title="Unicode"
accesskey="P">previous</a> |</li>
<li><a href="index.html">Werkzeug 0.9.4 documentation</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-werkzeug">
<span id="id1"></span><span id="dealing-with-request-data"></span><h1>Dealing with Request Data<a class="headerlink" href="#module-werkzeug" title="Permalink to this headline">¶</a></h1>
<p>The most important rule about web development is “Do not trust the user”.
This is especially true for incoming request data on the input stream.
With WSGI this is actually a bit harder than you would expect. Because
of that Werkzeug wraps the request stream for you to save you from the
most prominent problems with it.</p>
<div class="section" id="missing-eof-marker-on-input-stream">
<h2>Missing EOF Marker on Input Stream<a class="headerlink" href="#missing-eof-marker-on-input-stream" title="Permalink to this headline">¶</a></h2>
<p>The input stream has no end-of-file marker. If you would call the
<tt class="xref py py-meth docutils literal"><span class="pre">read()</span></tt> method on the <cite>wsgi.input</cite> stream you would cause your
application to hang on conforming servers. This is actually intentional
however painful. Werkzeug solves that problem by wrapping the input
stream in a special <tt class="xref py py-class docutils literal"><span class="pre">LimitedStream</span></tt>. The input stream is exposed
on the request objects as <tt class="xref py py-attr docutils literal"><span class="pre">stream</span></tt>. This one is either
an empty stream (if the form data was parsed) or a limited stream with
the contents of the input stream.</p>
</div>
<div class="section" id="when-does-werkzeug-parse">
<h2>When does Werkzeug Parse?<a class="headerlink" href="#when-does-werkzeug-parse" title="Permalink to this headline">¶</a></h2>
<p>Werkzeug parses the incoming data under the following situations:</p>
<ul class="simple">
<li>you access either <tt class="xref py py-attr docutils literal"><span class="pre">form</span></tt>, <tt class="xref py py-attr docutils literal"><span class="pre">files</span></tt>,
or <tt class="xref py py-attr docutils literal"><span class="pre">stream</span></tt> and the request method was
<cite>POST</cite> or <cite>PUT</cite>.</li>
<li>if you call <tt class="xref py py-func docutils literal"><span class="pre">parse_form_data()</span></tt>.</li>
</ul>
<p>These calls are not interchangeable. If you invoke <tt class="xref py py-func docutils literal"><span class="pre">parse_form_data()</span></tt>
you must not use the request object or at least not the attributes that
trigger the parsing process.</p>
<p>This is also true if you read from the <cite>wsgi.input</cite> stream before the
parsing.</p>
<p><strong>General rule:</strong> Leave the WSGI input stream alone. Especially in
WSGI middlewares. Use either the parsing functions or the request
object. Do not mix multiple WSGI utility libraries for form data
parsing or anything else that works on the input stream.</p>
</div>
<div class="section" id="how-does-it-parse">
<h2>How does it Parse?<a class="headerlink" href="#how-does-it-parse" title="Permalink to this headline">¶</a></h2>
<p>The standard Werkzeug parsing behavior handles three cases:</p>
<ul class="simple">
<li>input content type was <cite>multipart/form-data</cite>. In this situation the
<tt class="xref py py-class docutils literal"><span class="pre">stream</span></tt> will be empty and
<tt class="xref py py-class docutils literal"><span class="pre">form</span></tt> will contain the regular <cite>POST</cite> / <cite>PUT</cite>
data, <tt class="xref py py-class docutils literal"><span class="pre">files</span></tt> will contain the uploaded
files as <tt class="xref py py-class docutils literal"><span class="pre">FileStorage</span></tt> objects.</li>
<li>input content type was <cite>application/x-www-form-urlencoded</cite>. Then the
<tt class="xref py py-class docutils literal"><span class="pre">stream</span></tt> will be empty and
<tt class="xref py py-class docutils literal"><span class="pre">form</span></tt> will contain the regular <cite>POST</cite> / <cite>PUT</cite>
data and <tt class="xref py py-class docutils literal"><span class="pre">files</span></tt> will be empty.</li>
<li>the input content type was neither of them, <tt class="xref py py-class docutils literal"><span class="pre">stream</span></tt>
points to a <tt class="xref py py-class docutils literal"><span class="pre">LimitedStream</span></tt> with the input data for further
processing.</li>
</ul>
<p>Special note on the <tt class="xref py py-attr docutils literal"><span class="pre">get_data</span></tt> method: Calling this
loads the full request data into memory. This is only safe to do if the
<tt class="xref py py-attr docutils literal"><span class="pre">max_content_length</span></tt> is set. Also you can <em>either</em>
read the stream <em>or</em> call <tt class="xref py py-meth docutils literal"><span class="pre">get_data()</span></tt>.</p>
</div>
<div class="section" id="limiting-request-data">
<h2>Limiting Request Data<a class="headerlink" href="#limiting-request-data" title="Permalink to this headline">¶</a></h2>
<p>To avoid being the victim of a DDOS attack you can set the maximum
accepted content length and request field sizes. The <tt class="xref py py-class docutils literal"><span class="pre">BaseRequest</span></tt>
class has two attributes for that: <tt class="xref py py-attr docutils literal"><span class="pre">max_content_length</span></tt>
and <tt class="xref py py-attr docutils literal"><span class="pre">max_form_memory_size</span></tt>.</p>
<p>The first one can be used to limit the total content length. For example
by setting it to <tt class="docutils literal"><span class="pre">1024</span> <span class="pre">*</span> <span class="pre">1024</span> <span class="pre">*</span> <span class="pre">16</span></tt> the request won’t accept more than
16MB of transmitted data.</p>
<p>Because certain data can’t be moved to the hard disk (regular post data)
whereas temporary files can, there is a second limit you can set. The
<tt class="xref py py-attr docutils literal"><span class="pre">max_form_memory_size</span></tt> limits the size of <cite>POST</cite>
transmitted form data. By setting it to <tt class="docutils literal"><span class="pre">1024</span> <span class="pre">*</span> <span class="pre">1024</span> <span class="pre">*</span> <span class="pre">2</span></tt> you can make
sure that all in memory-stored fields is not more than 2MB in size.</p>
<p>This however does <em>not</em> affect in-memory stored files if the
<cite>stream_factory</cite> used returns a in-memory file.</p>
</div>
<div class="section" id="how-to-extend-parsing">
<h2>How to extend Parsing?<a class="headerlink" href="#how-to-extend-parsing" title="Permalink to this headline">¶</a></h2>
<p>Modern web applications transmit a lot more than multipart form data or
url encoded data. Extending the parsing capabilities by subclassing
the <tt class="xref py py-class docutils literal"><span class="pre">BaseRequest</span></tt> is simple. The following example implements
parsing for incoming JSON data:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">werkzeug.utils</span> <span class="kn">import</span> <span class="n">cached_property</span>
<span class="kn">from</span> <span class="nn">werkzeug.wrappers</span> <span class="kn">import</span> <span class="n">Request</span>
<span class="kn">from</span> <span class="nn">simplejson</span> <span class="kn">import</span> <span class="n">loads</span>
<span class="k">class</span> <span class="nc">JSONRequest</span><span class="p">(</span><span class="n">Request</span><span class="p">):</span>
<span class="c"># accept up to 4MB of transmitted data.</span>
<span class="n">max_content_length</span> <span class="o">=</span> <span class="mi">1024</span> <span class="o">*</span> <span class="mi">1024</span> <span class="o">*</span> <span class="mi">4</span>
<span class="nd">@cached_property</span>
<span class="k">def</span> <span class="nf">json</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'content-type'</span><span class="p">)</span> <span class="o">==</span> <span class="s">'application/json'</span><span class="p">:</span>
<span class="k">return</span> <span class="n">loads</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper"><p class="logo"><a href="index.html">
<img class="logo" src="_static/werkzeug.png" alt="Logo"/>
</a></p>
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Dealing with Request Data</a><ul>
<li><a class="reference internal" href="#missing-eof-marker-on-input-stream">Missing EOF Marker on Input Stream</a></li>
<li><a class="reference internal" href="#when-does-werkzeug-parse">When does Werkzeug Parse?</a></li>
<li><a class="reference internal" href="#how-does-it-parse">How does it Parse?</a></li>
<li><a class="reference internal" href="#limiting-request-data">Limiting Request Data</a></li>
<li><a class="reference internal" href="#how-to-extend-parsing">How to extend Parsing?</a></li>
</ul>
</li>
</ul>
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="unicode.html" title="previous chapter">Unicode</a></li>
<li>Next: <a href="changes.html" title="next chapter">Werkzeug Changelog</a></li>
</ul></li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/request_data.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
© Copyright 2011, The Werkzeug Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
</div>
</body>
</html>
|