/usr/share/doc/python-twisted-web/howto/web-in-60/handling-posts.html is in python-twisted-web 13.2.0-1ubuntu1.
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 | <?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Twisted Documentation: Handling POSTs</title>
<link href="../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body bgcolor="white">
<h1 class="title">Handling POSTs</h1>
<div class="toc"><ol/></div>
<div class="content">
<span/>
<p>All of the previous examples have focused on <code>GET</code>
requests. Unlike <code>GET</code> requests, <code>POST</code> requests can have
a request body - extra data after the request headers; for example, data
representing the contents of an HTML form. Twisted Web makes this data available
to applications via the <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.server.Request.html" title="twisted.web.server.Request">Request</a></code> object.</p>
<p>Here's an example web server which renders a static HTML form and then
generates a dynamic page when that form is posted back to it. Disclaimer: While
it's convenient for this example, it's often not a good idea to make a resource
that <code>POST</code>s to itself; this isn't about Twisted Web, but the nature
of HTTP in general; if you do this in a real application, make sure you
understand the possible negative consequences.</p>
<p>As usual, we start with some imports. In addition to the Twisted imports,
this example uses the <code>cgi</code> module to <a href="http://en.wikipedia.org/wiki/Cross-site_scripting" shape="rect">escape user-entered
content</a> for inclusion in the output.</p>
<pre class="python"><p class="py-linenumber">1
2
3
4
5
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">server</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Site</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">resource</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Resource</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
<span class="py-src-keyword">import</span> <span class="py-src-variable">cgi</span>
</pre>
<p>Next, we'll define a resource which is going to do two things. First, it will
respond to <code>GET</code> requests with a static HTML form:</p>
<pre class="python"><p class="py-linenumber">1
2
3
</p><span class="py-src-keyword">class</span> <span class="py-src-identifier">FormPage</span>(<span class="py-src-parameter">Resource</span>):
<span class="py-src-keyword">def</span> <span class="py-src-identifier">render_GET</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>):
<span class="py-src-keyword">return</span> <span class="py-src-string">'<html><body><form method="POST"><input name="the-field" type="text" /></form></body></html>'</span>
</pre>
<p>This is similar to the resource used in a <a href="dynamic-content.html" shape="rect">previous installment</a>. However, we'll now add
one more method to give it a second behavior; this <code>render_POST</code>
method will allow it to accept <code>POST</code> requests:</p>
<pre class="python"><p class="py-linenumber">1
2
3
</p>...
<span class="py-src-keyword">def</span> <span class="py-src-identifier">render_POST</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>):
<span class="py-src-keyword">return</span> <span class="py-src-string">'<html><body>You submitted: %s</body></html>'</span> % (<span class="py-src-variable">cgi</span>.<span class="py-src-variable">escape</span>(<span class="py-src-variable">request</span>.<span class="py-src-variable">args</span>[<span class="py-src-string">"the-field"</span>][<span class="py-src-number">0</span>]),)
</pre>
<p>The main thing to note here is the use
of <code>request.args</code>. This is a dictionary-like object that
provides access to the contents of the form. The keys in this
dictionary are the names of inputs in the form. Each value is a list
containing strings (since there can be multiple inputs with the same
name), which is why we had to extract the first element to pass
to <code>cgi.escape</code>. <code>request.args</code> will be
populated from form contents whenever a <code>POST</code> request is
made with a content type
of <code>application/x-www-form-urlencoded</code>
or <code>multipart/form-data</code> (it's also populated by query
arguments for any type of request).</p>
<p>Finally, the example just needs the usual site creation and port setup:</p>
<pre class="python"><p class="py-linenumber">1
2
3
4
5
</p><span class="py-src-variable">root</span> = <span class="py-src-variable">Resource</span>()
<span class="py-src-variable">root</span>.<span class="py-src-variable">putChild</span>(<span class="py-src-string">"form"</span>, <span class="py-src-variable">FormPage</span>())
<span class="py-src-variable">factory</span> = <span class="py-src-variable">Site</span>(<span class="py-src-variable">root</span>)
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">listenTCP</span>(<span class="py-src-number">8880</span>, <span class="py-src-variable">factory</span>)
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
</pre>
<p>Run the server and
visit <a href="http://localhost:8880/form" shape="rect">http://localhost:8880/form</a>,
submit the form, and watch it generate a page including the value you entered
into the single field.</p>
<p>Here's the complete source for the example:</p>
<pre class="python"><p class="py-linenumber"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">server</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Site</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">resource</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Resource</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
<span class="py-src-keyword">import</span> <span class="py-src-variable">cgi</span>
<span class="py-src-keyword">class</span> <span class="py-src-identifier">FormPage</span>(<span class="py-src-parameter">Resource</span>):
<span class="py-src-keyword">def</span> <span class="py-src-identifier">render_GET</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>):
<span class="py-src-keyword">return</span> <span class="py-src-string">'<html><body><form method="POST"><input name="the-field" type="text" /></form></body></html>'</span>
<span class="py-src-keyword">def</span> <span class="py-src-identifier">render_POST</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>):
<span class="py-src-keyword">return</span> <span class="py-src-string">'<html><body>You submitted: %s</body></html>'</span> % (<span class="py-src-variable">cgi</span>.<span class="py-src-variable">escape</span>(<span class="py-src-variable">request</span>.<span class="py-src-variable">args</span>[<span class="py-src-string">"the-field"</span>][<span class="py-src-number">0</span>]),)
<span class="py-src-variable">root</span> = <span class="py-src-variable">Resource</span>()
<span class="py-src-variable">root</span>.<span class="py-src-variable">putChild</span>(<span class="py-src-string">"form"</span>, <span class="py-src-variable">FormPage</span>())
<span class="py-src-variable">factory</span> = <span class="py-src-variable">Site</span>(<span class="py-src-variable">root</span>)
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">listenTCP</span>(<span class="py-src-number">8880</span>, <span class="py-src-variable">factory</span>)
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
</pre>
</div>
<p><a href="../index.html">Index</a></p>
<span class="version">Version: 13.2.0</span>
</body>
</html>
|