CHips L MINI SHELL

CHips L pro

Current Path : /usr/share/doc/python-twisted-web/howto/
Upload File :
Current File : //usr/share/doc/python-twisted-web/howto/using-twistedweb.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

  <head>
    <meta name="Description" content="An event-driven networking engine written in Python and MIT licensed." />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Configuring and Using the Twisted Web Server &mdash; Twisted 16.0.0 documentation</title>
    <link rel="stylesheet" href="../../_static/twistedtrac.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../../',
        VERSION:     '16.0.0',
        COLLAPSE_MODINDEX: 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="Twisted 16.0.0 documentation" href="../../index.html" />
    <link rel="up" title="Developer Guides" href="index.html" />
    <link rel="next" title="Web Application Development" href="web-development.html" />
    <link rel="prev" title="Overview of Twisted Web" href="web-overview.html" /> 
    
<!-- Can stuff between these comments go? -->
        <link rel="search" href="/trac/search" />
        <link rel="help" href="/trac/wiki/TracGuide" />
        <link rel="alternate" href="/trac/wiki/Documentation?format=txt" type="text/x-trac-wiki" title="Plain Text" />
        <link rel="start" href="/trac/wiki" />

        
    <script type="text/javascript" src="/trac/chrome/common/js/jquery.js"></script><script type="text/javascript" src="/trac/chrome/common/js/trac.js"></script><script type="text/javascript" src="/trac/chrome/common/js/search.js"></script>
    
    <!-- the following script tag is a holdover frome Trac, which shouldn't be needed in Sphinx
    <script type="text/javascript">
      $(document).ready(function() {
        $("#content").find("h1,h2,h3,h4,h5,h6").addAnchor("Link to this section");
      });
    </script>
    -->
<!-- Can stuff between these comments go? -->

  </head>
  
  
<body>

<div id="banner">
<div id="top_grad">
         
</div>
<div id="tab">
        <a href="http://twistedmatrix.com/trac/wiki">HOME</a>
    <a href="http://twistedmatrix.com/trac/wiki/FrequentlyAskedQuestions">FAQ</a>
    <a href="/">DOCS</a>
    <a href="http://twistedmatrix.com/trac/wiki/Downloads">DOWNLOAD</a>

</div>
      <div id="header">
        <a id="logo" href="http://twistedmatrix.com/trac/"><img src="../../_static/trac_banner.png" alt="Twisted" /></a>
      </div>
      <!-- taking this out for now, but might use 
           the space for something else later 
      -->
      <!--
      <form id="topsearch" action="/trac/search" method="get"><div>
        <label for="proj-search">Search:</label>
        <input type="text" id="proj-search" name="q" size="10" value="" />
        <input type="submit" value="Search" />
        <input type="hidden" name="wiki" value="on" />

        <input type="hidden" name="changeset" value="on" />
        <input type="hidden" name="ticket" value="on" />
      </div></form>
      -->
      <div id="metanav" class="nav">
    <ul>
      <li> </li>
      <!-- taking this out for now, but might use 
           the space for something else later 
      -->
      <!--
      <li class="first">logged in as khorn</li><li class=""><a href="/trac/logout">Logout</a></li><li class=""><a href="/trac/wiki/TracGuide">Help/Guide</a></li><li class=""><a href="/trac/about">About Trac</a></li><li class="last"><a href="/trac/account">My Account</a></li>
      -->
    </ul>
  </div>
    </div>

<!-- mainnav -->
    <div id="mainnav" 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="web-development.html" title="Web Application Development"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="web-overview.html" title="Overview of Twisted Web"
             accesskey="P">previous</a> |</li>
        <li><a href="../../index.html">Twisted 16.0.0 documentation</a> &raquo;</li>
          <li><a href="../index.html" >Twisted Web</a> &raquo;</li>
          <li><a href="index.html" accesskey="U">Developer Guides</a> &raquo;</li> 
      </ul>
    </div>

    <div id="main">
    <div id="ctxtnav" class="nav">
      <h2>Wiki Navigation</h2>
      <ul>
        <li>
        
        </li>
        <!-- taking this out for now, but might use 
             the space for something else later 
        -->
        <!--
        <li><a href="/trac/wiki/WikiStart">Start Page</a></li>
        <li><a href="/trac/wiki/TitleIndex">Index by Title</a></li>

        <li><a href="/trac/wiki/RecentChanges">Index by Date</a></li>
        <li class="last">
          <a href="/trac/wiki/Documentation?action=diff&amp;version=15">Last Change</a>
        </li>
        -->
      </ul>
      <hr />
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div id="current-docs-container" style="display: none">
            <em>
              <a id="current-docs-link">
                Go to the latest version of this document.
              </a>
            </em>
          </div>
          <div class="body">
            
  <div class="section" id="configuring-and-using-the-twisted-web-server">
<h1>Configuring and Using the Twisted Web Server<a class="headerlink" href="#configuring-and-using-the-twisted-web-server" title="Permalink to this headline">¶</a></h1>
<div class="section" id="twisted-web-development">
<h2>Twisted Web Development<a class="headerlink" href="#twisted-web-development" title="Permalink to this headline">¶</a></h2>
<p id="web-howto-using-twistedweb-development">Twisted Web serves Python objects that implement the interface
IResource.</p>
<img alt="../../_images/web-process.png" src="../../_images/web-process.png" />
<div class="section" id="main-concepts">
<h3>Main Concepts<a class="headerlink" href="#main-concepts" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><a class="reference internal" href="#web-howto-using-twistedweb-sites"><span>Site Objects</span></a> are responsible for
creating <code class="docutils literal"><span class="pre">HTTPChannel</span></code> instances to parse the HTTP request,
and begin the object lookup process. They contain the root Resource,
the resource which represents the URL <code class="docutils literal"><span class="pre">/</span></code> on the site.</li>
<li><a class="reference internal" href="#web-howto-using-twistedweb-resources"><span>Resource</span></a> objects represent a single URL segment. The <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.resource.IResource.html">IResource</a> interface describes the methods a Resource object must implement in order to participate in the object publishing process.</li>
<li><a class="reference internal" href="#web-howto-using-twistedweb-trees"><span>Resource trees</span></a> are arrangements of Resource objects into a Resource tree. Starting at the root Resource object, the tree of Resource objects defines the URLs which will be valid.</li>
<li><a class="reference internal" href="#web-howto-using-twistedweb-rpys"><span>.rpy scripts</span></a> are python scripts which the twisted.web static file server will execute, much like a CGI. However, unlike CGI they must create a Resource object which will be rendered when the URL is visited.</li>
<li><a class="reference internal" href="#web-howto-using-twistedweb-rendering"><span>Resource rendering</span></a> occurs when Twisted Web locates a leaf Resource object. A Resource can either return an html string or write to the request object.</li>
<li><a class="reference internal" href="#web-howto-using-twistedweb-sessions"><span>Session</span></a> objects allow you to store information across multiple requests. Each individual browser using the system has a unique Session instance.</li>
</ul>
<p>The Twisted Web server is started through the Twisted Daemonizer, as in:</p>
<div class="highlight-console"><div class="highlight"><pre><span class="gp">%</span> twistd web
</pre></div>
</div>
</div>
<div class="section" id="site-objects">
<h3>Site Objects<a class="headerlink" href="#site-objects" title="Permalink to this headline">¶</a></h3>
<p id="web-howto-using-twistedweb-sites">Site objects serve as the glue between a port to listen for HTTP requests on, and a root Resource object.</p>
<p>When using <code class="docutils literal"><span class="pre">twistd</span> <span class="pre">-n</span> <span class="pre">web</span> <span class="pre">--path</span> <span class="pre">/foo/bar/baz</span></code> , a Site object is created with a root Resource that serves files out of the given path.</p>
<p>You can also create a <code class="docutils literal"><span class="pre">Site</span></code> instance by hand, passing
it a <code class="docutils literal"><span class="pre">Resource</span></code> object which will serve as the root of the
site:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">server</span><span class="p">,</span> <span class="n">resource</span>
<span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>

<span class="k">class</span> <span class="nc">Simple</span><span class="p">(</span><span class="n">resource</span><span class="o">.</span><span class="n">Resource</span><span class="p">):</span>
    <span class="n">isLeaf</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="k">def</span> <span class="nf">render_GET</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;&lt;html&gt;Hello, world!&lt;/html&gt;&quot;</span>

<span class="n">site</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">Simple</span><span class="p">())</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">listenTCP</span><span class="p">(</span><span class="mi">8080</span><span class="p">,</span> <span class="n">site</span><span class="p">)</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="resource-objects">
<h3>Resource objects<a class="headerlink" href="#resource-objects" title="Permalink to this headline">¶</a></h3>
<p id="web-howto-using-twistedweb-resources"><code class="docutils literal"><span class="pre">Resource</span></code> objects represent a single URL segment of a site. During URL parsing, <code class="docutils literal"><span class="pre">getChild</span></code> is called on the current <code class="docutils literal"><span class="pre">Resource</span></code> to produce the next <code class="docutils literal"><span class="pre">Resource</span></code> object.</p>
<p>When the leaf Resource is reached, either because there were no more URL segments or a Resource had isLeaf set to True, the leaf Resource is rendered by calling <code class="docutils literal"><span class="pre">render(request)</span></code> . See &#8220;Resource Rendering&#8221; below for more about this.</p>
<p>During the Resource location process, the URL segments which have already been processed and those which have not yet been processed are available in <code class="docutils literal"><span class="pre">request.prepath</span></code> and <code class="docutils literal"><span class="pre">request.postpath</span></code> .</p>
<p>A Resource can know where it is in the URL tree by looking at <code class="docutils literal"><span class="pre">request.prepath</span></code> , a list of URL segment strings.</p>
<p>A Resource can know which path segments will be processed after it by looking at <code class="docutils literal"><span class="pre">request.postpath</span></code> .</p>
<p>If the URL ends in a slash, for example <code class="docutils literal"><span class="pre">http://example.com/foo/bar/</span></code> , the final URL segment will be an empty string. Resources can thus know if they were requested with or without a final slash.</p>
<p>Here is a simple Resource object:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.web.resource</span> <span class="kn">import</span> <span class="n">Resource</span>

<span class="k">class</span> <span class="nc">Hello</span><span class="p">(</span><span class="n">Resource</span><span class="p">):</span>
    <span class="n">isLeaf</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="k">def</span> <span class="nf">getChild</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s">&#39;&#39;</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">self</span>
        <span class="k">return</span> <span class="n">Resource</span><span class="o">.</span><span class="n">getChild</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">request</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">render_GET</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;Hello, world! I am located at </span><span class="si">%r</span><span class="s">.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">prepath</span><span class="p">,)</span>

<span class="n">resource</span> <span class="o">=</span> <span class="n">Hello</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="resource-trees">
<h3>Resource Trees<a class="headerlink" href="#resource-trees" title="Permalink to this headline">¶</a></h3>
<p id="web-howto-using-twistedweb-trees">Resources can be arranged in trees using <code class="docutils literal"><span class="pre">putChild</span></code> . <code class="docutils literal"><span class="pre">putChild</span></code> puts a Resource instance into another Resource instance, making it available at the given path segment name:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">root</span> <span class="o">=</span> <span class="n">Hello</span><span class="p">()</span>
<span class="n">root</span><span class="o">.</span><span class="n">putChild</span><span class="p">(</span><span class="s">&#39;fred&#39;</span><span class="p">,</span> <span class="n">Hello</span><span class="p">())</span>
<span class="n">root</span><span class="o">.</span><span class="n">putChild</span><span class="p">(</span><span class="s">&#39;bob&#39;</span><span class="p">,</span> <span class="n">Hello</span><span class="p">())</span>
</pre></div>
</div>
<p>If this root resource is served as the root of a Site instance, the following URLs will all be valid:</p>
<ul class="simple">
<li><code class="docutils literal"><span class="pre">http://example.com/</span></code></li>
<li><code class="docutils literal"><span class="pre">http://example.com/fred</span></code></li>
<li><code class="docutils literal"><span class="pre">http://example.com/bob</span></code></li>
<li><code class="docutils literal"><span class="pre">http://example.com/fred/</span></code></li>
<li><code class="docutils literal"><span class="pre">http://example.com/bob/</span></code></li>
</ul>
</div>
<div class="section" id="rpy-scripts">
<h3>.rpy scripts<a class="headerlink" href="#rpy-scripts" title="Permalink to this headline">¶</a></h3>
<p id="web-howto-using-twistedweb-rpys">Files with the extension <code class="docutils literal"><span class="pre">.rpy</span></code> are python scripts which, when placed in a directory served by Twisted Web, will be executed when visited through the web.</p>
<p>An <code class="docutils literal"><span class="pre">.rpy</span></code> script must define a variable, <code class="docutils literal"><span class="pre">resource</span></code> , which is the Resource object that will render the request.</p>
<p><code class="docutils literal"><span class="pre">.rpy</span></code> files are very convenient for rapid development and prototyping. Since they are executed on every web request, defining a Resource subclass in an <code class="docutils literal"><span class="pre">.rpy</span></code> will make viewing the results of changes to your class visible simply by refreshing the page:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.web.resource</span> <span class="kn">import</span> <span class="n">Resource</span>

<span class="k">class</span> <span class="nc">MyResource</span><span class="p">(</span><span class="n">Resource</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">render_GET</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;&lt;html&gt;Hello, world!&lt;/html&gt;&quot;</span>

<span class="n">resource</span> <span class="o">=</span> <span class="n">MyResource</span><span class="p">()</span>
</pre></div>
</div>
<p>However, it is often a better idea to define Resource subclasses in Python modules. In order for changes in modules to be visible, you must either restart the Python process, or reload the module:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">myresource</span>

<span class="c">## Comment out this line when finished debugging</span>
<span class="nb">reload</span><span class="p">(</span><span class="n">myresource</span><span class="p">)</span>

<span class="n">resource</span> <span class="o">=</span> <span class="n">myresource</span><span class="o">.</span><span class="n">MyResource</span><span class="p">()</span>
</pre></div>
</div>
<p>Creating a Twisted Web server which serves a directory is easy:</p>
<div class="highlight-console"><div class="highlight"><pre><span class="gp">%</span> twistd -n web --path /Users/dsp/Sites
</pre></div>
</div>
</div>
<div class="section" id="resource-rendering">
<h3>Resource rendering<a class="headerlink" href="#resource-rendering" title="Permalink to this headline">¶</a></h3>
<p id="web-howto-using-twistedweb-rendering">Resource rendering occurs when Twisted Web locates a leaf Resource object to handle a web request. A Resource&#8217;s <code class="docutils literal"><span class="pre">render</span></code> method may do various things to produce output which will be sent back to the browser:</p>
<ul class="simple">
<li>Return a string</li>
<li>Call <code class="docutils literal"><span class="pre">request.write(&quot;stuff&quot;)</span></code> as many times as desired, then call <code class="docutils literal"><span class="pre">request.finish()</span></code> and return <code class="docutils literal"><span class="pre">server.NOT_DONE_YET</span></code> (This is deceptive, since you are in fact done with the request, but is the correct way to do this)</li>
<li>Request a <code class="docutils literal"><span class="pre">Deferred</span></code> , return <code class="docutils literal"><span class="pre">server.NOT_DONE_YET</span></code> , and call <code class="docutils literal"><span class="pre">request.write(&quot;stuff&quot;)</span></code> and <code class="docutils literal"><span class="pre">request.finish()</span></code> later, in a callback on the <code class="docutils literal"><span class="pre">Deferred</span></code> .</li>
</ul>
<p>The <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.resource.Resource.html">Resource</a>
class, which is usually what one&#8217;s Resource classes subclass, has a
convenient default implementation
of <code class="docutils literal"><span class="pre">render</span></code> . It will call a method
named <code class="docutils literal"><span class="pre">self.render_METHOD</span></code>
where &#8220;METHOD&#8221; is whatever HTTP method was used to request this
resource. Examples: request_GET, request_POST, request_HEAD, and so
on. It is recommended that you have your resource classes
subclass <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.resource.Resource.html">Resource</a>
and implement <code class="docutils literal"><span class="pre">render_METHOD</span></code> methods as
opposed to <code class="docutils literal"><span class="pre">render</span></code> itself. Note that for
certain resources, <code class="docutils literal"><span class="pre">request_POST</span> <span class="pre">=</span> <span class="pre">request_GET</span></code> may be desirable in case one wants to process
arguments passed to the resource regardless of whether they used GET
(<code class="docutils literal"><span class="pre">?foo=bar&amp;baz=quux</span></code> , and so forth) or POST.</p>
</div>
<div class="section" id="request-encoders">
<h3>Request encoders<a class="headerlink" href="#request-encoders" title="Permalink to this headline">¶</a></h3>
<p>When using a <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.resource.Resource.html">Resource</a> ,
one can specify wrap it using a
<a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.resource.EncodingResourceWrapper.html">EncodingResourceWrapper</a>
and passing a list of encoder factories.  The encoder factories are
called when a request is processed and potentially return an encoder.
By default twisted provides
<a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.server.GzipEncoderFactory.html">GzipEncoderFactory</a> which
manages standard gzip compression. You can use it this way:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.web.server</span> <span class="kn">import</span> <span class="n">Site</span><span class="p">,</span> <span class="n">GzipEncoderFactory</span>
<span class="kn">from</span> <span class="nn">twisted.web.resource</span> <span class="kn">import</span> <span class="n">Resource</span><span class="p">,</span> <span class="n">EncodingResourceWrapper</span>
<span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>

<span class="k">class</span> <span class="nc">Simple</span><span class="p">(</span><span class="n">Resource</span><span class="p">):</span>
    <span class="n">isLeaf</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="k">def</span> <span class="nf">render_GET</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;&lt;html&gt;Hello, world!&lt;/html&gt;&quot;</span>

<span class="n">resource</span> <span class="o">=</span> <span class="n">Simple</span><span class="p">()</span>
<span class="n">wrapped</span> <span class="o">=</span> <span class="n">EncodingResourceWrapper</span><span class="p">(</span><span class="n">resource</span><span class="p">,</span> <span class="p">[</span><span class="n">GzipEncoderFactory</span><span class="p">()])</span>
<span class="n">site</span> <span class="o">=</span> <span class="n">Site</span><span class="p">(</span><span class="n">wrapped</span><span class="p">)</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">listenTCP</span><span class="p">(</span><span class="mi">8080</span><span class="p">,</span> <span class="n">site</span><span class="p">)</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</pre></div>
</div>
<p>Using compression on SSL served resources where the user can influence the
content can lead to information leak, so be careful which resources use
request encoders.</p>
<p>Note that only encoder can be used per request: the first encoder factory
returning an object will be used, so the order in which they are specified
matters.</p>
</div>
<div class="section" id="session">
<h3>Session<a class="headerlink" href="#session" title="Permalink to this headline">¶</a></h3>
<p id="web-howto-using-twistedweb-sessions">HTTP is a stateless protocol; every request-response is treated as an individual unit, distinguishable from any other request only by the URL requested. With the advent of Cookies in the mid nineties, dynamic web servers gained the ability to distinguish between requests coming from different <em>browser sessions</em> by sending a Cookie to a browser. The browser then sends this cookie whenever it makes a request to a web server, allowing the server to track which requests come from which browser session.</p>
<p>Twisted Web provides an abstraction of this browser-tracking behavior called the <em>Session object</em> . Calling <code class="docutils literal"><span class="pre">request.getSession()</span></code> checks to see if a session cookie has been set; if not, it creates a unique session id, creates a Session object, stores it in the Site, and returns it. If a session object already exists, the same session object is returned. In this way, you can store data specific to the session in the session object.</p>
<img alt="../../_images/web-session.png" src="../../_images/web-session.png" />
</div>
<div class="section" id="proxies-and-reverse-proxies">
<h3>Proxies and reverse proxies<a class="headerlink" href="#proxies-and-reverse-proxies" title="Permalink to this headline">¶</a></h3>
<p id="web-howto-using-twistedweb-proxies">A proxy is a general term for a server that functions as an intermediary
between clients and other servers.</p>
<p>Twisted supports two main proxy variants: a <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.proxy.Proxy.html">Proxy</a> and a <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.proxy.ReverseProxy.html">ReverseProxy</a> .</p>
<div class="section" id="proxy">
<h4>Proxy<a class="headerlink" href="#proxy" title="Permalink to this headline">¶</a></h4>
<p>A proxy forwards requests made by a client to a destination server. Proxies
typically sit on the internal network for a client or out on the internet, and
have many uses, including caching, packet filtering, auditing, and circumventing
local access restrictions to web content.</p>
<p>Here is an example of a simple but complete web proxy:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">proxy</span><span class="p">,</span> <span class="n">http</span>
<span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>

<span class="k">class</span> <span class="nc">ProxyFactory</span><span class="p">(</span><span class="n">http</span><span class="o">.</span><span class="n">HTTPFactory</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">buildProtocol</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">proxy</span><span class="o">.</span><span class="n">Proxy</span><span class="p">()</span>

<span class="n">reactor</span><span class="o">.</span><span class="n">listenTCP</span><span class="p">(</span><span class="mi">8080</span><span class="p">,</span> <span class="n">ProxyFactory</span><span class="p">())</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</pre></div>
</div>
<p>With this proxy running, you can configure your web browser to use <code class="docutils literal"><span class="pre">localhost:8080</span></code> as a proxy. After doing so, when browsing the web
all requests will go through this proxy.</p>
<p><a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.proxy.Proxy.html">Proxy</a> inherits
from <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.http.HTTPChannel.html">http.HTTPChannel</a> . Each client
request to the proxy generates a <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.proxy.ProxyRequest.html">ProxyRequest</a> from the proxy to the destination
server on behalf of the client. <code class="docutils literal"><span class="pre">ProxyRequest</span></code> uses
a <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.proxy.ProxyClientFactory.html">ProxyClientFactory</a> to create
an instance of the <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.proxy.ProxyClient.html">ProxyClient</a>
protocol for the connection. <code class="docutils literal"><span class="pre">ProxyClient</span></code> inherits
from <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.http.HTTPClient.html">http.HTTPClient</a> . Subclass <code class="docutils literal"><span class="pre">ProxyRequest</span></code> to
customize the way requests are processed or logged.</p>
</div>
<div class="section" id="reverseproxyresource">
<h4>ReverseProxyResource<a class="headerlink" href="#reverseproxyresource" title="Permalink to this headline">¶</a></h4>
<p>A reverse proxy retrieves resources from other servers on behalf of a
client. Reverse proxies typically sit inside the server&#8217;s internal network and
are used for caching, application firewalls, and load balancing.</p>
<p>Here is an example of a basic reverse proxy:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>
<span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">proxy</span><span class="p">,</span> <span class="n">server</span>

<span class="n">site</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">proxy</span><span class="o">.</span><span class="n">ReverseProxyResource</span><span class="p">(</span><span class="s">&#39;www.yahoo.com&#39;</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">))</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">listenTCP</span><span class="p">(</span><span class="mi">8080</span><span class="p">,</span> <span class="n">site</span><span class="p">)</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</pre></div>
</div>
<p>With this reverse proxy running locally, you can
visit <code class="docutils literal"><span class="pre">http://localhost:8080</span></code> in your web browser, and the reverse
proxy will proxy your connection to <code class="docutils literal"><span class="pre">www.yahoo.com</span></code>.</p>
<p>In this example we use <code class="docutils literal"><span class="pre">server.Site</span></code> to serve
a <code class="docutils literal"><span class="pre">ReverseProxyResource</span></code> directly. There is
also a <code class="docutils literal"><span class="pre">ReverseProxy</span></code> family of classes
in <code class="docutils literal"><span class="pre">twisted.web.proxy</span></code> mirroring those of the <code class="docutils literal"><span class="pre">Proxy</span></code>
family:</p>
<p>Like <code class="docutils literal"><span class="pre">Proxy</span></code> , <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.proxy.ReverseProxy.html">ReverseProxy</a> inherits
from <code class="docutils literal"><span class="pre">http.HTTPChannel</span></code> . Each client request to the reverse proxy
generates a <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.proxy.ReverseProxyRequest.html">ReverseProxyRequest</a> to the destination
server. Like <code class="docutils literal"><span class="pre">ProxyRequest</span></code> , <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.proxy.ReverseProxyRequest.html">ReverseProxyRequest</a> uses a <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.proxy.ProxyClientFactory.html">ProxyClientFactory</a> to create an instance of
the <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.proxy.ProxyClient.html">ProxyClient</a> protocol for
the connection.</p>
<p>Additional examples of proxies and reverse proxies can be found in
the <a class="reference external" href="../examples/index.html">Twisted web examples</a></p>
</div>
</div>
</div>
<div class="section" id="advanced-configuration">
<h2>Advanced Configuration<a class="headerlink" href="#advanced-configuration" title="Permalink to this headline">¶</a></h2>
<p>Non-trivial configurations of Twisted Web are achieved with Python
configuration files. This is a Python snippet which builds up a
variable called application. Usually,
a <code class="docutils literal"><span class="pre">twisted.application.internet.TCPServer</span></code>
instance will be used to make the application listen on a TCP port
(80, in case direct web serving is desired), with the listener being
a <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.server.Site.html">twisted.web.server.Site</a> . The resulting file
can then be run with <code class="docutils literal"><span class="pre">twistd</span> <span class="pre">-y</span></code> . Alternatively a reactor object can be used directly to make
a runnable script.</p>
<p>The <code class="docutils literal"><span class="pre">Site</span></code> will wrap a <code class="docutils literal"><span class="pre">Resource</span></code> object &#8211; the
root.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.application</span> <span class="kn">import</span> <span class="n">internet</span><span class="p">,</span> <span class="n">service</span>
<span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">static</span><span class="p">,</span> <span class="n">server</span>

<span class="n">root</span> <span class="o">=</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/var/www/htdocs&quot;</span><span class="p">)</span>
<span class="n">application</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">Application</span><span class="p">(</span><span class="s">&#39;web&#39;</span><span class="p">)</span>
<span class="n">site</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
<span class="n">sc</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">IServiceCollection</span><span class="p">(</span><span class="n">application</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">internet</span><span class="o">.</span><span class="n">TCPServer</span><span class="p">(</span><span class="mi">80</span><span class="p">,</span> <span class="n">site</span><span class="p">)</span>
<span class="n">i</span><span class="o">.</span><span class="n">setServiceParent</span><span class="p">(</span><span class="n">sc</span><span class="p">)</span>
</pre></div>
</div>
<p>Most advanced configurations will be in the form of tweaking the
root resource object.</p>
<div class="section" id="adding-children">
<h3>Adding Children<a class="headerlink" href="#adding-children" title="Permalink to this headline">¶</a></h3>
<p>Usually, the root&#8217;s children will be based on the filesystem&#8217;s contents.
It is possible to override the filesystem by explicit <code class="docutils literal"><span class="pre">putChild</span></code>
methods.</p>
<p>Here are two examples. The first one adds a <code class="docutils literal"><span class="pre">/doc</span></code> child
to serve the documentation of the installed packages, while the second
one adds a <code class="docutils literal"><span class="pre">cgi-bin</span></code> directory for CGI scripts.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>
<span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">static</span><span class="p">,</span> <span class="n">server</span>

<span class="n">root</span> <span class="o">=</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/var/www/htdocs&quot;</span><span class="p">)</span>
<span class="n">root</span><span class="o">.</span><span class="n">putChild</span><span class="p">(</span><span class="s">&quot;doc&quot;</span><span class="p">,</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/usr/share/doc&quot;</span><span class="p">))</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">listenTCP</span><span class="p">(</span><span class="mi">80</span><span class="p">,</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">root</span><span class="p">))</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</pre></div>
</div>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>
<span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">static</span><span class="p">,</span> <span class="n">server</span><span class="p">,</span> <span class="n">twcgi</span>

<span class="n">root</span> <span class="o">=</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/var/www/htdocs&quot;</span><span class="p">)</span>
<span class="n">root</span><span class="o">.</span><span class="n">putChild</span><span class="p">(</span><span class="s">&quot;cgi-bin&quot;</span><span class="p">,</span> <span class="n">twcgi</span><span class="o">.</span><span class="n">CGIDirectory</span><span class="p">(</span><span class="s">&quot;/var/www/cgi-bin&quot;</span><span class="p">))</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">listenTCP</span><span class="p">(</span><span class="mi">80</span><span class="p">,</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">root</span><span class="p">))</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="modifying-file-resources">
<h3>Modifying File Resources<a class="headerlink" href="#modifying-file-resources" title="Permalink to this headline">¶</a></h3>
<p><code class="docutils literal"><span class="pre">File</span></code> resources, be they root object or children
thereof, have two important attributes that often need to be
modified: <code class="docutils literal"><span class="pre">indexNames</span></code>
and <code class="docutils literal"><span class="pre">processors</span></code> . <code class="docutils literal"><span class="pre">indexNames</span></code> determines which
files are treated as &#8220;index files&#8221; &#8211; served up when a directory
is rendered. <code class="docutils literal"><span class="pre">processors</span></code> determine how certain file
extensions are treated.</p>
<p>Here is an example for both, creating a site where all <code class="docutils literal"><span class="pre">.rpy</span></code>
extensions are Resource Scripts, and which renders directories by
searching for a <code class="docutils literal"><span class="pre">index.rpy</span></code> file.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.application</span> <span class="kn">import</span> <span class="n">internet</span><span class="p">,</span> <span class="n">service</span>
<span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">static</span><span class="p">,</span> <span class="n">server</span><span class="p">,</span> <span class="n">script</span>

<span class="n">root</span> <span class="o">=</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/var/www/htdocs&quot;</span><span class="p">)</span>
<span class="n">root</span><span class="o">.</span><span class="n">indexNames</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;index.rpy&#39;</span><span class="p">]</span>
<span class="n">root</span><span class="o">.</span><span class="n">processors</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;.rpy&#39;</span><span class="p">:</span> <span class="n">script</span><span class="o">.</span><span class="n">ResourceScript</span><span class="p">}</span>
<span class="n">application</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">Application</span><span class="p">(</span><span class="s">&#39;web&#39;</span><span class="p">)</span>
<span class="n">sc</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">IServiceCollection</span><span class="p">(</span><span class="n">application</span><span class="p">)</span>
<span class="n">site</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">internet</span><span class="o">.</span><span class="n">TCPServer</span><span class="p">(</span><span class="mi">80</span><span class="p">,</span> <span class="n">site</span><span class="p">)</span>
<span class="n">i</span><span class="o">.</span><span class="n">setServiceParent</span><span class="p">(</span><span class="n">sc</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal"><span class="pre">File</span></code> objects also have a method called <code class="docutils literal"><span class="pre">ignoreExt</span></code> .
This method can be used to give extension-less URLs to users, so that
implementation is hidden. Here is an example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.application</span> <span class="kn">import</span> <span class="n">internet</span><span class="p">,</span> <span class="n">service</span>
<span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">static</span><span class="p">,</span> <span class="n">server</span><span class="p">,</span> <span class="n">script</span>

<span class="n">root</span> <span class="o">=</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/var/www/htdocs&quot;</span><span class="p">)</span>
<span class="n">root</span><span class="o">.</span><span class="n">ignoreExt</span><span class="p">(</span><span class="s">&quot;.rpy&quot;</span><span class="p">)</span>
<span class="n">root</span><span class="o">.</span><span class="n">processors</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;.rpy&#39;</span><span class="p">:</span> <span class="n">script</span><span class="o">.</span><span class="n">ResourceScript</span><span class="p">}</span>
<span class="n">application</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">Application</span><span class="p">(</span><span class="s">&#39;web&#39;</span><span class="p">)</span>
<span class="n">sc</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">IServiceCollection</span><span class="p">(</span><span class="n">application</span><span class="p">)</span>
<span class="n">site</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">internet</span><span class="o">.</span><span class="n">TCPServer</span><span class="p">(</span><span class="mi">80</span><span class="p">,</span> <span class="n">site</span><span class="p">)</span>
<span class="n">i</span><span class="o">.</span><span class="n">setServiceParent</span><span class="p">(</span><span class="n">sc</span><span class="p">)</span>
</pre></div>
</div>
<p>Now, a URL such as <code class="docutils literal"><span class="pre">/foo</span></code> might be served from a Resource
Script called <code class="docutils literal"><span class="pre">foo.rpy</span></code> , if no file by the name of <code class="docutils literal"><span class="pre">foo</span></code>
exists.</p>
</div>
<div class="section" id="virtual-hosts">
<h3>Virtual Hosts<a class="headerlink" href="#virtual-hosts" title="Permalink to this headline">¶</a></h3>
<p>Virtual hosting is done via a special resource, that should be used
as the root resource
&#8211; <code class="docutils literal"><span class="pre">NameVirtualHost</span></code> . <code class="docutils literal"><span class="pre">NameVirtualHost</span></code> has an
attribute named <code class="docutils literal"><span class="pre">default</span></code> , which holds the default
website. If a different root for some other name is desired,
the <code class="docutils literal"><span class="pre">addHost</span></code> method should be called.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.application</span> <span class="kn">import</span> <span class="n">internet</span><span class="p">,</span> <span class="n">service</span>
<span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">static</span><span class="p">,</span> <span class="n">server</span><span class="p">,</span> <span class="n">vhost</span><span class="p">,</span> <span class="n">script</span>

<span class="n">root</span> <span class="o">=</span> <span class="n">vhost</span><span class="o">.</span><span class="n">NameVirtualHost</span><span class="p">()</span>

<span class="c"># Add a default -- htdocs</span>
<span class="n">root</span><span class="o">.</span><span class="n">default</span><span class="o">=</span><span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/var/www/htdocs&quot;</span><span class="p">)</span>

<span class="c"># Add a simple virtual host -- foo.com</span>
<span class="n">root</span><span class="o">.</span><span class="n">addHost</span><span class="p">(</span><span class="s">&quot;foo.com&quot;</span><span class="p">,</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/var/www/foo&quot;</span><span class="p">))</span>

<span class="c"># Add a simple virtual host -- bar.com</span>
<span class="n">root</span><span class="o">.</span><span class="n">addHost</span><span class="p">(</span><span class="s">&quot;bar.com&quot;</span><span class="p">,</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/var/www/bar&quot;</span><span class="p">))</span>

<span class="c"># The &quot;baz&quot; people want to use Resource Scripts in their web site</span>
<span class="n">baz</span> <span class="o">=</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/var/www/baz&quot;</span><span class="p">)</span>
<span class="n">baz</span><span class="o">.</span><span class="n">processors</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;.rpy&#39;</span><span class="p">:</span> <span class="n">script</span><span class="o">.</span><span class="n">ResourceScript</span><span class="p">}</span>
<span class="n">baz</span><span class="o">.</span><span class="n">ignoreExt</span><span class="p">(</span><span class="s">&#39;.rpy&#39;</span><span class="p">)</span>
<span class="n">root</span><span class="o">.</span><span class="n">addHost</span><span class="p">(</span><span class="s">&#39;baz&#39;</span><span class="p">,</span> <span class="n">baz</span><span class="p">)</span>

<span class="n">application</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">Application</span><span class="p">(</span><span class="s">&#39;web&#39;</span><span class="p">)</span>
<span class="n">sc</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">IServiceCollection</span><span class="p">(</span><span class="n">application</span><span class="p">)</span>
<span class="n">site</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">internet</span><span class="o">.</span><span class="n">TCPServer</span><span class="p">(</span><span class="mi">80</span><span class="p">,</span> <span class="n">site</span><span class="p">)</span>
<span class="n">i</span><span class="o">.</span><span class="n">setServiceParent</span><span class="p">(</span><span class="n">sc</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="advanced-techniques">
<h3>Advanced Techniques<a class="headerlink" href="#advanced-techniques" title="Permalink to this headline">¶</a></h3>
<p>Since the configuration is a Python snippet, it is possible to
use the full power of Python. Here are some simple examples:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># No need for configuration of virtual hosts -- just make sure</span>
<span class="c"># a directory /var/vhosts/&lt;vhost name&gt; exists:</span>
<span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">vhost</span><span class="p">,</span> <span class="n">static</span><span class="p">,</span> <span class="n">server</span>
<span class="kn">from</span> <span class="nn">twisted.application</span> <span class="kn">import</span> <span class="n">internet</span><span class="p">,</span> <span class="n">service</span>

<span class="n">root</span> <span class="o">=</span> <span class="n">vhost</span><span class="o">.</span><span class="n">NameVirtualHost</span><span class="p">()</span>
<span class="n">root</span><span class="o">.</span><span class="n">default</span> <span class="o">=</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/var/www/htdocs&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="nb">dir</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="s">&quot;/var/vhosts&quot;</span><span class="p">):</span>
    <span class="n">root</span><span class="o">.</span><span class="n">addHost</span><span class="p">(</span><span class="nb">dir</span><span class="p">,</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s">&quot;/var/vhosts&quot;</span><span class="p">,</span> <span class="nb">dir</span><span class="p">)))</span>

<span class="n">application</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">Application</span><span class="p">(</span><span class="s">&#39;web&#39;</span><span class="p">)</span>
<span class="n">sc</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">IServiceCollection</span><span class="p">(</span><span class="n">application</span><span class="p">)</span>
<span class="n">site</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">internet</span><span class="o">.</span><span class="n">TCPServer</span><span class="p">(</span><span class="mi">80</span><span class="p">,</span> <span class="n">site</span><span class="p">)</span>
<span class="n">i</span><span class="o">.</span><span class="n">setServiceParent</span><span class="p">(</span><span class="n">sc</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># Determine ports we listen on based on a file with numbers:</span>
<span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">vhost</span><span class="p">,</span> <span class="n">static</span><span class="p">,</span> <span class="n">server</span>
<span class="kn">from</span> <span class="nn">twisted.application</span> <span class="kn">import</span> <span class="n">internet</span><span class="p">,</span> <span class="n">service</span>

<span class="n">root</span> <span class="o">=</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/var/www/htdocs&quot;</span><span class="p">)</span>

<span class="n">site</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
<span class="n">application</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">Application</span><span class="p">(</span><span class="s">&#39;web&#39;</span><span class="p">)</span>
<span class="n">serviceCollection</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">IServiceCollection</span><span class="p">(</span><span class="n">application</span><span class="p">)</span>

<span class="k">for</span> <span class="n">num</span> <span class="ow">in</span> <span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">open</span><span class="p">(</span><span class="s">&quot;/etc/web/ports&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">()):</span>
    <span class="n">serviceCollection</span><span class="o">.</span><span class="n">addCollection</span><span class="p">(</span><span class="n">internet</span><span class="o">.</span><span class="n">TCPServer</span><span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="n">site</span><span class="p">))</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="running-a-twisted-web-server">
<h2>Running a Twisted Web Server<a class="headerlink" href="#running-a-twisted-web-server" title="Permalink to this headline">¶</a></h2>
<p>In many cases, you&#8217;ll end up repeating common usage patterns of
twisted.web. In those cases you&#8217;ll probably want to use Twisted&#8217;s
pre-configured web server setup.</p>
<p>The easiest way to run a Twisted Web server is with the Twisted Daemonizer.
For example, this command will run a web server which serves static files from
a particular directory:</p>
<div class="highlight-console"><div class="highlight"><pre><span class="gp">%</span> twistd web --path /path/to/web/content
</pre></div>
</div>
<p>If you just want to serve content from your own home directory, the
following will do:</p>
<div class="highlight-console"><div class="highlight"><pre><span class="gp">%</span> twistd web --path ~/public_html/
</pre></div>
</div>
<p>You can stop the server at any time by going back to the directory you
started it in and running the command:</p>
<div class="highlight-console"><div class="highlight"><pre><span class="gp">%</span> <span class="nb">kill</span> <span class="sb">`</span>cat twistd.pid<span class="sb">`</span>
</pre></div>
</div>
<p>Some other configuration options are available as well:</p>
<ul class="simple">
<li><code class="docutils literal"><span class="pre">--port</span></code> : Specify the port for the web
server to listen on.  This defaults to 8080.</li>
<li><code class="docutils literal"><span class="pre">--logfile</span></code> : Specify the path to the
log file.</li>
</ul>
<p>The full set of options that are available can be seen with:</p>
<div class="highlight-console"><div class="highlight"><pre><span class="gp">%</span> twistd web --help
</pre></div>
</div>
<div class="section" id="serving-flat-html">
<h3>Serving Flat HTML<a class="headerlink" href="#serving-flat-html" title="Permalink to this headline">¶</a></h3>
<p>Twisted Web serves flat HTML files just as it does any other flat file.</p>
</div>
<div class="section" id="resource-scripts">
<span id="web-howto-using-twistedweb-resourcescripts"></span><h3>Resource Scripts<a class="headerlink" href="#resource-scripts" title="Permalink to this headline">¶</a></h3>
<p>A Resource script is a Python file ending with the extension <code class="docutils literal"><span class="pre">.rpy</span></code> , which is required to create an instance of a (subclass of a) <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.resource.Resource.html">twisted.web.resource.Resource</a> .</p>
<p>Resource scripts have 3 special variables:</p>
<ul class="simple">
<li><code class="docutils literal"><span class="pre">__file__</span></code> : The name of the .rpy file, including the full path.  This variable is automatically defined and present within the namespace.</li>
<li><code class="docutils literal"><span class="pre">registry</span></code> : An object of class <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.static.Registry.html">static.Registry</a> . It can be used to access and set persistent data keyed by a class.</li>
<li><code class="docutils literal"><span class="pre">resource</span></code> : The variable which must be defined by the script and set to the resource instance that will be used to render the page.</li>
</ul>
<p>A very simple Resource Script might look like:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">resource</span>
<span class="k">class</span> <span class="nc">MyGreatResource</span><span class="p">(</span><span class="n">resource</span><span class="o">.</span><span class="n">Resource</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">render_GET</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;&lt;html&gt;foo&lt;/html&gt;&quot;</span>

<span class="n">resource</span> <span class="o">=</span> <span class="n">MyGreatResource</span><span class="p">()</span>
</pre></div>
</div>
<p>A slightly more complicated resource script, which accesses some
persistent data, might look like:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">resource</span>
<span class="kn">from</span> <span class="nn">SillyWeb</span> <span class="kn">import</span> <span class="n">Counter</span>

<span class="n">counter</span> <span class="o">=</span> <span class="n">registry</span><span class="o">.</span><span class="n">getComponent</span><span class="p">(</span><span class="n">Counter</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">counter</span><span class="p">:</span>
   <span class="n">registry</span><span class="o">.</span><span class="n">setComponent</span><span class="p">(</span><span class="n">Counter</span><span class="p">,</span> <span class="n">Counter</span><span class="p">())</span>
<span class="n">counter</span> <span class="o">=</span> <span class="n">registry</span><span class="o">.</span><span class="n">getComponent</span><span class="p">(</span><span class="n">Counter</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">MyResource</span><span class="p">(</span><span class="n">resource</span><span class="o">.</span><span class="n">Resource</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">render_GET</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
        <span class="n">counter</span><span class="o">.</span><span class="n">increment</span><span class="p">()</span>
        <span class="k">return</span> <span class="s">&quot;you are visitor </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">counter</span><span class="o">.</span><span class="n">getValue</span><span class="p">()</span>

<span class="n">resource</span> <span class="o">=</span> <span class="n">MyResource</span><span class="p">()</span>
</pre></div>
</div>
<p>This is assuming you have the <code class="docutils literal"><span class="pre">SillyWeb.Counter</span></code> module,
implemented something like the following:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Counter</span><span class="p">:</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="mi">0</span>

    <span class="k">def</span> <span class="nf">increment</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">+=</span> <span class="mi">1</span>

    <span class="k">def</span> <span class="nf">getValue</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
</pre></div>
</div>
</div>
<div class="section" id="web-uis">
<h3>Web UIs<a class="headerlink" href="#web-uis" title="Permalink to this headline">¶</a></h3>
<p>The <a class="reference external" href="https://launchpad.net/nevow">Nevow</a> framework, available as
part of the <a class="reference external" href="https://launchpad.net/quotient">Quotient</a> project,
is an advanced system for giving Web UIs to your application. Nevow uses Twisted Web but is
not itself part of Twisted.</p>
</div>
<div class="section" id="spreadable-web-servers">
<span id="web-howto-using-twistedweb-spreadablewebservers"></span><h3>Spreadable Web Servers<a class="headerlink" href="#spreadable-web-servers" title="Permalink to this headline">¶</a></h3>
<p>One of the most interesting applications of Twisted Web is the distributed webserver; multiple servers can all answer requests on the same port, using the <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.spread.html">twisted.spread</a> package for &#8220;spreadable&#8221; computing.  In two different directories, run the commands:</p>
<div class="highlight-console"><div class="highlight"><pre><span class="gp">%</span> twistd web --user
<span class="gp">%</span> twistd web --personal <span class="o">[</span>other options, <span class="k">if</span> you desire<span class="o">]</span>
</pre></div>
</div>
<p>Once you&#8217;re running both of these instances, go to <code class="docutils literal"><span class="pre">http://localhost:8080/your_username.twistd/</span></code> &#8211; you will see the front page from the server you created with the <code class="docutils literal"><span class="pre">--personal</span></code> option.  What&#8217;s happening here is that the request you&#8217;ve sent is being relayed from the central (User) server to your own (Personal) server, over a PB connection.  This technique can be highly useful for small &#8220;community&#8221; sites; using the code that makes this demo work, you can connect one HTTP port to multiple resources running with different permissions on the same machine, on different local machines, or even over the internet to a remote site.</p>
<p>By default, a personal server listens on a UNIX socket in the owner&#8217;s home
directory.  The <code class="docutils literal"><span class="pre">--port</span></code> option can be used to make
it listen on a different address, such as a TCP or SSL server or on a UNIX
server in a different location.  If you use this option to make a personal
server listen on a different address, the central (User) server won&#8217;t be
able to find it, but a custom server which uses the same APIs as the central
server might.  Another use of the <code class="docutils literal"><span class="pre">--port</span></code> option
is to make the UNIX server robust against system crashes.  If the server
crashes and the UNIX socket is left on the filesystem, the personal server
will not be able to restart until it is removed.  However, if <code class="docutils literal"><span class="pre">--port</span> <span class="pre">unix:/home/username/.twistd-web-pb:wantPID=1</span></code> is
supplied when creating the personal server, then a lockfile will be used to
keep track of whether the server socket is in use and automatically delete
it when it is not.</p>
</div>
<div class="section" id="serving-php-perl-cgi">
<h3>Serving PHP/Perl/CGI<a class="headerlink" href="#serving-php-perl-cgi" title="Permalink to this headline">¶</a></h3>
<p>Everything related to CGI is located in
the <code class="docutils literal"><span class="pre">twisted.web.twcgi</span></code> , and it&#8217;s here you&#8217;ll find the
classes that you need to subclass in order to support the language of
your (or somebody elses) taste. You&#8217;ll also need to create your own
kind of resource if you are using a non-unix operating system (such as
Windows), or if the default resources has wrong pathnames to the
parsers.</p>
<p>The following snippet is a .rpy that serves perl-files. Look at <code class="docutils literal"><span class="pre">twisted.web.twcgi</span></code>
for more examples regarding twisted.web and CGI.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">static</span><span class="p">,</span> <span class="n">twcgi</span>

<span class="k">class</span> <span class="nc">PerlScript</span><span class="p">(</span><span class="n">twcgi</span><span class="o">.</span><span class="n">FilteredScript</span><span class="p">):</span>
    <span class="nb">filter</span> <span class="o">=</span> <span class="s">&#39;/usr/bin/perl&#39;</span> <span class="c"># Points to the perl parser</span>

<span class="n">resource</span> <span class="o">=</span> <span class="n">static</span><span class="o">.</span><span class="n">File</span><span class="p">(</span><span class="s">&quot;/perlsite&quot;</span><span class="p">)</span> <span class="c"># Points to the perl website</span>
<span class="n">resource</span><span class="o">.</span><span class="n">processors</span> <span class="o">=</span> <span class="p">{</span><span class="s">&quot;.pl&quot;</span><span class="p">:</span> <span class="n">PerlScript</span><span class="p">}</span> <span class="c"># Files that end with .pl will be</span>
                                          <span class="c"># processed by PerlScript</span>
<span class="n">resource</span><span class="o">.</span><span class="n">indexNames</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;index.pl&#39;</span><span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="serving-wsgi-applications">
<h3>Serving WSGI Applications<a class="headerlink" href="#serving-wsgi-applications" title="Permalink to this headline">¶</a></h3>
<p><a class="reference external" href="http://wsgi.org">WSGI</a> is the Web Server Gateway
Interface. It is a specification for web servers and application servers to
communicate with Python web applications. All modern Python web frameworks
support the WSGI interface.</p>
<p>The easiest way to get started with WSGI application is to use the twistd
command:</p>
<div class="highlight-console"><div class="highlight"><pre><span class="gp">%</span> twistd -n web --wsgi<span class="o">=</span>helloworld.application
</pre></div>
</div>
<p>This assumes that you have a WSGI application called application in
your helloworld module/package, which might look like this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Basic WSGI Application&quot;&quot;&quot;</span>
    <span class="n">start_response</span><span class="p">(</span><span class="s">&#39;200 OK&#39;</span><span class="p">,</span> <span class="p">[(</span><span class="s">&#39;Content-type&#39;</span><span class="p">,</span><span class="s">&#39;text/plain&#39;</span><span class="p">)])</span>
    <span class="k">return</span> <span class="p">[</span><span class="s">&#39;Hello World!&#39;</span><span class="p">]</span>
</pre></div>
</div>
<p>The above setup will be suitable for many applications where all that is
needed is to server the WSGI application at the site&#8217;s root. However, for
greater control, Twisted provides support for using WSGI applications as
resources <code class="docutils literal"><span class="pre">twisted.web.wsgi.WSGIResource</span></code> .</p>
<p>Here is an example of a WSGI application being served as the root resource
for a site, in the following tac file:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">server</span>
<span class="kn">from</span> <span class="nn">twisted.web.wsgi</span> <span class="kn">import</span> <span class="n">WSGIResource</span>
<span class="kn">from</span> <span class="nn">twisted.python.threadpool</span> <span class="kn">import</span> <span class="n">ThreadPool</span>
<span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>
<span class="kn">from</span> <span class="nn">twisted.application</span> <span class="kn">import</span> <span class="n">service</span><span class="p">,</span> <span class="n">strports</span>

<span class="c"># Create and start a thread pool,</span>
<span class="n">wsgiThreadPool</span> <span class="o">=</span> <span class="n">ThreadPool</span><span class="p">()</span>
<span class="n">wsgiThreadPool</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>

<span class="c"># ensuring that it will be stopped when the reactor shuts down</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">addSystemEventTrigger</span><span class="p">(</span><span class="s">&#39;after&#39;</span><span class="p">,</span> <span class="s">&#39;shutdown&#39;</span><span class="p">,</span> <span class="n">wsgiThreadPool</span><span class="o">.</span><span class="n">stop</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;A basic WSGI application&quot;&quot;&quot;</span>
    <span class="n">start_response</span><span class="p">(</span><span class="s">&#39;200 OK&#39;</span><span class="p">,</span> <span class="p">[(</span><span class="s">&#39;Content-type&#39;</span><span class="p">,</span><span class="s">&#39;text/plain&#39;</span><span class="p">)])</span>
    <span class="k">return</span> <span class="p">[</span><span class="s">&#39;Hello World!&#39;</span><span class="p">]</span>

<span class="c"># Create the WSGI resource</span>
<span class="n">wsgiAppAsResource</span> <span class="o">=</span> <span class="n">WSGIResource</span><span class="p">(</span><span class="n">reactor</span><span class="p">,</span> <span class="n">wsgiThreadPool</span><span class="p">,</span> <span class="n">application</span><span class="p">)</span>

<span class="c"># Hooks for twistd</span>
<span class="n">application</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">Application</span><span class="p">(</span><span class="s">&#39;Twisted.web.wsgi Hello World Example&#39;</span><span class="p">)</span>
<span class="n">server</span> <span class="o">=</span> <span class="n">strports</span><span class="o">.</span><span class="n">service</span><span class="p">(</span><span class="s">&#39;tcp:8080&#39;</span><span class="p">,</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">wsgiAppAsResource</span><span class="p">))</span>
<span class="n">server</span><span class="o">.</span><span class="n">setServiceParent</span><span class="p">(</span><span class="n">application</span><span class="p">)</span>
</pre></div>
</div>
<p>This can then be run like any other .tac file:</p>
<div class="highlight-console"><div class="highlight"><pre><span class="gp">%</span> twistd -ny myapp.tac
</pre></div>
</div>
<p>Because of the synchronous nature of WSGI, each application call (for
each request) is called within a thread, and the result is written back to the
web server. For this, a <code class="docutils literal"><span class="pre">twisted.python.threadpool.ThreadPool</span></code>
instance is used.</p>
</div>
<div class="section" id="using-vhostmonster">
<h3>Using VHostMonster<a class="headerlink" href="#using-vhostmonster" title="Permalink to this headline">¶</a></h3>
<p>It is common to use one server (for example, Apache) on a site with multiple
names which then uses reverse proxy (in Apache, via <code class="docutils literal"><span class="pre">mod_proxy</span></code> ) to different
internal web servers, possibly on different machines. However, naive
configuration causes miscommunication: the internal server firmly believes it
is running on &#8220;internal-name:port&#8221; , and will generate URLs to that effect,
which will be completely wrong when received by the client.</p>
<p>While Apache has the ProxyPassReverse directive, it is really a hack
and is nowhere near comprehensive enough. Instead, the recommended practice
in case the internal web server is Twisted Web is to use VHostMonster.</p>
<p>From the Twisted side, using VHostMonster is easy: just drop a file named
(for example) <code class="docutils literal"><span class="pre">vhost.rpy</span></code> containing the following:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">vhost</span>
<span class="n">resource</span> <span class="o">=</span> <span class="n">vhost</span><span class="o">.</span><span class="n">VHostMonsterResource</span><span class="p">()</span>
</pre></div>
</div>
<p>Make sure the web server is configured with the correct processors
for the <code class="docutils literal"><span class="pre">rpy</span></code> extensions (the web server <code class="docutils literal"><span class="pre">twistd</span> <span class="pre">web</span> <span class="pre">--path</span></code> generates by default is so configured).</p>
<p>From the Apache side, instead of using the following ProxyPass directive:</p>
<div class="highlight-python"><div class="highlight"><pre>&lt;VirtualHost ip-addr&gt;
ProxyPass / http://localhost:8538/
ServerName example.com
&lt;/VirtualHost&gt;
</pre></div>
</div>
<p>Use the following directive:</p>
<div class="highlight-python"><div class="highlight"><pre>&lt;VirtualHost ip-addr&gt;
ProxyPass / http://localhost:8538/vhost.rpy/http/example.com:80/
ServerName example.com
&lt;/VirtualHost&gt;
</pre></div>
</div>
<p>Here is an example for Twisted Web&#8217;s reverse proxy:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.application</span> <span class="kn">import</span> <span class="n">internet</span><span class="p">,</span> <span class="n">service</span>
<span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">proxy</span><span class="p">,</span> <span class="n">server</span><span class="p">,</span> <span class="n">vhost</span>
<span class="n">vhostName</span> <span class="o">=</span> <span class="s">&#39;example.com&#39;</span>
<span class="n">reverseProxy</span> <span class="o">=</span> <span class="n">proxy</span><span class="o">.</span><span class="n">ReverseProxyResource</span><span class="p">(</span><span class="s">&#39;internal&#39;</span><span class="p">,</span> <span class="mi">8538</span><span class="p">,</span>
                                          <span class="s">&#39;/vhost.rpy/http/&#39;</span><span class="o">+</span><span class="n">vhostName</span><span class="o">+</span><span class="s">&#39;/&#39;</span><span class="p">)</span>
<span class="n">root</span> <span class="o">=</span> <span class="n">vhost</span><span class="o">.</span><span class="n">NameVirtualHost</span><span class="p">()</span>
<span class="n">root</span><span class="o">.</span><span class="n">addHost</span><span class="p">(</span><span class="n">vhostName</span><span class="p">,</span> <span class="n">reverseProxy</span><span class="p">)</span>
<span class="n">site</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">Site</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
<span class="n">application</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">Application</span><span class="p">(</span><span class="s">&#39;web-proxy&#39;</span><span class="p">)</span>
<span class="n">sc</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">IServiceCollection</span><span class="p">(</span><span class="n">application</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">internet</span><span class="o">.</span><span class="n">TCPServer</span><span class="p">(</span><span class="mi">80</span><span class="p">,</span> <span class="n">site</span><span class="p">)</span>
<span class="n">i</span><span class="o">.</span><span class="n">setServiceParent</span><span class="p">(</span><span class="n">sc</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="rewriting-urls">
<h2>Rewriting URLs<a class="headerlink" href="#rewriting-urls" title="Permalink to this headline">¶</a></h2>
<p>Sometimes it is convenient to modify the content of
the <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.server.Request.html">Request</a> object
before passing it on. Because this is most often used to rewrite
either the URL, the similarity to Apache&#8217;s <code class="docutils literal"><span class="pre">mod_rewrite</span></code>
has inspired the <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.rewrite.html">twisted.web.rewrite</a>
module. Using this module is done via wrapping a resource with
a <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.rewrite.RewriterResource.html">twisted.web.rewrite.RewriterResource</a> which
then has rewrite rules. Rewrite rules are functions which accept a
request object, and possible modify it. After all rewrite rules run,
the child resolution chain continues as if the wrapped resource,
rather than the <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.rewrite.RewriterResource.html">RewriterResource</a> , was the child.</p>
<p>Here is an example, using the only rule currently supplied by Twisted
itself:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">default_root</span> <span class="o">=</span> <span class="n">rewrite</span><span class="o">.</span><span class="n">RewriterResource</span><span class="p">(</span><span class="n">default</span><span class="p">,</span> <span class="n">rewrite</span><span class="o">.</span><span class="n">tildeToUsers</span><span class="p">)</span>
</pre></div>
</div>
<p>This causes the URL <code class="docutils literal"><span class="pre">/~foo/bar.html</span></code> to be treated
like <code class="docutils literal"><span class="pre">/users/foo/bar.html</span></code> . If done after setting
default&#8217;s <code class="docutils literal"><span class="pre">users</span></code> child to a <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.distrib.UserDirectory.html">distrib.UserDirectory</a> , it gives a
configuration similar to the classical configuration of web server,
common since the first NCSA servers.</p>
</div>
<div class="section" id="knowing-when-we-re-not-wanted">
<h2>Knowing When We&#8217;re Not Wanted<a class="headerlink" href="#knowing-when-we-re-not-wanted" title="Permalink to this headline">¶</a></h2>
<p>Sometimes it is useful to know when the other side has broken the connection.
Here is an example which does that:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">twisted.web.resource</span> <span class="kn">import</span> <span class="n">Resource</span>
<span class="kn">from</span> <span class="nn">twisted.web</span> <span class="kn">import</span> <span class="n">server</span>
<span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>
<span class="kn">from</span> <span class="nn">twisted.python.util</span> <span class="kn">import</span> <span class="n">println</span>


<span class="k">class</span> <span class="nc">ExampleResource</span><span class="p">(</span><span class="n">Resource</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">render_GET</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
        <span class="n">request</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;hello world&quot;</span><span class="p">)</span>
        <span class="n">d</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">notifyFinish</span><span class="p">()</span>
        <span class="n">d</span><span class="o">.</span><span class="n">addCallback</span><span class="p">(</span><span class="k">lambda</span> <span class="n">_</span><span class="p">:</span> <span class="n">println</span><span class="p">(</span><span class="s">&quot;finished normally&quot;</span><span class="p">))</span>
        <span class="n">d</span><span class="o">.</span><span class="n">addErrback</span><span class="p">(</span><span class="n">println</span><span class="p">,</span> <span class="s">&quot;error&quot;</span><span class="p">)</span>
        <span class="n">reactor</span><span class="o">.</span><span class="n">callLater</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">request</span><span class="o">.</span><span class="n">finish</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">server</span><span class="o">.</span><span class="n">NOT_DONE_YET</span>

<span class="n">resource</span> <span class="o">=</span> <span class="n">ExampleResource</span><span class="p">()</span>
</pre></div>
</div>
<p>This will allow us to run statistics on the log-file to see how many users
are frustrated after merely 10 seconds.</p>
</div>
<div class="section" id="as-is-serving">
<h2>As-Is Serving<a class="headerlink" href="#as-is-serving" title="Permalink to this headline">¶</a></h2>
<p>Sometimes, you want to be able to send headers and status
directly. While you can do this with a <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.script.ResourceScript.html">ResourceScript</a> , an easier way is to
use <a class="api reference external" href="https://twistedmatrix.com/documents/16.0.0/api/twisted.web.static.ASISProcessor.html">ASISProcessor</a> .
Use it by, for example, adding it as a processor for
the <code class="docutils literal"><span class="pre">.asis</span></code> extension. Here is a sample file:</p>
<div class="highlight-python"><div class="highlight"><pre>HTTP/1.0 200 OK
Content-Type: text/html

Hello world
</pre></div>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="../../index.html">Table Of Contents</a></h3>
            <ul>
<li><a class="reference internal" href="#">Configuring and Using the Twisted Web Server</a><ul>
<li><a class="reference internal" href="#twisted-web-development">Twisted Web Development</a><ul>
<li><a class="reference internal" href="#main-concepts">Main Concepts</a></li>
<li><a class="reference internal" href="#site-objects">Site Objects</a></li>
<li><a class="reference internal" href="#resource-objects">Resource objects</a></li>
<li><a class="reference internal" href="#resource-trees">Resource Trees</a></li>
<li><a class="reference internal" href="#rpy-scripts">.rpy scripts</a></li>
<li><a class="reference internal" href="#resource-rendering">Resource rendering</a></li>
<li><a class="reference internal" href="#request-encoders">Request encoders</a></li>
<li><a class="reference internal" href="#session">Session</a></li>
<li><a class="reference internal" href="#proxies-and-reverse-proxies">Proxies and reverse proxies</a><ul>
<li><a class="reference internal" href="#proxy">Proxy</a></li>
<li><a class="reference internal" href="#reverseproxyresource">ReverseProxyResource</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#advanced-configuration">Advanced Configuration</a><ul>
<li><a class="reference internal" href="#adding-children">Adding Children</a></li>
<li><a class="reference internal" href="#modifying-file-resources">Modifying File Resources</a></li>
<li><a class="reference internal" href="#virtual-hosts">Virtual Hosts</a></li>
<li><a class="reference internal" href="#advanced-techniques">Advanced Techniques</a></li>
</ul>
</li>
<li><a class="reference internal" href="#running-a-twisted-web-server">Running a Twisted Web Server</a><ul>
<li><a class="reference internal" href="#serving-flat-html">Serving Flat HTML</a></li>
<li><a class="reference internal" href="#resource-scripts">Resource Scripts</a></li>
<li><a class="reference internal" href="#web-uis">Web UIs</a></li>
<li><a class="reference internal" href="#spreadable-web-servers">Spreadable Web Servers</a></li>
<li><a class="reference internal" href="#serving-php-perl-cgi">Serving PHP/Perl/CGI</a></li>
<li><a class="reference internal" href="#serving-wsgi-applications">Serving WSGI Applications</a></li>
<li><a class="reference internal" href="#using-vhostmonster">Using VHostMonster</a></li>
</ul>
</li>
<li><a class="reference internal" href="#rewriting-urls">Rewriting URLs</a></li>
<li><a class="reference internal" href="#knowing-when-we-re-not-wanted">Knowing When We&#8217;re Not Wanted</a></li>
<li><a class="reference internal" href="#as-is-serving">As-Is Serving</a></li>
</ul>
</li>
</ul>

            <h4>Previous topic</h4>
            <p class="topless"><a href="web-overview.html"
                                  title="previous chapter">Overview of Twisted Web</a></p>
            <h4>Next topic</h4>
            <p class="topless"><a href="web-development.html"
                                  title="next chapter">Web Application Development</a></p>
            <h3>This Page</h3>
            <ul class="this-page-menu">
              <li><a href="../../_sources/web/howto/using-twistedweb.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">
                <p>
                <input type="text" name="q" size="18" />
                <input type="submit" value="Go" />
                <input type="hidden" name="check_keywords" value="yes" />
                <input type="hidden" name="area" value="default" />
                </p>
              </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>
    <div id="footer"><hr />
      <div>

</div>
      <p class="left2">
        Site design<br />
        By <a href="http://huw.ugbox.net/">huw.wilkins.</a>

      </p>
      <p class="right"></p>
    </div>
    <script type="text/javascript">
      if (window.location.pathname.indexOf('/current/') == -1) {
          <!-- Give the user a link to this page, but in the current version of the docs. -->
          var link = document.getElementById('current-docs-link');
          link.href = window.location.pathname.replace(/\/\d+\.\d+\.\d+/, '/current');
          <!-- And make it visible -->
          var container = document.getElementById('current-docs-container');
          container.style.display = '';
          delete link;
          delete container;
      }
    </script>
  </body>
</html>

Copyright 2K16 - 2K18 Indonesian Hacker Rulez