
<!--l. 13-->

  <p class="noindent">

  <div class="maketitle">
    <h2 class="titleHead">Mongrel2 Manual<br>
    Installing, Deploying, Managing, Hacking</h2>

    <div class="author">
      <span class="pplr7t-x-x-120">Zed A. Shaw</span><br>
      <span class="pplr7t-x-x-90">Guillermo O. &ldquo;Tordek&rdquo;
      Freschi</span>
    </div><br>

    <div class="date">
      <span class="pplr7t-x-x-120">July 2010</span>
    </div>
  </div>

  <h2 class="likechapterHead"><a id="x1-1000" name=
  "x1-1000"></a>Contents</h2>

  <div class="tableofcontents">
    <span class="chapterToc"><a href="#x1-2000" id="QQ2-1-2" name=
    "QQ2-1-2">Preface</a></span><br>
    <span class="chapterToc">1 <a href="#x1-40001" id="QQ2-1-4"
    name="QQ2-1-4">Introduction</a></span><br>
    &nbsp;<span class="sectionToc">1.1 <a href="#x1-50001.1" id=
    "QQ2-1-6" name="QQ2-1-6">Language Agnostic</a></span><br>
    &nbsp;<span class="sectionToc">1.2 <a href="#x1-60001.2" id=
    "QQ2-1-7" name="QQ2-1-7">Asynchronous</a></span><br>
    &nbsp;<span class="sectionToc">1.3 <a href="#x1-70001.3" id=
    "QQ2-1-8" name="QQ2-1-8">Message Protocol</a></span><br>
    &nbsp;<span class="sectionToc">1.4 <a href="#x1-80001.4" id=
    "QQ2-1-9" name="QQ2-1-9">Application Oriented</a></span><br>
    &nbsp;<span class="sectionToc">1.5 <a href="#x1-90001.5" id=
    "QQ2-1-10" name="QQ2-1-10">Automated Management</a></span><br>
    &nbsp;<span class="sectionToc">1.6 <a href="#x1-100001.6" id=
    "QQ2-1-11" name="QQ2-1-11">Using This Manual</a></span><br>
    <span class="chapterToc">2 <a href="#x1-110002" id="QQ2-1-12"
    name="QQ2-1-12">Installing</a></span><br>
    &nbsp;<span class="sectionToc">2.1 <a href="#x1-120002.1" id=
    "QQ2-1-13" name="QQ2-1-13">Install Dependencies</a></span><br>
    &nbsp;<span class="sectionToc">2.2 <a href="#x1-130002.2" id=
    "QQ2-1-16" name="QQ2-1-16">Building Mongrel2</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">2.2.1 <a href=
    "#x1-140002.2.1" id="QQ2-1-17" name="QQ2-1-17">Using
    Fossil</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">2.2.2 <a href=
    "#x1-150002.2.2" id="QQ2-1-19" name="QQ2-1-19">Using the .zip
    File</a></span><br>
    &nbsp;<span class="sectionToc">2.3 <a href="#x1-160002.3" id=
    "QQ2-1-20" name="QQ2-1-20">Building And
    Installing</a></span><br>
    &nbsp;<span class="sectionToc">2.4 <a href="#x1-170002.4" id=
    "QQ2-1-21" name="QQ2-1-21">Testing The
    Installation</a></span><br>
    &nbsp;<span class="sectionToc">2.5 <a href="#x1-180002.5" id=
    "QQ2-1-23" name="QQ2-1-23">Upgrading from trunk</a></span><br>
    &nbsp;<span class="sectionToc">2.6 <a href="#x1-190002.6" id=
    "QQ2-1-25" name="QQ2-1-25">Up Next</a></span><br>
    <span class="chapterToc">3 <a href="#x1-200003" id="QQ2-1-26"
    name="QQ2-1-26">Managing</a></span><br>
    &nbsp;<span class="sectionToc">3.1 <a href="#x1-210003.1" id=
    "QQ2-1-28" name="QQ2-1-28">Model-View-Controller</a></span><br>
    &nbsp;<span class="sectionToc">3.2 <a href="#x1-220003.2" id=
    "QQ2-1-29" name="QQ2-1-29">Trying m2sh</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">3.2.1 <a href=
    "#x1-230003.2.1" id="QQ2-1-32" name="QQ2-1-32">What The Hell
    Just Happened?</a></span><br>
    &nbsp;<span class="sectionToc">3.3 <a href="#x1-240003.3" id=
    "QQ2-1-33" name="QQ2-1-33">A Simple Configuration
    File</a></span><br>
    &nbsp;<span class="sectionToc">3.4 <a href="#x1-250003.4" id=
    "QQ2-1-37" name="QQ2-1-37">How A Config Is
    Structured</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">3.4.1 <a href=
    "#x1-260003.4.1" id="QQ2-1-38" name=
    "QQ2-1-38">Server</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">3.4.2 <a href=
    "#x1-270003.4.2" id="QQ2-1-39" name=
    "QQ2-1-39">Host</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">3.4.3 <a href=
    "#x1-280003.4.3" id="QQ2-1-40" name=
    "QQ2-1-40">Route</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">3.4.4 <a href=
    "#x1-290003.4.4" id="QQ2-1-41" name=
    "QQ2-1-41">Dir</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">3.4.5 <a href=
    "#x1-300003.4.5" id="QQ2-1-42" name=
    "QQ2-1-42">Proxy</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">3.4.6 <a href=
    "#x1-310003.4.6" id="QQ2-1-43" name=
    "QQ2-1-43">Handler</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">3.4.7 <a href=
    "#x1-320003.4.7" id="QQ2-1-44" name=
    "QQ2-1-44">Others</a></span><br>
    &nbsp;<span class="sectionToc">3.5 <a href="#x1-330003.5" id=
    "QQ2-1-45" name="QQ2-1-45">A More Complex
    Example</a></span><br>
    &nbsp;<span class="sectionToc">3.6 <a href="#x1-340003.6" id=
    "QQ2-1-48" name="QQ2-1-48">Routing And Host
    Patterns</a></span><br>
    &nbsp;<span class="sectionToc">3.7 <a href="#x1-350003.7" id=
    "QQ2-1-50" name="QQ2-1-50">Deployment Logs And
    Commits</a></span><br>
    &nbsp;<span class="sectionToc">3.8 <a href="#x1-360003.8" id=
    "QQ2-1-52" name="QQ2-1-52">Control Port</a></span><br>
    &nbsp;<span class="sectionToc">3.9 <a href="#x1-370003.9" id=
    "QQ2-1-54" name="QQ2-1-54">Multiple Servers</a></span><br>
    &nbsp;<span class="sectionToc">3.10 <a href="#x1-380003.10" id=
    "QQ2-1-55" name="QQ2-1-55">Tweakable Expert
    Settings</a></span><br>
    <span class="chapterToc">4 <a href="#x1-390004" id="QQ2-1-57"
    name="QQ2-1-57">Deploying</a></span><br>
    &nbsp;<span class="sectionToc">4.1 <a href="#x1-400004.1" id=
    "QQ2-1-58" name="QQ2-1-58">Mongrel2 Deployment
    Requirements</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">4.1.1 <a href=
    "#x1-410004.1.1" id="QQ2-1-60" name="QQ2-1-60">Introducing
    procer</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">4.1.2 <a href=
    "#x1-420004.1.2" id="QQ2-1-62" name="QQ2-1-62">Installing
    procer</a></span><br>
    &nbsp;<span class="sectionToc">4.2 <a href="#x1-430004.2" id=
    "QQ2-1-64" name="QQ2-1-64">The Plan</a></span><br>
    &nbsp;<span class="sectionToc">4.3 <a href="#x1-440004.3" id=
    "QQ2-1-65" name="QQ2-1-65">Step 1: The Deployment
    Area</a></span><br>
    &nbsp;<span class="sectionToc">4.4 <a href="#x1-450004.4" id=
    "QQ2-1-67" name="QQ2-1-67">Step 2: The mongrel2.org
    Configuration</a></span><br>
    &nbsp;<span class="sectionToc">4.5 <a href="#x1-460004.5" id=
    "QQ2-1-69" name="QQ2-1-69">Step 3: Setup procer</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">4.5.1 <a href=
    "#x1-470004.5.1" id="QQ2-1-74" name="QQ2-1-74">The Python
    Examples</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">4.5.2 <a href=
    "#x1-480004.5.2" id="QQ2-1-78" name="QQ2-1-78">Testing The New
    Setup</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">4.5.3 <a href=
    "#x1-490004.5.3" id="QQ2-1-80" name="QQ2-1-80">Nice Features of
    Procer</a></span><br>
    &nbsp;<span class="sectionToc">4.6 <a href="#x1-500004.6" id=
    "QQ2-1-81" name="QQ2-1-81">Step 4: Static
    Content</a></span><br>
    &nbsp;<span class="sectionToc">4.7 <a href="#x1-510004.7" id=
    "QQ2-1-83" name="QQ2-1-83">Step 5: Testing And
    Troubleshooting</a></span><br>
    &nbsp;<span class="sectionToc">4.8 <a href="#x1-520004.8" id=
    "QQ2-1-84" name="QQ2-1-84">Further Improvements</a></span><br>
    &nbsp;<span class="sectionToc">4.9 <a href="#x1-530004.9" id=
    "QQ2-1-85" name="QQ2-1-85">Deployment Tips</a></span><br>
    <span class="chapterToc">5 <a href="#x1-540005" id="QQ2-1-86"
    name="QQ2-1-86">Hacking</a></span><br>
    &nbsp;<span class="sectionToc">5.1 <a href="#x1-550005.1" id=
    "QQ2-1-88" name="QQ2-1-88">Front-end Goodies</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.1.1 <a href=
    "#x1-560005.1.1" id="QQ2-1-89" name=
    "QQ2-1-89">HTTP</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.1.2 <a href=
    "#x1-570005.1.2" id="QQ2-1-91" name=
    "QQ2-1-91">Proxying</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.1.3 <a href=
    "#x1-580005.1.3" id="QQ2-1-93" name=
    "QQ2-1-93">WebSockets</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.1.4 <a href=
    "#x1-590005.1.4" id="QQ2-1-95" name=
    "QQ2-1-95">JSSocket</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.1.5 <a href=
    "#x1-600005.1.5" id="QQ2-1-96" name="QQ2-1-96">Long
    Poll</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.1.6 <a href=
    "#x1-610005.1.6" id="QQ2-1-97" name=
    "QQ2-1-97">Streaming</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.1.7 <a href=
    "#x1-620005.1.7" id="QQ2-1-98" name="QQ2-1-98">N:M
    Responses</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.1.8 <a href=
    "#x1-630005.1.8" id="QQ2-1-99" name="QQ2-1-99">Async
    Uploads</a></span><br>
    &nbsp;<span class="sectionToc">5.2 <a href="#x1-640005.2" id=
    "QQ2-1-100" name="QQ2-1-100">Introduction to
    ZeroMQ</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.2.1 <a href=
    "#x1-650005.2.1" id="QQ2-1-101" name="QQ2-1-101">A Quick Python
    ZeroMQ Example</a></span><br>
    &nbsp;<span class="sectionToc">5.3 <a href="#x1-660005.3" id=
    "QQ2-1-107" name="QQ2-1-107">Handler ZeroMQ
    Format</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.3.1 <a href=
    "#x1-670005.3.1" id="QQ2-1-108" name="QQ2-1-108">Socket Types
    Used</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.3.2 <a href=
    "#x1-680005.3.2" id="QQ2-1-109" name="QQ2-1-109">UUID
    Addressing</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.3.3 <a href=
    "#x1-690005.3.3" id="QQ2-1-110" name="QQ2-1-110">Numbers
    Identify Listeners</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.3.4 <a href=
    "#x1-700005.3.4" id="QQ2-1-111" name="QQ2-1-111">Paths Identify
    Targets</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.3.5 <a href=
    "#x1-710005.3.5" id="QQ2-1-112" name="QQ2-1-112">Request
    Headers And Body</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.3.6 <a href=
    "#x1-720005.3.6" id="QQ2-1-113" name="QQ2-1-113">Complete
    Message Examples</a></span><br>
    &nbsp;&nbsp;<span class="subsectionToc">5.3.7 <a href=
    "#x1-730005.3.7" id="QQ2-1-116" name="QQ2-1-116">Python Handler
    API</a></span><br>
    &nbsp;<span class="sectionToc">5.4 <a href="#x1-740005.4" id=
    "QQ2-1-117" name="QQ2-1-117">Basic Handler Demo</a></span><br>
    &nbsp;<span class="sectionToc">5.5 <a href="#x1-750005.5" id=
    "QQ2-1-121" name="QQ2-1-121">Async File Upload
    Demo</a></span><br>
    &nbsp;<span class="sectionToc">5.6 <a href="#x1-760005.6" id=
    "QQ2-1-125" name="QQ2-1-125">MP3 Streaming Demo</a></span><br>
    &nbsp;<span class="sectionToc">5.7 <a href="#x1-770005.7" id=
    "QQ2-1-128" name="QQ2-1-128">Chat Demo</a></span><br>
    &nbsp;<span class="sectionToc">5.8 <a href="#x1-780005.8" id=
    "QQ2-1-129" name="QQ2-1-129">Other Language APIs</a></span><br>
    &nbsp;<span class="sectionToc">5.9 <a href="#x1-790005.9" id=
    "QQ2-1-130" name="QQ2-1-130">Writing Your Own
    m2sh</a></span><br>
    <span class="chapterToc">6 <a href="#x1-800006" id="QQ2-1-131"
    name="QQ2-1-131">Contributing</a></span>
  </div><!--l. 1-->

  <p class="noindent">

  <h2 class="chapterHead"><a id="x1-2000" name=
  "x1-2000"></a>Preface</h2><!--l. 3-->

  <p class="noindent">This manual will tell you about the most
  awesome webserver on the planet: Mongrel2. It is written for
  people with a sense of humor who want to get things done with
  Mongrel2. That means, if you're an operations professional,
  software developer, hacker or just curious, it's for you.
  However, if you're too serious and think &ldquo;flowery
  language&rdquo; (A.K.A.&nbsp;good, entertaining writing) does not
  belong in your software manuals, then you should just go read the
  source code and save everyone a huge headache dealing with you. 
  <!--l. 11-->

  <p class="noindent">In case you haven't figured it out,
  this book will be fun and slightly obnoxious. That's not
  intended to insult you, but just to keep you interested so that
  you want to read it.

  <h3 class="likesectionHead"><a id="x1-3000" name=
  "x1-3000"></a>Typography</h3><!--l. 18-->

  <p class="noindent">Usually the people running the web can be
  divided into three types of people: Steves, Edsgers, and Knuths. 
  <!--l. 21-->

  <p class="noindent">The Steves think that the entire internet
  should be a wonderful user experience where all pages are crafted
  with pixel-perfect fonts with high gloss visuals and coated with
  the most happy happy joy joy of all possible experiences. To
  them, design is paramount and actual stability isn't
  important unless it interferes with design. The Steves of the
  internet think the Edsgers of internet are destroying the
  universe with things like &ldquo;functionality&rdquo;,
  &ldquo;security&rdquo;, and &ldquo;stability&rdquo;. Just like
  the real Steve Jobs, they would rather everything look fantastic
  and then use awesome marketing to cover up any technical flaws. 
  <!--l. 31-->

  <p class="noindent">The Edsgers feel that the internet is
  completely unsafe, and until it is a fully curated and crafted
  set of academic, peer reviewed papers, it will be a festering
  pile of dung. To the Edsgers, the world is dangerous and only a
  truly paranoid attitude toward security and stability will ensure
  that it becomes safe. They want every single piece of software to
  reject all reality and be crafted from nothing but pure
  mathematics, and hate the fact that the Steves want to run around
  painting the world with useless frivolous colors and words and
  things that lead to ambiguity and happiness. <!--l. 40-->

  <p class="noindent">The typography in this book, and the entire
  project, is for the Knuths of the world. I like to think of the
  Knuths as the practical yet professional types with a light sense
  of humor. They are the ones who are getting things done while
  still balancing between great typography and solid bug-free
  functionality. They aren't zealots, but practical,
  straight-forward type of people. <!--l. 47-->

  <p class="noindent">That is why this book is written in
  <span class="TEX">T<span class="E">E</span>X</span>, and why it
  uses whatever fonts <span class="TEX">T<span class=
  "E">E</span>X</span> uses. <!--l. 21-->

  <p class="noindent">

  <h2 class="chapterHead"><span class=
  "titlemark">Chapter&nbsp;1</span><br>
  <a id="x1-40001" name="x1-40001"></a>Introduction</h2><!--l. 3-->

  <p class="noindent">Mongrel2 is a web server. HTTP requests come
  in, HTTP responses go out. Request, response. There is nothing
  revolutionary or extravagant in what Mongrel2 does with a
  browser, apart from supporting fancy asynchronous socket
  protocols. To the browser, Mongrel2 is just this nice web server
  that has WebSockets and Flash Sockets in it. That's it. 
  <!--l. 9-->

  <p class="noindent">What makes Mongrel2 special is how it
  satisfies these requests in a <span class="pplri7t-">language
  agnostic</span> and <span class="pplri7t-">asynchronous</span>
  way using a <span class="pplri7t-">simple messaging
  protocol</span> to talk to <span class=
  "pplri7t-">applications</span>; not just serve files. Mongrel2 is
  also designed to be incredibly easy to <span class=
  "pplri7t-">automatically manage</span> it as part of your
  infrastructure. <!--l. 15-->

  <p class="noindent">Other web servers do some of these things,
  but they either do them in a bastardized way or not all of them
  at once. Plenty of language specific web servers like Node.js and
  Jetty have asynchronous operation, but they're not language
  agnostic<span class="footnote-mark"><a href=
  "book-final2.html#fn1x3"><sup class=
  "textsuperscript">1</sup></a></span><a id="x1-4001f1" name=
  "x1-4001f1"></a> . Other web servers will let you talk to any
  language as a backend, but they insist on using HTTP proxying or
  FastCGI, which is <span class="pplri7t-">not</span> friendly to
  asynchronous operations. <!--l. 22-->

  <p class="noindent">Mongrel2 is the only web server I know of
  that actively tries to focus on these features as a cohesive
  whole. <!--l. 25-->

  <p class="noindent"><a id="x1-4002r1" name="x1-4002r1"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 1:</span> <span class=
      "content pplri7t-">TL;DR!</span>
    </div><!--tex4ht:label?: x1-4002r1 -->

    <div class="quote">
      <!--l. 26-->

      <p class="indent">Don't want to read the
      manual?<span class="footnote-mark"><a href=
      "book-final3.html#fn2x3"><sup class=
      "textsuperscript">2</sup></a></span><a id="x1-4003f2" name=
      "x1-4003f2"></a> You can read <a href=
      "http://mongrel2.org/wiki?name=GettingStarted">the
      GettingStarted page</a> available many languages even.
      It's a fast crash course in getting Mongrel2 up and
      running.
    </div>
  </div>
  <hr class="endfloat">

  <h3 class="sectionHead"><span class="titlemark">1.1</span> <a id=
  "x1-50001.1" name="x1-50001.1"></a>Language Agnostic</h3>
  <!--l. 33-->

  <p class="noindent">The term &ldquo;language agnostic&rdquo; came
  from people who read about Mongrel2 in the early days, and it
  means that Mongrel2 does <span class="pplri7t-">not</span> try to
  promote any one language over any others. Mongrel2 does not care
  if you run a &ldquo;Python shop&rdquo;, or if you're a die
  hard PHP fan, or if you hate PHP and love only Ruby on Rails.
  Mongrel2 only knows about HTTP requests, HTTP responses, async
  messages, and getting them to your gear to meet those
  requirements. <!--l. 40-->

  <p class="noindent">Language Agnosticism is the most important
  feature of Mongrel2, and its entire purpose stems from the desire
  to reduce the amount of programming language religion in the
  world. Real people want to get things done, not wanker on which
  technology is the best or force other people to use their
  favorite toys. Instead, Mongrel2 works to just be great for every
  language and make it easy to use what works best for a given
  problem. <!--l. 48-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">1.2</span> <a id=
  "x1-60001.2" name="x1-60001.2"></a>Asynchronous</h3><!--l. 50-->

  <p class="noindent">Many web servers are
  &ldquo;asynchronous&rdquo; internally, and some force you to know
  way too much about how they work internally to get anything done.
  What makes Mongrel2's version of asynchronous messaging
  different is that it extends to <span class=
  "pplri7t-">outside</span> the Mongrel2 server. This is a powerful
  concept that even your backends can operate asynchronously using
  simple identification of connected clients. <!--l. 56-->

  <p class="noindent">Other servers assume that every request is
  received by a browser, then sent to a backend, and then directly
  sent out to the client and that's it. Mongrel2 assumes that
  there is a connected client, and it sends requests to backends,
  but it makes no assumptions about how those backends respond to
  the clients. All it requires is that the backend application send
  messages addressed to the client and it will write them on the
  socket. <!--l. 63-->

  <p class="noindent">Because of this design, Mongrel2 can easily
  house both classic HTTP clients, keep-alive style HTTP client,
  chunked encoding responses, JSSockets, or WebSockets using the
  same code. <!--l. 68-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">1.3</span> <a id=
  "x1-70001.3" name="x1-70001.3"></a>Message Protocol</h3>
  <!--l. 70-->

  <p class="noindent">In order to properly do asynchronous
  messaging in a language agnostic way, Mongrel2 needed a good base
  protocol that allowed for different messaging styles and worked
  with many different languages. HTTP proxying already does this,
  although it's not asynchronous at all. What gives Mongrel2
  its special powers is ZeroMQ, a language- and
  transport-mechanism-agnostic messaging system that does
  <span class="pplri7t-">not</span> require a centralized messaging
  server to operate. <!--l. 77-->

  <p class="noindent">Using ZeroMQ lets Mongrel2 talk to a huge
  number of languages, operate within any kind of network
  architecture, and do it with a very simple communication model
  and API that most programmers can understand. <!--l. 82-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">1.4</span> <a id=
  "x1-80001.4" name="x1-80001.4"></a>Application Oriented</h3>
  <!--l. 84-->

  <p class="noindent">Web servers today are written as if it was
  still 1995 and all anyone needs to do is serve files, maybe some
  graphics. Today's web applications are not about serving
  files; they're about serving application logic <span class=
  "pplri7t-">and</span> doing it asynchronously. The advent of the
  bewildering numbers of ways to hack HTTP into an async messaging
  protocol<span class="footnote-mark"><a href=
  "book-final4.html#fn3x3"><sup class=
  "textsuperscript">3</sup></a></span><a id="x1-8001f3" name=
  "x1-8001f3"></a> is proof enough that the pressure is on for web
  servers to be for applications with highly interactive
  interfaces. <!--l. 92-->

  <p class="noindent">Mongrel2 can still serve files just fine. In
  fact, it's got very accurate and easy-to-understand file
  serving code. However, Mongrel2 will always be about
  applications. Fast, scalable, awesome, asynchronous or
  synchronous applications that need to use languages that mere
  mortals can work with, like PHP. If there's ever a choice,
  apps win.

  <h3 class="sectionHead"><span class="titlemark">1.5</span> <a id=
  "x1-90001.5" name="x1-90001.5"></a>Automated Management</h3>
  <!--l. 99-->

  <p class="noindent">The language agnostic philosophy even extends
  to the configuration system where you can use any language you
  need to configure it and manage it, as long as the results are a
  SQLite3 database Mongrel2 can read and work with to run. There
  are great tools for managing this database already written in
  Python, but if you hate Python then you can write anything you
  want. <!--l. 105-->

  <p class="noindent">This pattern is established with servers like
  Postfix, Exim, Sendmail, qmail, and others, that convert
  configuration files to half-assed SQL databases. Mongrel2
  effectively adopts a Model-View-Controller design for its
  configuration system, the same way every web application is
  designed today. The Model is a SQLite3 database file, which any
  programming language can access. The Controller is a Mongrel2
  process that reads this file and sets itself up accordingly. 
  <!--l. 113-->

  <p class="noindent">The View is a Python script called m2sh that
  gives you a command line &ldquo;UI&rdquo; to configure and setup
  the Mongrel2 sqlite model. It gives you commands for managing it,
  crafting configurations, looking at them; the works. 
  <!--l. 117-->

  <p class="noindent">But, most importantly, <span class=
  "pplri7t-">you can write your own</span>. You don't have to
  wait for a Mongrel2 developer to craft a configuration file
  parser for your favorite language, or use some hack job Nagios
  Perl junk to automate or scan it. It's SQLite3 with a
  solid, simple schema and well written Python code showing you how
  it works. <!--l. 123-->

  <p class="noindent">Nothing stops you from automating the hell
  out of Mongrel2 with that. <!--l. 126-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">1.6</span> <a id=
  "x1-100001.6" name="x1-100001.6"></a>Using This Manual</h3>
  <!--l. 128-->

  <p class="noindent">This manual is intended to be fun to read, so
  probably the best way to use it is to actually <span class=
  "pplri7t-">read it</span>. <!--l. 131-->

  <p class="noindent">I know! Revolutionary, right? I mean, who has
  time to read and learn about something these days. You just want
  to get in there and get whatever problem you have done, now! No
  time for words. You just want a straight dump right into your
  brain so that you are able to solve all your problems instantly
  and screw all this talking. <!--l. 136-->

  <p class="noindent">You ever ask yourself if this attitude about
  not wanting to read and learn is possibly the reason you always
  get stuck in emergencies with no time to read and learn? 
  <!--l. 140-->

  <p class="noindent">Something to think about. <!--l. 142-->

  <p class="noindent">My recommendation is that you go through
  every page of this manual and do the stuff in it. Even if you
  think you won't need something, because you're not a
  programmer, or you're not in operations, you should learn
  it. Doing so will make the parts you do need clearer and give you
  better ideas for later. <!--l. 1-->

  <p class="noindent">

  <h2 class="chapterHead"><span class=
  "titlemark">Chapter&nbsp;2</span><br>
  <a id="x1-110002" name="x1-110002"></a>Installing</h2><!--l. 3-->

  <p class="noindent">Mongrel2 is designed to build on most modern
  Unix systems, specifically Linux and Mac OSX. It is written in C
  (<span class="pplri7t-">not Ruby</span>) and uses fairly vanilla
  C and standard libraries, except for one piece that implements
  the internal coroutines. Other than this, you should be able to
  compile and install Mongrel2 with nothing more than <span class=
  "pcrro7t-">make all install</span> after you've installed
  all the dependencies. <!--l. 10-->

  <p class="noindent">Now, if when I said dependencies you started
  to groan at having to install software to use my software, well
  my friend, welcome to the future. You said you don't want
  people reinventing the wheel, right? Great, that means you need
  to install software for my software to work. It's either
  that or wait 10 years for me to build everything from scratch
  like some arrogant jackass. <!--l. 17-->

  <p class="noindent">We good now? Great, let's get started.

  <h3 class="sectionHead"><span class="titlemark">2.1</span> <a id=
  "x1-120002.1" name="x1-120002.1"></a>Install Dependencies</h3>
  <!--l. 21-->

  <p class="noindent">To get everything working you will need the
  following dependencies:

  <ul class="itemize1">
    <li class="itemize">GNU make (gmake).

    <li class="itemize"><a href="http://zeromq.org">ZeroMQ
    2.0.8</a> for the messaging.

    <li class="itemize"><a href="http://python.org">Python 2.6</a>
    for the m2sh management and examples.

    <li class="itemize"><a href=
    "http://www.sqlite.org/">SQLite3</a> and make sure <span class=
    "pplri7t-">Python</span> has the ability to access SQLite3.

    <li class="itemize"><a href=
    "http://pypi.python.org/pypi/distribute">distribute</a> and
    <a href="http://pypi.python.org/pypi/pip/0.7.2">pip</a>.

    <li class="itemize"><a href=
    "http://github.com/zeromq/pyzmq">PyZMQ</a> for the examples.

    <li class="itemize"><a href="http://webpy.org/">web.py</a> for
    the examples.
  </ul><!--l. 33-->

  <p class="noindent">If you install these things in this order,
  then everything should be good. Typically people run into
  problems if they do this out of order; for example, trying to
  install Mongrel2 before they have distribute and pip installed. 
  <!--l. 37-->

  <p class="noindent">Since every system is different, it is
  difficult to tell you exactly how to install required packages
  for your OS, but here's how I did it on my computer: 
  <!--l. 40-->

  <p class="noindent"><a id="x1-12001r2" name="x1-12001r2"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 2:</span> <span class=
      "content"><span class="pplri7t-">Use Virtualenv If You
      Fear</span> <span class="pplri7t-">Pip</span></span>
    </div><!--tex4ht:label?: x1-12001r2 -->

    <div class="quote">
      <!--l. 41-->

      <p class="indent">For those who still want to use the package
      management but want to use pip and distribute, I suggest you
      check out <a href=
      "http://pypi.python.org/pypi/virtualenv">virtualenv</a>. What
      virtualenv does is create a little &ldquo;chroot
      install&rdquo; of just the packages you need using pip or
      distribute. When you don't want them anymore, you can
      just delete one directory and you're fine.
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 49-->

  <p class="noindent"><a id="x1-12002r1" name="x1-12002r1"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 1:</span> <span class=
      "content"><span class="pplri7t-">Installing Dependencies
      on</span> <span class="pplri7t-">ArchLinux</span></span>
    </div><!--tex4ht:label?: x1-12002r1 -->
    <!--l. 50-->

    <div class="lstlisting" id="listing-1">
      <span class="label"><a id="x1-12003r1" name=
      "x1-12003r1"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">install</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ZeroMQ</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12004r2" name=
      "x1-12004r2"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">wget</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">http</span><span class=
      "pcrr7t-x-x-90">://</span><span class=
      "pcrr7t-x-x-90">www</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">zeromq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">org</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">local</span><span class=
      "pcrr7t-x-x-90">--</span><span class=
      "pcrr7t-x-x-90">files</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">area</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">download</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">zeromq</span><span class=
      "pcrr7t-x-x-90">-2.0.8.</span><span class=
      "pcrr7t-x-x-90">tar</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">gz</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12005r3" name=
      "x1-12005r3"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tar</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">xzvf</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zeromq</span><span class=
      "pcrr7t-x-x-90">-2.0.8.</span><span class=
      "pcrr7t-x-x-90">tar</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">gz</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12006r4" name=
      "x1-12006r4"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zeromq</span><span class=
      "pcrr7t-x-x-90">-2.0.8/</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12007r5" name=
      "x1-12007r5"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">./</span><span class=
      "pcrr7t-x-x-90">configure</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12008r6" name=
      "x1-12008r6"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">make</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12009r7" name=
      "x1-12009r7"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">make</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">install</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12010r8" name=
      "x1-12010r8"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12011r9" name=
      "x1-12011r9"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">install</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12012r10" name=
      "x1-12012r10"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pacman</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">S</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12013r11" name=
      "x1-12013r11"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12014r12" name=
      "x1-12014r12"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">install</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sqlite3</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12015r13" name=
      "x1-12015r13"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pacman</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">S</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sqlite3</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12016r14" name=
      "x1-12016r14"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12017r15" name=
      "x1-12017r15"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">install</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">distribute</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">and</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pip</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12018r16" name=
      "x1-12018r16"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pacman</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">S</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">pip</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12019r17" name=
      "x1-12019r17"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pip</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">install</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">distribute</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12020r18" name=
      "x1-12020r18"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12021r19" name=
      "x1-12021r19"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">install</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">PyZMQ</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">from</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">github</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12022r20" name=
      "x1-12022r20"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pacman</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">S</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">git</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12023r21" name=
      "x1-12023r21"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">git</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">clone</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">http</span><span class=
      "pcrr7t-x-x-90">://</span><span class=
      "pcrr7t-x-x-90">github</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">com</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">zeromq</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">pyzmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">git</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12024r22" name=
      "x1-12024r22"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pyzmq</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12025r23" name=
      "x1-12025r23"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">setup</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">install</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12026r24" name=
      "x1-12026r24"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12027r25" name=
      "x1-12027r25"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">web</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-12028r26" name=
      "x1-12028r26"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pip</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">install</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">web</span><span class=
      "pcrr7t-x-x-90">.</span><span class="pcrr7t-x-x-90">py</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 80-->

  <p class="noindent">If you run into parts that your OS is
  missing, which is likely on Debian and SuSE systems, then
  you'll have to go and figure out how to install it.

  <h3 class="sectionHead"><span class="titlemark">2.2</span> <a id=
  "x1-130002.2" name="x1-130002.2"></a>Building Mongrel2</h3>
  <!--l. 87-->

  <p class="noindent">If everything went well you should be able to
  grab the Mongrel2 source and try building it. There's two
  ways you can get the source code to Mongrel2: <!--l. 91-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-13002x1">Install <a href=
    "http://fossil-scm.org">Fossil SCM</a> and check out the
    source.

    <li class="enumerate" id="x1-13004x2">Grab the source .zip
    release and install it from there.
  </ol><!--l. 96-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">2.2.1</span>
  <a id="x1-140002.2.1" name="x1-140002.2.1"></a>Using Fossil</h4>
  <!--l. 98-->

  <p class="noindent">Since it's early in Mongrel2
  development, we recommend you get fossil and install it so you
  can track the latest fixes and development. Here's the
  easiest way to do that: <!--l. 102-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-14002x1">Go to <a href=
    "http://www.fossil-scm.org/download.html">the fossil download
    page</a> and grab the binary that fits your system, or the
    source tar.gz.

    <li class="enumerate" id="x1-14004x2">Follow their <a href=
    "http://fossil-scm.org/index.html/doc/tip/www/build.wiki">install
    instructions</a> to get it on your system.

    <li class="enumerate" id="x1-14006x3">If you find that your
    version of fossil ends up having problems with mongrel2.org let
    us know since we might need to upgrade.
  </ol><!--l. 111-->

  <p class="noindent">Once you have fossil you can then get the
  Mongrel2 source and open it up: <!--l. 113-->

  <p class="noindent"><a id="x1-14007r2" name="x1-14007r2"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 2:</span> <span class=
      "content"><span class="pplri7t-">Cloning the Mongrel2</span>
      <span class="pplri7t-">Source</span></span>
    </div><!--tex4ht:label?: x1-14007r2 -->
    <!--l. 114-->

    <div class="lstlisting" id="listing-2">
      <span class="label"><a id="x1-14008r1" name=
      "x1-14008r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mkdir</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">~/</span><span class=
      "pcrr7t-x-x-90">fossils</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-14009r2" name=
      "x1-14009r2"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">fossil</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">clone</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">http</span><span class=
      "pcrr7t-x-x-90">://</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">org</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">~/</span><span class=
      "pcrr7t-x-x-90">fossils</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">fossil</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-14010r3" name=
      "x1-14010r3"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mkdir</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-14011r4" name=
      "x1-14011r4"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-14012r5" name=
      "x1-14012r5"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">fossil</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">open</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">~/</span><span class=
      "pcrr7t-x-x-90">fossils</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">fossil</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 123-->

  <p class="noindent">Make sure you do this in order (just like
  with every set of instructions you follow) or else you'll
  get errors. For example, if you don't make the <span class=
  "pcrb7t-">~/fossils</span> directory then you'll get an
  error saying fossil can't open your file to clone. Well,
  that's because you <span class="pplri7t-">didn't make
  the ~/fossils directory</span>. Just pay attention and
  don't blame fossil if you can't.

  <h4 class="subsectionHead"><span class="titlemark">2.2.2</span>
  <a id="x1-150002.2.2" name="x1-150002.2.2"></a>Using the .zip
  File</h4><!--l. 132-->

  <p class="noindent">If you don't want to install fossil
  then you will need to get the .zip file from our site and install
  it that way. Since the code is new, you have <span class=
  "pplri7t-">no guarantees</span> that this will work at all or
  that you will get a stable server. We have not made an official
  release, so using the .zip file is effectively a lame way of
  avoiding using fossil. <!--l. 138-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-15002x1">Login as an anonymous
    user <a href="http://mongrel2.org/login">at mongrel2.org</a>.

    <li class="enumerate" id="x1-15004x2">Go to the <a href=
    "http://mongrel2.org/info/tip">latest source tip</a>.

    <li class="enumerate" id="x1-15006x3">Click on the &ldquo;ZIP
    archive&rdquo; link to download the latest zip file of the
    source.

    <li class="enumerate" id="x1-15008x4">Unzip this file and cd
    into the resulting directory.
  </ol><!--l. 146-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">2.3</span> <a id=
  "x1-160002.3" name="x1-160002.3"></a>Building And Installing</h3>
  <!--l. 148-->

  <p class="noindent">Once you have the source ready to go you can
  build it and then install it with one command: <span class=
  "pcrro7t-">make all install</span> <!--l. 151-->

  <p class="noindent">There is no <span class=
  "pcrro7t-">./configure</span> for Mongrel2 since we avoid too
  many OS specific differences or shield those away with good
  feature checks in the code. <!--l. 154-->

  <p class="noindent">The end result of this should be: 
  <!--l. 156-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-16002x1">Mongrel2 builds and
    compiles without errors.

    <li class="enumerate" id="x1-16004x2">All the unit tests
    run.<span class="footnote-mark"><a href=
    "book-final5.html#fn1x4"><sup class=
    "textsuperscript">1</sup></a></span><a id="x1-16005f1" name=
    "x1-16005f1"></a>

    <li class="enumerate" id="x1-16007x3">The Python libraries that
    m2sh needs get installed.

    <li class="enumerate" id="x1-16009x4">The m2sh itself gets
    installed.

    <li class="enumerate" id="x1-16011x5">Finally, the mongrel2
    binary gets installed.
  </ol><!--l. 164-->

  <p class="noindent">If any of these stages fail, then you can
  simply try to fix them and then run: <span class=
  "pcrro7t-">make</span> <span class="pcrro7t-">clean all
  install</span> which will do everything all over again. 
  <!--l. 167-->

  <p class="noindent">The most common error is if you didn't
  install pip or distribute and insist on using your own
  system's package management. Do <span class=
  "pplri7t-">not</span> report bugs about your own flavor of
  Linux's stupidity about versions and how it installs
  Python. If you don't want to use the package system every
  other Python programmer uses, then you're on your own. 
  <!--l. 174-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">2.4</span> <a id=
  "x1-170002.4" name="x1-170002.4"></a>Testing The
  Installation</h3><!--l. 176-->

  <p class="noindent">When you are done, you probably want to make
  sure that it installed correctly. There's a test
  configuration file in <span class=
  "pcrb7t-">tests/config.sqlite</span> that you can use to try it
  out: <!--l. 180-->

  <p class="noindent"><a id="x1-17001r3" name="x1-17001r3"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 3:</span> <span class=
      "content"><span class="pplri7t-">First Test</span>
      <span class="pplri7t-">Run</span></span>
    </div><!--tex4ht:label?: x1-17001r3 -->
    <!--l. 181-->

    <div class="lstlisting" id="listing-3">
      <span class="label"><a id="x1-17002r1" name=
      "x1-17002r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mkdir</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-17003r2" name=
      "x1-17003r2"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mkdir</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">logs</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-17004r3" name=
      "x1-17004r3"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mkdir</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tmp</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-17005r4" name=
      "x1-17005r4"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">dump</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-17006r5" name=
      "x1-17006r5"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">start</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 190-->

  <p class="noindent">That's it. Just hit CTRL-c for now and
  we'll get into playing with this setup later.

  <h3 class="sectionHead"><span class="titlemark">2.5</span> <a id=
  "x1-180002.5" name="x1-180002.5"></a>Upgrading from trunk</h3>
  <!--l. 194-->

  <p class="noindent"><a id="x1-18001r4" name="x1-18001r4"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 4:</span> <span class=
      "content"><span class="pplri7t-">Update your</span>
      <span class="pplri7t-">checkout</span></span>
    </div><!--tex4ht:label?: x1-18001r4 -->
    <!--l. 195-->

    <div class="lstlisting" id="listing-4">
      <span class="label"><a id="x1-18002r1" name=
      "x1-18002r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-18003r2" name=
      "x1-18003r2"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">fossil</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pull</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">http</span><span class=
      "pcrr7t-x-x-90">://</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">org</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-18004r3" name=
      "x1-18004r3"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">fossil</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">update</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 202-->

  <p class="noindent">Don't forget <span class=
  "pcrro7t-">make clean all install</span>.

  <h3 class="sectionHead"><span class="titlemark">2.6</span> <a id=
  "x1-190002.6" name="x1-190002.6"></a>Up Next</h3><!--l. 207-->

  <p class="noindent">You now should have a working Mongrel2 system
  installed and the m2sh configuration interface ready to go. In
  the rest of this manual we'll be simply learning how to do
  more with Mongrel2, like making our own configs, writing
  handlers, and other fun stuff.

  <h2 class="chapterHead"><span class=
  "titlemark">Chapter&nbsp;3</span><br>
  <a id="x1-200003" name="x1-200003"></a>Managing</h2><!--l. 3-->

  <p class="noindent">Mongrel2 is designed to be easy to deploy and
  <span class="pplri7t-">automate</span> the deployment. This is
  why it uses <a href="http://www.sqlite.org/">SQLite</a> to store
  the configuration, but m2sh as an interface to creating the
  configuration. Doing this lets you access the configuration using
  any language that works for you, augment it, alter it, migrate it
  and automate it. <!--l. 9-->

  <p class="noindent">In this chapter, I'm going to show you
  how to make a basic configuration using m2sh and all the commands
  that are available. You'll learn how the configuration
  system is structured so that you know what goes where, but in the
  end it's just a simple storage mechanism. <!--l. 14-->

  <p class="noindent"><a id="x1-20001r3" name="x1-20001r3"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 3:</span> <span class=
      "content"><span class="pplri7t-">Apparently SQL
      Inspires</span> <span class="pplri7t-">FUD</span></span>
    </div><!--tex4ht:label?: x1-20001r3 -->

    <div class="quote">
      <!--l. 15-->

      <p class="indent">When I first started talking about
      Mongrel2, I said I'd store the configuration in SQLite
      and do a Model-View-Controller kind of design. Immediately
      people who can't read flipped out and thought this
      meant they'd be back in &ldquo;Windows registry
      hell&rdquo;, but with SQL as their only way to access it.
      They thought that they'd be stuck writing
      configurations with SQL; that SQL couldn't possibly
      configure a web server. <!--l. 21-->

      <p class="indent">They were wrong on many levels. Nobody was
      <span class="pplri7t-">ever</span> going to make <span class=
      "pplri7t-">anyone</span> use SQL. That was repeated over and
      over but, again, people don't read and love spreading
      FUD. The SQLite config database is nothing like the Windows
      Registry. No other web server really uses a true hierarchy;
      they just cram a relational model into a weirdo configuration
      format. The real goal was to make a web server that was easy
      to manage from <span class="pplri7t-">any</span> language,
      and then give people a nice tool to get their job done
      without having to ever touch SQL. <span class=
      "pplri7t-">EVER!</span> <!--l. 29-->

      <p class="indent">In the end, what we got despite all this
      fear mongering is a bad ass configuration tool and a design
      that is simple, elegant, and works fantastic. If you read
      that Mongrel2 uses SQLite and though this was weird, well,
      welcome to the future. Sometimes it's weird out here
      (even though Postfix has been doing this for a decade or
      more).
    </div>
  </div>
  <hr class="endfloat">

  <h3 class="sectionHead"><span class="titlemark">3.1</span> <a id=
  "x1-210003.1" name="x1-210003.1"></a>Model-View-Controller</h3>
  <!--l. 38-->

  <p class="noindent">When you hear Model-View-Controller, you
  think about web applications. This is a design pattern where you
  place different concerns into different parts of your system and
  try not to mix them too much. For an interactive application, if
  you keep the part that stores data (Model) separated from the
  logic (Controller) and use another piece to display and interact
  with the user (View), then it's easier to change the system
  and adapt it over time to new features. <!--l. 44-->

  <p class="noindent">The power of MVC is simply that these things
  really are separate orthogonal pieces that get ugly if
  they're mixed together. There's no math or theory
  that says why; just lots of experience has told us it's
  usually a bad idea. When you start mixing them, you find out that
  it's hard to change for new requirements later, because
  you've sprinkled logic all over your web pages. Or you
  can't update your database because there's all these
  stored procedures that assume the tables are a certain way. 
  <!--l. 51-->

  <p class="noindent">Mongrel2 needed a way to allow you to use
  various languages and tools to automate its configuration.
  Letting you automate your deployments is the entire point of the
  server. The idea was that if we gave you the Controller and the
  Model, then you can craft any <span class="pplri7t-">View</span>
  you wanted, and there's no better Model than a SQL database
  like SQLite: it's embeddable, easily accessed from C or any
  language, portable, small, fast enough and full of all the
  features you need and then some. <!--l. 57-->

  <p class="noindent">What you are doing when you use m2sh to
  configure a configuration for Mongrel2, is working with a View
  we've given you to create a Model for the Mongrel2 server
  to work with. That's it, and you can create your own View
  if you want. It could be automated deployment scripts, a web
  interface, monitoring scripts, anything you need. <!--l. 62-->

  <p class="noindent">The point is, if you just want to get
  Mongrel2 up and running, then use m2sh. If you want to do more
  advanced stuff, then get into the configuration database schema
  and see what you can do. The structure of the database very
  closely matches Mongrel2's internal structure, so
  understanding that means you understand how Mongrel2 works. This
  is a vast improvement over other web servers like Apache where
  you've got no idea why one stanza has to go in a particular
  place, or why information has to be duplicated. <!--l. 69-->

  <p class="noindent">With Mongrel2, it's all right there. 
  <!--l. 72-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">3.2</span> <a id=
  "x1-220003.2" name="x1-220003.2"></a>Trying m2sh</h3><!--l. 74-->

  <p class="noindent">To give this configuration system a try you
  just need to run the test configuration used in the unit tests.
  Let's try doing a few of the most basic commands with this
  configuration: <!--l. 77-->

  <p class="noindent"><a id="x1-22001r5" name="x1-22001r5"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 5:</span> <span class=
      "content"><span class="pplri7t-">Sample m2sh</span>
      <span class="pplri7t-">Commands</span></span>
    </div><!--tex4ht:label?: x1-22001r5 -->
    <!--l. 78-->

    <div class="lstlisting" id="listing-5">
      <span class="label"><a id="x1-22002r1" name=
      "x1-22002r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">dump</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-22003r2" name=
      "x1-22003r2"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">servers</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-22004r3" name=
      "x1-22004r3"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">hosts</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-22005r4" name=
      "x1-22005r4"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">running</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-22006r5" name=
      "x1-22006r5"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">start</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 87-->

  <p class="noindent">At this point you should have seen some raw
  dumps of the database, lists of servers and hosts, seen that
  mongrel2 is not running, and then started it. You can find out
  about all the commands and get help for them with <span class=
  "pcrro7t-">m2sh help</span> or <span class="pcrro7t-">ms2h
  help</span> <span class="pcrro7t-">-for command</span>. 
  <!--l. 91-->

  <p class="noindent">You can now try doing some simple starting,
  stopping and reloading using sudo (make sure you CTRL-c to exit
  from the previous start command): <!--l. 94-->

  <p class="noindent"><a id="x1-22007r6" name="x1-22007r6"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 6:</span> <span class=
      "content"><span class="pplri7t-">Starting, Stopping,</span>
      <span class="pplri7t-">Reloading</span></span>
    </div><!--tex4ht:label?: x1-22007r6 -->
    <!--l. 95-->

    <div class="lstlisting" id="listing-6">
      <span class="label"><a id="x1-22008r1" name=
      "x1-22008r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">start</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-22009r2" name=
      "x1-22009r2"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tail</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">logs</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">error</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-22010r3" name=
      "x1-22010r3"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">reload</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-22011r4" name=
      "x1-22011r4"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tail</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">logs</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">error</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-22012r5" name=
      "x1-22012r5"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">curl</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">http</span><span class=
      "pcrr7t-x-x-90">://</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">:6767/</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-22013r6" name=
      "x1-22013r6"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tail</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">logs</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">error</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-22014r7" name=
      "x1-22014r7"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">running</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-22015r8" name=
      "x1-22015r8"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">stop</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 107-->

  <p class="noindent">Awesome, right? Using just this one little
  Python management script, you are able to completely manage a
  Mongrel2 instance without having to hack on a config file at all.
  But you probably need to know how this is all working anyway.

  <h4 class="subsectionHead"><span class="titlemark">3.2.1</span>
  <a id="x1-230003.2.1" name="x1-230003.2.1"></a>What The Hell Just
  Happened?</h4><!--l. 115-->

  <p class="noindent">You now have done nearly everything you can
  to a configuration, but you might not know exactly what's
  going on. Here's an explanation of what's going on
  behind the scenes: <!--l. 118-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-23002x1">When you did <span class=
    "pcrro7t-">m2sh start</span> with the <span class=
    "pcrro7t-">-sudo</span> option, it actually runs <span class=
    "pcrro7t-">sudo mongrel2 tests/config.sqlite localhost</span>
    to start the server.

    <li class="enumerate" id="x1-23004x2">Mongrel2 is now running
    in the background as a daemon process, just like a regular
    server. However, what it did was chroot to the current
    directory and then drop privileges so that they match the owner
    of that directory (you). Use <span class="pcrro7t-">ps
    aux</span> to take a look.

    <li class="enumerate" id="x1-23006x3">With Mongrel2 running,
    you can look in the logs/error.log file to see what it said. It
    should be a bunch of debug logging, but check out the messages:
    nice and detailed.

    <li class="enumerate" id="x1-23008x4">Next you did a soft
    reload with <span class="pcrro7t-">m2sh reload</span> and you
    should notice that your mongrel2 process was able to load the
    new config <span class="pplri7t-">without</span> <span class=
    "pplri7t-">restarting</span>.

    <li class="enumerate" id="x1-23010x5">However, there's a
    slight bug that doesn't do the reload until the next
    request is served. That's what the <span class=
    "pcrro7t-">curl http://localhost:6767/</span> was for.

    <li class="enumerate" id="x1-23012x6">Now that you can see this
    reload work in <span class="pcrb7t-">logs/error.log</span>, you
    used <span class="pcrro7t-">m2sh running</span> to see if
    it's running. This command is just reading the config
    database to find out where the PID file is (<span class=
    "pcrb7t-">run/mongrel2.pid</span>) and then checking if that
    process is running.

    <li class="enumerate" id="x1-23014x7">Finally, you tell
    mongrel2 to stop, and since it dropped privileges to be owned
    by you, you can do that without having to use sudo.
  </ol><!--l. 137-->

  <p class="noindent">All of this is happening by reading the
  <span class="pcrb7t-">tests/config.sqlite</span> file and not
  reading any configuration files. You can now try building your
  own configuration that matches this one or some others. 
  <!--l. 141-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">3.3</span> <a id=
  "x1-240003.3" name="x1-240003.3"></a>A Simple Configuration
  File</h3><!--l. 143-->

  <p class="noindent">To configure a new config database
  you'll write a Python file that looks a lot like a
  configuration file. The advantage of using Python is that you can
  put actual real logic in your configuration file in order to make
  your configuration smarter. A great application of this is when
  your configuration has to change depending on the server it is
  deployed on, but you want to check the configuration file into a
  revision control system. With Python you just write your
  configuration like it's code and you're set. 
  <!--l. 151-->

  <p class="noindent">The first thing you need to do is initialize
  a fresh configuration database to get started by using
  <span class="pcrro7t-">m2sh init</span> and then you load your
  configuration into it using <span class="pcrro7t-">m2sh
  load</span>. For our example, we'll use the example
  configuration from <span class=
  "pcrb7t-">examples/python/tests/sample</span><span class=
  "pcrb7t-">_conf.py</span> to make a simple one: <!--l. 156-->

  <p class="noindent"><a id="x1-24001r7" name="x1-24001r7"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 7:</span> <span class=
      "content"><span class="pplri7t-">Simple Little Config</span>
      <span class="pplri7t-">Example</span></span>
    </div><!--tex4ht:label?: x1-24001r7 -->
    <!--l. 157-->

    <div class="lstinputlisting">
      <a id="x1-24002" name="x1-24002"></a> <span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24003r1" name=
      "x1-24003r1"></a></span><span class=
      "pcrb7t-x-x-90">from</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&#8902;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24004r2" name=
      "x1-24004r2"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24005r3" name=
      "x1-24005r3"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24006r4" name=
      "x1-24006r4"></a></span><span class=
      "pcrr7t-x-x-90">main</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Server</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24007r5" name=
      "x1-24007r5"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">uuid</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">f400bf85</span><span class=
      "pcrr7t-x-x-90">-4538-4</span><span class=
      "pcrr7t-x-x-90">f7a</span><span class=
      "pcrr7t-x-x-90">-8908-67</span><span class=
      "pcrr7t-x-x-90">e313d515c2</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24008r6" name=
      "x1-24008r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">access_log</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">logs</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">access</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24009r7" name=
      "x1-24009r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">error_log</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">logs</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">error</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24010r8" name=
      "x1-24010r8"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chroot</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">./</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24011r9" name=
      "x1-24011r9"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">default_host</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24012r10" name=
      "x1-24012r10"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">name</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">test</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24013r11" name=
      "x1-24013r11"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pid_file</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24014r12" name=
      "x1-24014r12"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">port</span><span class=
      "pcrr7t-x-x-90">=6767,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24015r13" name=
      "x1-24015r13"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">hosts</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&#91;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24016r14" name=
      "x1-24016r14"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Host</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">name</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">routes</span><span class=
      "pcrr7t-x-x-90">={</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24017r15" name=
      "x1-24017r15"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Dir</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">base</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">index_file</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">index</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">html</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24018r16" name=
      "x1-24018r16"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">default_ctype</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">text</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">plain</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24019r17" name=
      "x1-24019r17"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">})</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24020r18" name=
      "x1-24020r18"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24021r19" name=
      "x1-24021r19"></a></span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24022r20" name=
      "x1-24022r20"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24023r21" name=
      "x1-24023r21"></a></span><span class=
      "pcrr7t-x-x-90">commit</span><span class=
      "pcrr7t-x-x-90">(&#91;</span><span class=
      "pcrr7t-x-x-90">main</span><span class=
      "pcrr7t-x-x-90">&#93;)</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 160-->

  <p class="noindent">If you aren't familiar with Python then
  this code might look freaky, but it's really simple.
  We'll get into how its structured in a second, but to load
  this file we would just do this: <!--l. 164-->

  <p class="noindent"><a id="x1-24027r8" name="x1-24027r8"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 8:</span> <span class=
      "content"><span class="pplri7t-">Loading The Simple</span>
      <span class="pplri7t-">Config</span></span>
    </div><!--tex4ht:label?: x1-24027r8 -->
    <!--l. 165-->

    <div class="lstlisting" id="listing-7">
      <span class="label"><a id="x1-24028r1" name=
      "x1-24028r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">init</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">simple</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24029r2" name=
      "x1-24029r2"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">load</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">simple</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">sample_conf</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24030r3" name=
      "x1-24030r3"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">servers</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">simple</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24031r4" name=
      "x1-24031r4"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">hosts</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">simple</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-24032r5" name=
      "x1-24032r5"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">start</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">simple</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 174-->

  <p class="noindent">With this sequence of commands you:

  <ol class="enumerate1">
    <li class="enumerate" id="x1-24034x1">Create a raw fresh config
    database name <span class="pcrb7t-">simple.sqlite</span>

    <li class="enumerate" id="x1-24036x2">Load the <span class=
    "pcrb7t-">sample</span><span class="pcrb7t-">_conf.py</span>
    into it.

    <li class="enumerate" id="x1-24038x3">List the servers it has
    configured.

    <li class="enumerate" id="x1-24040x4">List the hosts that
    server has, with what routes it has.

    <li class="enumerate" id="x1-24042x5">Start this server to try
    it out.
  </ol><!--l. 184-->

  <p class="noindent">By now you should be getting the hang of the
  pattern here, which is to use m2sh and little Python
  configuration &ldquo;script&rdquo; to generate .sqlite files that
  Mongrel2 understands.

  <h3 class="sectionHead"><span class="titlemark">3.4</span> <a id=
  "x1-250003.4" name="x1-250003.4"></a>How A Config Is
  Structured</h3><!--l. 190-->

  <p class="noindent">The base structure of a Mongrel2
  configuration is:

  <dl class="description">
    <dt class="description"><span class="pplb7t-">Server</span>

    <dd class="description">
      This is the root of a config, and you can have multiples of
      these in one database, even though each start command only
      runs one at a time.

      <dl class="description">
        <dt class="description"><span class="pplb7t-">Host</span>

        <dd class="description">
          Servers have Hosts inside them, which say what DNS
          hostname Mongrel2 should answer for. You can have
          multiples of these in each Server.

          <dl class="description">
            <dt class="description"><span class=
            "pplb7t-">Route</span>

            <dd class="description">
              Hosts have Routes in them, which tells Mongrel2 what
              to do with URL paths and patterns that match them.
              Routes then have <span class="pcrro7t-">Dir</span>,
              <span class="pcrro7t-">Handler</span> or <span class=
              "pcrro7t-">Proxy</span> items in them.

              <dl class="description">
                <dt class="description"><span class=
                "pplb7t-">Dir</span>

                <dd class="description">A Dir serves files out of a
                directory, full with 304 and ETag support, default
                content types, and most of the things you need to
                serve them.

                <dt class="description"><span class=
                "pplb7t-">Proxy</span>

                <dd class="description">A Proxy takes requests
                matching the Route they're attached to and
                sends them to another HTTP server somewhere else.
                Mongrel2 will then act as a full proxy and also try
                to keep connections open in keep-alive mode if the
                browser supports it.

                <dt class="description"><span class=
                "pplb7t-">Handler</span>

                <dd class="description">A Handler is the best part
                of Mongrel2. It takes HTTP requests, and turns them
                into nicely packed and processed ZeroMQ messages
                for your asynchronous handlers.
              </dl>
            </dl>
        </dl>
    </dl><!--l. 214-->

  <p class="noindent">Each of these nested &ldquo;objects&rdquo;
  then has a set of attributes you can use to configure them, and
  most of them have reasonable defaults. <!--l. 218-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">3.4.1</span>
  <a id="x1-260003.4.1" name="x1-260003.4.1"></a>Server</h4>
  <!--l. 220-->

  <p class="noindent">The server is all about telling Mongrel2
  where to listen on its port, where to chroot, and general server
  specific deployment gear.

  <dl class="description">
    <dt class="description"><span class="pplb7t-">uuid</span>

    <dd class="description">A UUID is used to make sure that each
    deployed server is unique in your infrastructure. You could
    easily use any string that's letters, numbers, or -
    characters.

    <dt class="description"><span class="pplb7t-">chroot</span>

    <dd class="description">This is the directory that Mongrel2
    should chroot to and drop privileges.

    <dt class="description"><span class=
    "pplb7t-">access</span><span class="pplb7t-">_log</span>

    <dd class="description">The access log file <span class=
    "pplri7t-">relative to the chroot</span>. Usually starts with a
    `/'. Make sure you don't configure your
    server so that this and other files are accessible, or make
    this owned by root.

    <dt class="description"><span class=
    "pplb7t-">error</span><span class="pplb7t-">_log</span>

    <dd class="description">The error log file just like
    access_log.

    <dt class="description"><span class=
    "pplb7t-">pid</span><span class="pplb7t-">_file</span>

    <dd class="description">Like the access log, where within the
    chroot directory is the pid file stored.

    <dt class="description"><span class=
    "pplb7t-">default</span><span class="pplb7t-">_host</span>

    <dd class="description">The server has a bunch of hosts listed,
    but it needs to know what the default host is. This is also
    used as a convenient way to refer to this Server.

    <dt class="description"><span class="pplb7t-">port</span>

    <dd class="description">The port the server should listen on
    for new connections.
  </dl><!--l. 237-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">3.4.2</span>
  <a id="x1-270003.4.2" name="x1-270003.4.2"></a>Host</h4>
  <!--l. 239-->

  <p class="noindent">A host is matched using a kind of
  <span class="pplri7t-">inverse route</span> that matches the
  ending of <span class="pcrro7t-">Host:</span> headers against a
  pattern. You'll see how this works when we talk about
  routes, but for now you just need to know that request to the
  <span class="pcrro7t-">Server.port</span> are routed based on
  these <span class="pcrro7t-">Host</span> configurations the
  <span class="pcrro7t-">Server</span> contains.

  <dl class="description">
    <dt class="description"><span class="pplb7t-">name</span>

    <dd class="description">The name that you use to talk about
    this Host in the server configuration.

    <dt class="description"><span class="pplb7t-">matching</span>

    <dd class="description">This is a pattern that's used to
    match incoming Host headers for routing purposes.

    <dt class="description"><span class="pplb7t-">server</span>

    <dd class="description">If you want to set the server
    separately you can use this attribute.

    <dt class="description"><span class=
    "pplb7t-">maintenance</span>

    <dd class="description">This will a setting for the future that
    will let you have Mongrel2 throw up a maintenance page for this
    host.

    <dt class="description"><span class="pplb7t-">routes</span>

    <dd class="description">This is a dict (hashmap) of the URL
    patterns mapped to the targets that should be run.
  </dl><!--l. 254-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">3.4.3</span>
  <a id="x1-280003.4.3" name="x1-280003.4.3"></a>Route</h4>
  <!--l. 256-->

  <p class="noindent">The <span class="pcrro7t-">Route</span> is
  the workhorse of the whole system. It uses some very fancy but
  still simple code in Mongrel2 to translate <span class=
  "pcrro7t-">Host:</span> headers to <span class=
  "pcrro7t-">Hosts</span> and URL paths to <span class=
  "pcrro7t-">Handlers</span>, <span class="pcrro7t-">Dirs</span>,
  and <span class="pcrro7t-">Proxies</span>.

  <dl class="description">
    <dt class="description"><span class="pplb7t-">path</span>

    <dd class="description">This is path <span class=
    "pplri7t-">pattern</span> that matches a route. The pattern
    uses the Mongrel2 pattern langauge which is a reduced version
    of the Lua pattern matching system.

    <dt class="description"><span class="pplb7t-">reversed</span>

    <dd class="description">Determines if this pattern is reversed,
    which is useful for matching file extensions, hostnames, and
    other naming systems where the ending is really the prefix.
    Usually you don't set this.

    <dt class="description"><span class="pplb7t-">host</span>

    <dd class="description">You can use this attribute to set the
    host manually.

    <dt class="description"><span class="pplb7t-">target</span>

    <dd class="description">This is the target that should handle
    the request, either a <span class="pcrro7t-">Dir</span>,
    <span class="pcrro7t-">Handler</span> or <span class=
    "pcrro7t-">Proxy</span>.
  </dl><!--l. 269-->

  <p class="noindent">Later on, you'll learn about the
  pattern matching that's used, but it's basically a
  stripped down version of your normal regular expressions, but
  with a few convenient syntaxes for doing simple string matching.
  When you configure a route, you write something like <span class=
  "pcrb7t-">/images/(.&#8902;.jpg)</span> and the part before the
  `(' is used as a fast matched prefix, while the part
  after it is considered a pattern to match. When a request comes
  in, Mongrel2 quickly finds the longest prefix that matches the
  URL, and then tests its pattern if there is one. If the pattern
  is valid, the request goes through. If not, 404. <!--l. 277-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">3.4.4</span>
  <a id="x1-290003.4.4" name="x1-290003.4.4"></a>Dir</h4>
  <!--l. 279-->

  <p class="noindent">A <span class="pcrro7t-">Dir</span> is a
  simple directory-serving route target that serves files out of a
  directory. It has caching built-in, handles if-modified-since,
  ETags, and all the various bizarre HTTP caching mechanisms as
  RFC-accurate as possible. It also has default content-types and
  index files.

  <dl class="description">
    <dt class="description"><span class="pplb7t-">base</span>

    <dd class="description">This is the base directory <span class=
    "pplri7t-">from the chroot</span> that is served. Files should
    not be served outside of this base directory even in the
    chroot.

    <dt class="description"><span class=
    "pplb7t-">index</span><span class="pplb7t-">_file</span>

    <dd class="description">This is the default index file to use
    if a request doesn't give one. The <span class=
    "pcrro7t-">Dir</span> also will do redirects if a request for a
    directory doesn't end in a / slash.

    <dt class="description"><span class=
    "pplb7t-">default</span><span class="pplb7t-">_ctype</span>

    <dd class="description">The default Content-Type to use if none
    matches the MIMEType table.
  </dl><!--l. 291-->

  <p class="noindent">Currently, we don't offer more
  parameters for configuration, but eventually you'll be able
  to tweak more and more of the settings to control how Dirs work. 
  <!--l. 294-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">3.4.5</span>
  <a id="x1-300003.4.5" name="x1-300003.4.5"></a>Proxy</h4>
  <!--l. 296-->

  <p class="noindent">A Proxy is a Ghetto. It is used so that you
  can use Mongrel2 but not have to throw out your existing
  infrastructure. Mongrel2 goes to great pains to make sure that it
  implements a fast and dead accurate proxy system internally, but
  no matter how good it is it, can't compete with ZeroMQ
  handlers. The idea with giving Proxy functionality is you can
  point Mongrel2 at existing servers, and then slowly carve out
  pieces that will work as handlers.

  <dl class="description">
    <dt class="description"><span class="pplb7t-">addr</span>

    <dd class="description">The DNS address of the server.

    <dt class="description"><span class="pplb7t-">port</span>

    <dd class="description">The port to connect to.
  </dl><!--l. 309-->

  <p class="noindent">Requests that match a Proxy route are still
  parsed by Mongrel2's incredibly accurate HTTP parser, so
  that your backend servers should not be receiving badly formatted
  HTTP requests. Responses from a Proxy server, however, are sent
  unaltered to the browser directly. <!--l. 315-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">3.4.6</span>
  <a id="x1-310003.4.6" name="x1-310003.4.6"></a>Handler</h4>
  <!--l. 317-->

  <p class="noindent">Now we get to the best part: the ZeroMQ
  <span class="pcrro7t-">Handlers</span> that will receive
  asynchronous requests from Mongrel2. You need to use the ZeroMQ
  syntax for configuring them, but this means with one
  configuration format you can use handlers that are using UDP,
  TCP, Unix, or PGM transports. Most testing has been done with TCP
  transports.

  <dl class="description">
    <dt class="description"><span class=
    "pplb7t-">send</span><span class="pplb7t-">_spec</span>

    <dd class="description">This is the 0MQ sender specification,
    something like &ldquo;tcp://127.0.0.1:9999&rdquo; will use TCP
    to connect to a server on 127.0.0.1 at port 9999. The type of
    socket used is a PUSH socket, so that handlers receive messages
    in round-robin style.

    <dt class="description"><span class=
    "pplb7t-">send</span><span class="pplb7t-">_ident</span>

    <dd class="description">This is an identifier (usually a UUID)
    that will be used to register the send socket. This makes it so
    that messages are persisted between crashes.

    <dt class="description"><span class=
    "pplb7t-">recv</span><span class="pplb7t-">_spec</span>

    <dd class="description">Same as the send spec, but it's
    for receiving responses from Handlers. The type of socket used
    is a SUB socket, so that a cluster of Mongrel2 servers will
    receive handler responses but only the one with the right
    recv_ident will process it.

    <dt class="description"><span class=
    "pplb7t-">recv</span><span class="pplb7t-">_ident</span>

    <dd class="description">This is another UUID if you want the
    receive socket to subscribe to its messages. Handlers properly
    mention the send_ident on all returned messages, so you should
    either set this to nothing and don't subscribe, or set it
    to the same as send_ident.
  </dl><!--l. 336-->

  <p class="noindent">The interesting thing about the <span class=
  "pcrro7t-">Handler</span> configuration is you don't have
  to say where the actual backend handlers live. Did you notice you
  aren't declaring large clusters of proxies, proxy selection
  methods, or anything else, other than two 0MQ endpoints and some
  identifiers? This is because Mongrel2 is <span class=
  "pplri7t-">binding</span> these sockets and listening. Mongrel2
  doesn't actively connect to backends; they connect to
  Mongrel2. This means, if you want to fire up 10 more handlers,
  you just start them; no need to restart or reconfigure Mongrel2
  to make them active. <!--l. 344-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">3.4.7</span>
  <a id="x1-320003.4.7" name="x1-320003.4.7"></a>Others</h4>
  <!--l. 346-->

  <p class="noindent">There's also <span class=
  "pcrro7t-">Log</span>, <span class="pcrro7t-">MIMEType</span>,
  and <span class="pcrro7t-">Setting</span> objects/tables you can
  work with, but we'll get into those later since you
  don't need to know about them to understand the Mongrel2
  structure. <!--l. 352-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">3.5</span> <a id=
  "x1-330003.5" name="x1-330003.5"></a>A More Complex Example</h3>
  <!--l. 354-->

  <p class="noindent">All of this knowledge about the Mongrel2
  configuration structure can now be used to take a look at a more
  complex example. We'll take a look at this example and
  I'll just say what's going on, and you try to match
  what I'm saying to the code. Here's the file
  <span class=
  "pcrb7t-">examples/python/tests/mongrel2</span><span class=
  "pcrb7t-">_org.py</span>: <!--l. 358-->

  <p class="noindent"><a id="x1-33001r9" name="x1-33001r9"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 9:</span> <span class=
      "content"><span class="pplri7t-">Mongrel2.org Config</span>
      <span class="pplri7t-">Script</span></span>
    </div><!--tex4ht:label?: x1-33001r9 -->
    <!--l. 359-->

    <div class="lstinputlisting">
      <a id="x1-33002" name="x1-33002"></a> <span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33003r1" name=
      "x1-33003r1"></a></span><span class=
      "pcrb7t-x-x-90">from</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&#8902;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33004r2" name=
      "x1-33004r2"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33005r3" name=
      "x1-33005r3"></a></span><span class=
      "pcrr7t-x-x-90">main</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Server</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33006r4" name=
      "x1-33006r4"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">uuid</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">2</span><span class=
      "pcrr7t-x-x-90">f62bd5</span><span class=
      "pcrr7t-x-x-90">-9</span><span class=
      "pcrr7t-x-x-90">e59</span><span class=
      "pcrr7t-x-x-90">-49</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">-993</span><span class=
      "pcrr7t-x-x-90">c</span><span class=
      "pcrr7t-x-x-90">-3</span><span class=
      "pcrr7t-x-x-90">b6013c28f05</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33007r5" name=
      "x1-33007r5"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">access_log</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">logs</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">access</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33008r6" name=
      "x1-33008r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">error_log</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">logs</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">error</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33009r7" name=
      "x1-33009r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chroot</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">./</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33010r8" name=
      "x1-33010r8"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pid_file</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33011r9" name=
      "x1-33011r9"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">default_host</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">org</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33012r10" name=
      "x1-33012r10"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">name</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">main</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33013r11" name=
      "x1-33013r11"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">port</span><span class=
      "pcrr7t-x-x-90">=6767</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33014r12" name=
      "x1-33014r12"></a></span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33015r13" name=
      "x1-33015r13"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33016r14" name=
      "x1-33016r14"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33017r15" name=
      "x1-33017r15"></a></span><span class=
      "pcrr7t-x-x-90">test_directory</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Dir</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">base</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33018r16" name=
      "x1-33018r16"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">index_file</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">index</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">html</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33019r17" name=
      "x1-33019r17"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">default_ctype</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">text</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">plain</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33020r18" name=
      "x1-33020r18"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33021r19" name=
      "x1-33021r19"></a></span><span class=
      "pcrr7t-x-x-90">web_app_proxy</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Proxy</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">addr</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">127.0.0.1</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">port</span><span class=
      "pcrr7t-x-x-90">=80)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33022r20" name=
      "x1-33022r20"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33023r21" name=
      "x1-33023r21"></a></span><span class=
      "pcrr7t-x-x-90">chat_demo_dir</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Dir</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">base</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">static</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33024r22" name=
      "x1-33024r22"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">index_file</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">index</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">html</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33025r23" name=
      "x1-33025r23"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">default_ctype</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">text</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">plain</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33026r24" name=
      "x1-33026r24"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33027r25" name=
      "x1-33027r25"></a></span><span class=
      "pcrr7t-x-x-90">chat_demo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Handler</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">send_spec</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9999</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33028r26" name=
      "x1-33028r26"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">send_ident</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">54</span><span class=
      "pcrr7t-x-x-90">c6755b</span><span class=
      "pcrr7t-x-x-90">-9628-40</span><span class=
      "pcrr7t-x-x-90">a4</span><span class=
      "pcrr7t-x-x-90">-9</span><span class=
      "pcrr7t-x-x-90">a2d</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">cc82a816345e</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33029r27" name=
      "x1-33029r27"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">recv_spec</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9998</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">recv_ident</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33030r28" name=
      "x1-33030r28"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33031r29" name=
      "x1-33031r29"></a></span><span class=
      "pcrr7t-x-x-90">handler_test</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Handler</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">send_spec</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9997</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33032r30" name=
      "x1-33032r30"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">send_ident</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">34</span><span class=
      "pcrr7t-x-x-90">f9ceee</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">cd52</span><span class=
      "pcrr7t-x-x-90">-4</span><span class=
      "pcrr7t-x-x-90">b7f</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">b197</span><span class=
      "pcrr7t-x-x-90">-88</span><span class=
      "pcrr7t-x-x-90">bf2f0ec378</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33033r31" name=
      "x1-33033r31"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">recv_spec</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9996</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">recv_ident</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33034r32" name=
      "x1-33034r32"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33035r33" name=
      "x1-33035r33"></a></span><span class=
      "pcrro7t-x-x-90">#</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">the</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">r</span><span class=
      "pcrro8c-x-x-90">''</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">string</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">syntax</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">means</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">to</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">not</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">interpret</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">any</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">\</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">chars</span><span class=
      "pcrro7t-x-x-90">,</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">for</span><span class=
      "pcrro7t-x-x-90">&nbsp;</span><span class=
      "pcrro7t-x-x-90">regexes</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33036r34" name=
      "x1-33036r34"></a></span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Host</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">name</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">org</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">routes</span><span class=
      "pcrr7t-x-x-90">={</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33037r35" name=
      "x1-33037r35"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">@chat</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat_demo</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33038r36" name=
      "x1-33038r36"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">handlertest</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">handler_test</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33039r37" name=
      "x1-33039r37"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">web_app_proxy</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33040r38" name=
      "x1-33040r38"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">web_app_proxy</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33041r39" name=
      "x1-33041r39"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">test_directory</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33042r40" name=
      "x1-33042r40"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">testsmulti</span><span class=
      "pcrr7t-x-x-90">/(.&#8902;.</span><span class=
      "pcrr7t-x-x-90">json</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">test_directory</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33043r41" name=
      "x1-33043r41"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chatdemo</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat_demo_dir</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33044r42" name=
      "x1-33044r42"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">static</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat_demo_dir</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33045r43" name=
      "x1-33045r43"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mp3stream</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Handler</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33046r44" name=
      "x1-33046r44"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">send_spec</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9995</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33047r45" name=
      "x1-33047r45"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">send_ident</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">53</span><span class=
      "pcrr7t-x-x-90">f9f1d1</span><span class=
      "pcrr7t-x-x-90">-1116-4751-</span><span class=
      "pcrr7t-x-x-90">b6ff</span><span class=
      "pcrr7t-x-x-90">-4</span><span class=
      "pcrr7t-x-x-90">fbe3e43d142</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33048r46" name=
      "x1-33048r46"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">recv_spec</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9994</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">recv_ident</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33049r47" name=
      "x1-33049r47"></a></span><span class=
      "pcrr7t-x-x-90">})</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33050r48" name=
      "x1-33050r48"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33051r49" name=
      "x1-33051r49"></a></span><span class=
      "pcrr7t-x-x-90">main</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">hosts</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">add</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33052r50" name=
      "x1-33052r50"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33053r51" name=
      "x1-33053r51"></a></span><span class=
      "pcrr7t-x-x-90">settings</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">{</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">zeromq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">threads</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">1}</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33054r52" name=
      "x1-33054r52"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-33055r53" name=
      "x1-33055r53"></a></span><span class=
      "pcrr7t-x-x-90">commit</span><span class=
      "pcrr7t-x-x-90">(&#91;</span><span class=
      "pcrr7t-x-x-90">main</span><span class=
      "pcrr7t-x-x-90">&#93;,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">settings</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">settings</span><span class=
      "pcrr7t-x-x-90">)</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 362-->

  <p class="noindent">If you haven't guessed yet, this
  configuration is what's used on <a href=
  "http://mongrel2.org" class="url"><span class=
  "pcrr7t-">http://mongrel2.org</span></a> to configure the main
  test system. In it we've got the following things to check
  out:

  <ol class="enumerate1">
    <li class="enumerate" id="x1-33060x1">Our basic server, with a
    default host of mongrel2.org.

    <li class="enumerate" id="x1-33062x2">The route targets are
    separated out into their own variables, unlike the <span class=
    "pcrb7t-">sample</span><span class="pcrb7t-">_conf.py</span>
    file where they're just tossed into one big structure.

    <li class="enumerate" id="x1-33064x3">First target is a
    <span class="pcrro7t-">Dir</span> that serves up files out of
    the <span class="pcrb7t-">tests</span> directory and uses
    <span class="pcrb7t-">index.html</span> as its default file.

    <li class="enumerate" id="x1-33066x4">Next we setup a
    <span class="pcrro7t-">Proxy</span> pointing at the main
    website's server for testing the proxy.

    <li class="enumerate" id="x1-33068x5">Then there's a
    <span class="pcrro7t-">Dir</span> target for the <a href=
    "http://mongrel2.org:6767/chatdemo/" class="url"><span class=
    "pcrr7t-">http://mongrel2.org:6767/chatdemo/</span></a> that
    we'll look at later.

    <li class="enumerate" id="x1-33070x6">And you have the
    <span class="pcrro7t-">Handler</span> for the same chat demo
    that does the actual logic of a chat system.

    <li class="enumerate" id="x1-33072x7">After that's a
    little <span class="pcrro7t-">Handler</span> for testing out
    doing HTTP requests to a handler. Notice how even though the
    chat demo and this handler use different protocols (chat demo
    is using JSSockets) you don't have tell mongrel2 that? It
    figures it out based on how they're being used rather
    than by configurations.

    <li class="enumerate" id="x1-33074x8">With all those handler
    targets, we can now make the <span class="pcrro7t-">mongrel2
    Host</span> with all the routes assigned once, nice and clean.
    However, look how I was lazy and just tossed the mp3stream demo
    right into the routes dict? You can totally do this and m2sh
    will figure it out. Remember also that you can use the
    <span class="obeylines-h verb pcrr7t-">r'blah'</span> string
    format to not have to double up on your <span class=
    "obeylines-h verb pcrr7t-">\</span> chars in the patterns.

    <li class="enumerate" id="x1-33076x9">We then assign this
    <span class="pcrro7t-">mongrel2</span> variable as the hosts
    for the <span class="pcrro7t-">main</span> server.

    <li class="enumerate" id="x1-33078x10">There is also a
    <span class="pcrro7t-">settings</span> feature, which is just a
    dict of global settings you can tweak. In this case,
    we're upping the number of threads that 0MQ is using for
    its operations.

    <li class="enumerate" id="x1-33080x11">Finally, we commit the
    whole thing to the database by passing in the servers to save
    and the settings to use.
  </ol><!--l. 388-->

  <p class="noindent">And that, my friends, is the most complex
  configuration we have so far.

  <h3 class="sectionHead"><span class="titlemark">3.6</span> <a id=
  "x1-340003.6" name="x1-340003.6"></a>Routing And Host
  Patterns</h3><!--l. 393-->

  <p class="noindent">The pattern code was taken from <a href=
  "http://www.lua.org/">Lua</a> and is some of the simplest code
  for doing fast pattern matches. It is very much like regular
  expressions, except it removes a lot of features you don't
  need for routes. Also, unlike regular expressions, URL patterns
  always match from the start. Mongrel2 uses them by breaking
  routes up into a prefix and pattern part. It then uses routes to
  find the longest matching prefix and then tests the pattern. If
  the pattern matches, then the route works. If the route
  doesn't have a pattern, then it's assumed to match,
  and you're done. <!--l. 402-->

  <p class="noindent">The only caveat is you have to wrap your
  pattern parts in parenthesis, but these don't mean anything
  other than to delimit where a pattern starts. So instead of
  <span class="pcrro7t-">/images/.&#8902;.jpg</span>, write
  <span class="pcrro7t-">/images/(.&#8902;.jpg)</span> for it to
  work. <!--l. 406-->

  <p class="noindent">Here's the list of characters you can
  use in your patterns:

  <ul class="itemize1">
    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">.</span> (period) All characters.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">\a</span> Letters.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">\c</span> Control characters.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">\d</span> Digits.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">\l</span> Lowercase letters.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">\p</span> Punctuation characters.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">\s</span> Space characters.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">\u</span> Uppercase letters.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">\w</span> Alphanumeric characters.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">\x</span> Hexadecimal digits.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">\z</span> The 0 character (null
    terminator).

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">&#91;set&#93;</span> Just like a regex &#91;&#93;
    where is a set of chars, like &#91;0-9&#93; for all digits.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">&#91;^set&#93;</span> Inverse character set,
    so <span class="obeylines-h verb pcrr7t-">&#91;^0-9&#93;</span> is
    anything but digits.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">&#8902;</span> Longest match of 0 or
    more of the preceding character.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">+</span> Longest match of 1 or more
    of the preceding character.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">-</span> Shortest match of 0 or more
    of the preceding character.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">?</span> 0 or 1 match of of the
    preceding character

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">\b</span><span class=
    "pplri7t-">xy</span> Balanced match a substring starting with
    <span class="pplri7t-">x</span> and ending in <span class=
    "pplri7t-">y</span>. So <span class=
    "obeylines-h verb pcrr7t-">\b()</span> will match balanced
    parentheses.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">$</span> End of the string.
  </ul><!--l. 431-->

  <p class="noindent">Using the uppercase version of an escaped
  character makes it work the opposite way (i.e., <span class=
  "obeylines-h verb pcrr7t-">\A</span> matches any character that
  <span class="pplri7t-">isn't</span> a letter). The
  backslash can be used to escape the following character,
  disabling its special abilities (i.e., <span class=
  "obeylines-h verb pcrr7t-">\\</span> will match a backslash). 
  <!--l. 436-->

  <p class="noindent">Anything that's not listed here is
  matched literally. Remember also that when you write the Python
  code for your scripts you can use the <span class=
  "obeylines-h verb pcrr7t-">r'blah'</span> string syntax to avoid
  having to double up on your <span class=
  "obeylines-h verb pcrr7t-">\</span> characters in the string. 
  <!--l. 440-->

  <p class="noindent"><a id="x1-34001r4" name="x1-34001r4"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 4:</span> <span class=
      "content"><span class="pplri7t-">Sorry, Unicodians,
      It's All</span> <span class=
      "pplri7t-">ASCII</span></span>
    </div><!--tex4ht:label?: x1-34001r4 -->

    <div class="quote">
      <!--l. 441-->

      <p class="indent">Yep, I get it. You think that everyone
      should use UTF-8 or some Unicode encoding for everything. You
      despise the dominance of the `A' in ASCII and
      hate that you can't put your spoken language right in a
      URL. <!--l. 445-->

      <p class="indent">Well, I hate to say it, but tough.
      Protocols are hard enough without having to worry about the
      bewildering mess that is Unicode. When you sit down to write
      a network protocol, the last thing you need is a format
      that's inconsistent, has multiple interpretations,
      can't be properly capitalized or lowercased, and
      requires extra translations steps for every operation. With
      ASCII, every computer just knows what it is, and it's
      the fastest for creating wire protocol formats. <!--l. 453-->

      <p class="indent">This is why, on the Internet, you have to
      do things to URLs to make them ASCII, like encoding them with
      % signs. It's in the standard, and it's the smart
      thing to do. I don't want to have to know the
      difference between the various accents in your spoken
      language to route a URL around. I just want to deal with a
      fixed set of characters and be done with it. Don't
      blame me or Mongrel2 for this, it's just the way the
      standard is and the way to get a server that is stable and
      works. <!--l. 461-->

      <p class="indent">Protocols work better when there's
      less politics in their design. This means you can't put
      Unicode into your URL patterns. I mean, you can try; but the
      behavior is completely undefined.
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 468-->

  <p class="noindent">Here are some example routes you can try to
  get a feel for the system:

  <ul class="itemize1">
    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">r"/images/"</span> This will just
    match any path that has /images/ in it without any patterns.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">r"/"</span> The fastest possible
    route you can have.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">r"/images/(.&#8902;.jpg)"</span>
    Match only requests for jpg images in the images directory.
    Keep in mind that this isn't actually looking in the
    directory, it's just matching the <span class=
    "pcrro7t-">(.&#8902;.jpg)</span> pattern.

    <li class="itemize"><span class=
    "obeylines-h verb pcrr7t-">r"/images/(\a-\-\d+\.jpg)"</span> A
    more complex example that matches a short sequence of 0 or more
    letters (remember -), then a dash (<span class=
    "obeylines-h verb pcrr7t-">\-</span> escapes the -), then 1 or
    long sequence of digits and finally a .jpg) with the
    <span class="obeylines-h verb pcrr7t-">\</span>. escaping the
    period.
  </ul><!--l. 479-->

  <p class="noindent">That should give the idea of how you can use
  them. Notice also that I'm using the Python <span class=
  "obeylines-h verb pcrr7t-">r"blah"</span> string syntax which is
  interchangeable with the <span class=
  "obeylines-h verb pcrr7t-">r'blah'</span> syntax so I don't
  have to double escape everything.

  <h3 class="sectionHead"><span class="titlemark">3.7</span> <a id=
  "x1-350003.7" name="x1-350003.7"></a>Deployment Logs And
  Commits</h3><!--l. 485-->

  <p class="noindent">A very nice feature for people doing
  operations work is that m2sh keeps track of all the commands you
  run on it while you work, and lets you add little commit logs to
  the log for documentation later. These commit logs are then
  maintained even across <span class="pcrro7t-">m2sh init</span>
  and <span class="pcrro7t-">m2sh load</span> commands so you can
  see what's going on. They track who did something, what
  server they did it on, what time they did it and what they did. 
  <!--l. 492-->

  <p class="noindent">To see the logs for your own tests, just do
  <span class="pcrro7t-">m2sh log -db simple.sqlite</span> and
  then, if you want to add a commit log message, you use the
  <span class="pcrro7t-">m2sh commit</span> command. Here's
  an example from mongrel2.org: <!--l. 496-->

  <p class="noindent"><a id="x1-35001r10" name="x1-35001r10"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 10:</span> <span class=
      "content"><span class="pplri7t-">Example Commit</span>
      <span class="pplri7t-">Log</span></span>
    </div><!--tex4ht:label?: x1-35001r10 -->
    <!--l. 497-->

    <div class="lstlisting" id="listing-8">
      <span class="label"><a id="x1-35002r1" name=
      "x1-35002r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-35003r2" name=
      "x1-35003r2"></a></span><span class=
      "pcrr7t-x-x-90">&#91;2010-07-18</span><span class=
      "pcrr7t-x-x-90">T04</span><span class=
      "pcrr7t-x-x-90">:14:53,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2@zedshaw</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">init_command</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">usr</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">bin</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">init</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-35004r3" name=
      "x1-35004r3"></a></span><span class=
      "pcrr7t-x-x-90">&#91;2010-07-18</span><span class=
      "pcrr7t-x-x-90">T04</span><span class=
      "pcrr7t-x-x-90">:15:06,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2@zedshaw</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">load_command</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">usr</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">bin</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">load</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2_org</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-35005r4" name=
      "x1-35005r4"></a></span><span class=
      "pcrr7t-x-x-90">&#91;2010-07-18</span><span class=
      "pcrr7t-x-x-90">T04</span><span class=
      "pcrr7t-x-x-90">:22:06,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2@zedshaw</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">load_command</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">usr</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">bin</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">load</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2_org</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-35006r5" name=
      "x1-35006r5"></a></span><span class=
      "pcrr7t-x-x-90">&#91;2010-07-18</span><span class=
      "pcrr7t-x-x-90">T04</span><span class=
      "pcrr7t-x-x-90">:23:32,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2@zedshaw</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">load_command</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">usr</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">bin</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">load</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2_org</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-35007r6" name=
      "x1-35007r6"></a></span><span class=
      "pcrr7t-x-x-90">&#91;2010-07-18</span><span class=
      "pcrr7t-x-x-90">T04</span><span class=
      "pcrr7t-x-x-90">:26:16,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2@zedshaw</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">upgrade</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Latest</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">code</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-35008r7" name=
      "x1-35008r7"></a></span><span class=
      "pcrr7t-x-x-90">&#91;2010-07-18</span><span class=
      "pcrr7t-x-x-90">T18</span><span class=
      "pcrr7t-x-x-90">:05:59,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2@zedshaw</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">load_command</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">usr</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">bin</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">load</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2_org</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-35009r8" name=
      "x1-35009r8"></a></span><span class=
      "pcrr7t-x-x-90">&#91;2010-07-18</span><span class=
      "pcrr7t-x-x-90">T20</span><span class=
      "pcrr7t-x-x-90">:09:01,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2@zedshaw</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">init_command</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">usr</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">bin</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2_org</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-35010r9" name=
      "x1-35010r9"></a></span><span class=
      "pcrr7t-x-x-90">&#91;2010-07-18</span><span class=
      "pcrr7t-x-x-90">T20</span><span class=
      "pcrr7t-x-x-90">:09:02,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2@zedshaw</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">load_command</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">usr</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">bin</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2_org</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-35011r10" name=
      "x1-35011r10"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">commit</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">what</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">org</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">why</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">Testing</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">things</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">out</span><span class=
      "pcrr7t-x-x-90">."</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 511-->

  <p class="noindent">The motivation for this feature is the trend
  that operations store server configurations in revision control
  systems like git or etckeeper. This works great for holding the
  configuration files, but it doesn't tell you what happened
  on each server. In many cases, the configuration files also need
  to be reworked or altered for each deployment. With the m2sh log
  and commit system, you can augment your revision control with
  deployment action tracking. <!--l. 517-->

  <p class="noindent">Later versions of Mongrel2 will keep small
  amounts of statistics which will link these actions to changes in
  Mongrel2 behavior like frequent crashing, failures, slowness, or
  other problems. <!--l. 520-->

  <p class="noindent">Basically, there's nowhere to hide.
  Mongrel2 will help operations figure out who needs to get fired
  the next time Twitter goes down.

  <h3 class="sectionHead"><span class="titlemark">3.8</span> <a id=
  "x1-360003.8" name="x1-360003.8"></a>Control Port</h3>
  <!--l. 526-->

  <p class="noindent">Just before the release of 1.0, we added a
  feature called the &ldquo;Control Port&rdquo;, which lets you
  connect to a running Mongrel2 server over a unix (domain) socket
  and give it control commands. These commands let you get the
  status of running tasks, lists of currently connected sockets and
  how long they've been connected, the server's current
  time and kill a connection. Using this control port, you can then
  implement any monitoring and timeout policies you want, and
  provide better status. <!--l. 534-->

  <p class="noindent">By default, the control port is in your
  chroot at run/control, but you can set the <span class=
  "pcrro7t-">control</span><span class="pcrro7t-">_port</span>
  setting to change this. You can actually change it to any ZeroMQ
  valid spec you want, although you're advised to use IPC for
  security. <!--l. 538-->

  <p class="noindent">Once Mongrel2 starts, you can then use
  <span class="pcrb7t-">m2sh</span> to connect to Mongrel2 and
  control it using the simple command language. Currently, what you
  get back is very raw, but it will improve as we work on the
  control port and what it does. <!--l. 542-->

  <p class="noindent">The list of commands you can issue are:

  <dl class="description">
    <dt class="description"><span class="pplb7t-">status
    tasks</span>

    <dd class="description">Dumps a JSON formatted dict (object) of
    all the currently running tasks and what they're doing.
    Think of it like an internal <span class="pcrb7t-">ps</span>
    command.

    <dt class="description"><span class="pplb7t-">status net</span>

    <dd class="description">Dumps a JSON dict that matches
    connections IDs (same ones your handlers get) to the seconds
    since their last ping. In the case of an HTTP connection this
    is how long they've been connected. In the case of a JSON
    socket this is the last time a ping message was received.

    <dt class="description"><span class="pplb7t-">time</span>

    <dd class="description">Prints the unix time the server thinks
    it's using. Useful for synching.

    <dt class="description"><span class="pplb7t-">kill ID</span>

    <dd class="description">Does a forced close on the socket that
    is at this ID from the <span class="pcrro7t-">status</span>
    <span class="pcrro7t-">net</span> command. This is a rather
    violent way to kill a connection so don't do it that
    often, but if you're overloaded then this is where to go.

    <dt class="description"><span class="pplb7t-">control
    stop</span>

    <dd class="description">Shuts down the control port permanently
    in case you want to keep it from being accessed for some
    reason.
  </dl><!--l. 560-->

  <p class="noindent">You then use the control port by running
  <span class="pcrro7t-">m2sh</span>: <!--l. 562-->

  <p class="noindent">

  <div class="fancyvrb" id="fancyvrb1">
    <a id="x1-36002r1" name="x1-36002r1"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;m2sh</span><span class=
    "pcrr7t-">&nbsp;control</span><span class=
    "pcrr7t-">&nbsp;-db</span><span class=
    "pcrr7t-">&nbsp;config.sqlite</span><span class=
    "pcrr7t-">&nbsp;-name</span><span class=
    "pcrr7t-">&nbsp;test</span><br class="fancyvrb">
    <a id="x1-36004r2" name="x1-36004r2"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;CONNECTING...</span><br class="fancyvrb">
    <a id="x1-36006r3" name="x1-36006r3"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;&gt;</span><span class=
    "pcrr7t-">&nbsp;status</span><span class=
    "pcrr7t-">&nbsp;net</span><br class="fancyvrb">
    <a id="x1-36008r4" name="x1-36008r4"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;{"total":</span><span class=
    "pcrr7t-">&nbsp;0}</span><br class="fancyvrb">
    <a id="x1-36010r5" name="x1-36010r5"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;&gt;</span><span class=
    "pcrr7t-">&nbsp;time</span><br class="fancyvrb">
    <a id="x1-36012r6" name="x1-36012r6"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;{"time":</span><span class=
    "pcrr7t-">&nbsp;1282980306}</span>
  </div><!--l. 571-->

  <p class="noindent">As we work on this feature more, we'll
  have a nicer interface to it. If you wanted to connect on your
  own, here is a simple Python script showing how to do it: 
  <!--l. 576-->

  <p class="noindent"><a id="x1-36013r11" name="x1-36013r11"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 11:</span> <span class=
      "content"><span class="pplri7t-">Python Control Port</span>
      <span class="pplri7t-">Example</span></span>
    </div><!--tex4ht:label?: x1-36013r11 -->
    <!--l. 577-->

    <div class="lstlisting" id="listing-9">
      <span class="label"><a id="x1-36014r1" name=
      "x1-36014r1"></a></span><span class=
      "pcrr7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36015r2" name=
      "x1-36015r2"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36016r3" name=
      "x1-36016r3"></a></span><span class=
      "pcrr7t-x-x-90">CTX</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">Context</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36017r4" name=
      "x1-36017r4"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36018r5" name=
      "x1-36018r5"></a></span><span class=
      "pcrr7t-x-x-90">addr</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">ipc</span><span class=
      "pcrr7t-x-x-90">://</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">control</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36019r6" name=
      "x1-36019r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36020r7" name=
      "x1-36020r7"></a></span><span class=
      "pcrr7t-x-x-90">ctl</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">CTX</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">socket</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">REQ</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36021r8" name=
      "x1-36021r8"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36022r9" name=
      "x1-36022r9"></a></span><span class=
      "pcrr7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">CONNECTING</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36023r10" name=
      "x1-36023r10"></a></span><span class=
      "pcrr7t-x-x-90">ctl</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">connect</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">addr</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36024r11" name=
      "x1-36024r11"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36025r12" name=
      "x1-36025r12"></a></span><span class=
      "pcrr7t-x-x-90">while</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">True</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36026r13" name=
      "x1-36026r13"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cmd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">raw_input</span><span class=
      "pcrr7t-x-x-90">("&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">")</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36027r14" name=
      "x1-36027r14"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36028r15" name=
      "x1-36028r15"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ctl</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">send</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">cmd</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36029r16" name=
      "x1-36029r16"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36030r17" name=
      "x1-36030r17"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ctl</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">recv</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36031r18" name=
      "x1-36031r18"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-36032r19" name=
      "x1-36032r19"></a></span><span class=
      "pcrr7t-x-x-90">ctl</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">close</span><span class=
      "pcrr7t-x-x-90">()</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 600-->

  <p class="noindent">You obviously don't need to do this,
  but should you want to do something special like a management
  interface, this is your start.

  <h3 class="sectionHead"><span class="titlemark">3.9</span> <a id=
  "x1-370003.9" name="x1-370003.9"></a>Multiple Servers</h3>
  <!--l. 606-->

  <p class="noindent">A Mongrel2 process itself does not have any
  support for running multiple servers; instead, it takes two
  simple parameters: a sqlite config database and a server uuid
  that names the server to be launched. This is done to keep the
  mongrel2 code simple and workable. <!--l. 611-->

  <p class="noindent">However. <!--l. 613-->

  <p class="noindent">Mongrel2's m2sh does support launching
  multiple servers from a single configuration database. By passing
  -every to many m2sh commands, you are able to perform actions on
  all configured servers at once. You can also perform actions on
  single servers by specifying their uuid, name or host. If any
  parameter given is ambiguous (that is if, for example, you search
  with <span class="pcrro7t-">-host</span> <span class=
  "pcrro7t-">localhost</span> and your config contains two servers
  which attempt to bind to localhost), m2sh will list the matching
  servers and ask you to clarify your selection. <!--l. 621-->

  <p class="noindent">For example:

  <div class="fancyvrb" id="fancyvrb2">
    <a id="x1-37002r1" name="x1-37002r1"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;&gt;</span><span class=
    "pcrr7t-">&nbsp;m2sh</span><span class=
    "pcrr7t-">&nbsp;start</span><span class=
    "pcrr7t-">&nbsp;-db</span><span class=
    "pcrr7t-">&nbsp;config.sqlite</span><span class=
    "pcrr7t-">&nbsp;-every</span><br class="fancyvrb">
    <a id="x1-37004r2" name="x1-37004r2"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;Launching</span><span class=
    "pcrr7t-">&nbsp;server</span><span class=
    "pcrr7t-">&nbsp;localhost</span><span class=
    "pcrr7t-">&nbsp;9f0cbd7d-aeff-4195-921e-2ce1c25512d3</span><span class="pcrr7t-">&nbsp;on</span><span class="pcrr7t-">&nbsp;port</span><span class="pcrr7t-">&nbsp;6768</span><br class="fancyvrb">
    <a id="x1-37006r3" name="x1-37006r3"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;...</span><br class="fancyvrb">
    <a id="x1-37008r4" name="x1-37008r4"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;Launching</span><span class=
    "pcrr7t-">&nbsp;server</span><span class=
    "pcrr7t-">&nbsp;localhost</span><span class=
    "pcrr7t-">&nbsp;3d815ade-9081-4c36-94dc-77a9b060b021</span><span class="pcrr7t-">&nbsp;on</span><span class="pcrr7t-">&nbsp;port</span><span class="pcrr7t-">&nbsp;6767</span><br class="fancyvrb">
    <a id="x1-37010r5" name="x1-37010r5"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;...</span><br class="fancyvrb">
    <a id="x1-37012r6" name="x1-37012r6"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;</span><br class="fancyvrb">
    <a id="x1-37014r7" name="x1-37014r7"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;&gt;</span><span class=
    "pcrr7t-">&nbsp;m2sh</span><span class=
    "pcrr7t-">&nbsp;start</span><span class=
    "pcrr7t-">&nbsp;-db</span><span class=
    "pcrr7t-">&nbsp;config.sqlite</span><span class=
    "pcrr7t-">&nbsp;-host</span><span class=
    "pcrr7t-">&nbsp;localhost</span><br class="fancyvrb">
    <a id="x1-37016r8" name="x1-37016r8"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;Not</span><span class=
    "pcrr7t-">&nbsp;sure</span><span class=
    "pcrr7t-">&nbsp;which</span><span class=
    "pcrr7t-">&nbsp;server</span><span class=
    "pcrr7t-">&nbsp;to</span><span class=
    "pcrr7t-">&nbsp;run,</span><span class=
    "pcrr7t-">&nbsp;what</span><span class=
    "pcrr7t-">&nbsp;I</span><span class=
    "pcrr7t-">&nbsp;found:</span><br class="fancyvrb">
    <a id="x1-37018r9" name="x1-37018r9"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;NAME</span><span class=
    "pcrr7t-">&nbsp;HOST</span><span class=
    "pcrr7t-">&nbsp;UUID</span><br class="fancyvrb">
    <a id="x1-37020r10" name="x1-37020r10"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;--------------</span><br class="fancyvrb">
    <a id="x1-37022r11" name="x1-37022r11"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;localhost</span><span class=
    "pcrr7t-">&nbsp;localhost</span><span class=
    "pcrr7t-">&nbsp;3d815ade-9081-4c36-94dc-77a9b060b021</span><br class="fancyvrb">
    <a id="x1-37024r12" name="x1-37024r12"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;localhost</span><span class=
    "pcrr7t-">&nbsp;localhost</span><span class=
    "pcrr7t-">&nbsp;9f0cbd7d-aeff-4195-921e-2ce1c25512d3</span><br class="fancyvrb">
    <a id="x1-37026r13" name="x1-37026r13"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;&#8902;</span><span class=
    "pcrr7t-">&nbsp;Use</span><span class=
    "pcrr7t-">&nbsp;-every</span><span class=
    "pcrr7t-">&nbsp;to</span><span class=
    "pcrr7t-">&nbsp;run</span><span class=
    "pcrr7t-">&nbsp;them</span><span class=
    "pcrr7t-">&nbsp;all.</span><br class="fancyvrb">
    <a id="x1-37028r14" name="x1-37028r14"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;</span><br class="fancyvrb">
    <a id="x1-37030r15" name="x1-37030r15"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;&gt;</span><span class=
    "pcrr7t-">&nbsp;m2sh</span><span class=
    "pcrr7t-">&nbsp;start</span><span class=
    "pcrr7t-">&nbsp;-db</span><span class=
    "pcrr7t-">&nbsp;config.sqlite</span><span class=
    "pcrr7t-">&nbsp;-uuid</span><span class=
    "pcrr7t-">&nbsp;3d815ade-9081-4c36-94dc-77a9b060b021</span><br class="fancyvrb">
    <a id="x1-37032r16" name="x1-37032r16"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;Launching</span><span class=
    "pcrr7t-">&nbsp;server</span><span class=
    "pcrr7t-">&nbsp;localhost</span><span class=
    "pcrr7t-">&nbsp;3d815ade-9081-4c36-94dc-77a9b060b021</span><span class="pcrr7t-">&nbsp;on</span><span class="pcrr7t-">&nbsp;port</span><span class="pcrr7t-">&nbsp;6767</span><br class="fancyvrb">
    <a id="x1-37034r17" name="x1-37034r17"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;...</span><br class="fancyvrb">
    <a id="x1-37036r18" name="x1-37036r18"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;</span><br class="fancyvrb">
    <a id="x1-37038r19" name="x1-37038r19"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;&gt;</span><span class=
    "pcrr7t-">&nbsp;m2sh</span><span class=
    "pcrr7t-">&nbsp;running</span><span class=
    "pcrr7t-">&nbsp;-db</span><span class=
    "pcrr7t-">&nbsp;config.sqlite</span><span class=
    "pcrr7t-">&nbsp;-every</span><br class="fancyvrb">
    <a id="x1-37040r20" name="x1-37040r20"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;Found</span><span class=
    "pcrr7t-">&nbsp;server</span><span class=
    "pcrr7t-">&nbsp;localhost</span><span class=
    "pcrr7t-">&nbsp;3d815ade-9081-4c36-94dc-77a9b060b021</span><span class="pcrr7t-">&nbsp;RUNNING</span><span class="pcrr7t-">&nbsp;at</span><span class="pcrr7t-">&nbsp;PID</span><span class="pcrr7t-">&nbsp;28525</span><br class="fancyvrb">
    <a id="x1-37042r21" name="x1-37042r21"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;PID</span><span class=
    "pcrr7t-">&nbsp;file</span><span class=
    "pcrr7t-">&nbsp;run/mongrel2.pid</span><span class=
    "pcrr7t-">&nbsp;not</span><span class=
    "pcrr7t-">&nbsp;found</span><span class=
    "pcrr7t-">&nbsp;for</span><span class=
    "pcrr7t-">&nbsp;server</span><span class=
    "pcrr7t-">&nbsp;localhost</span><span class=
    "pcrr7t-">&nbsp;9f0cbd7d-aeff-4195-921e-2ce1c25512d3</span><br class="fancyvrb">
    <a id="x1-37044r22" name="x1-37044r22"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;</span><br class="fancyvrb">
    <a id="x1-37046r23" name="x1-37046r23"></a><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;&gt;</span><span class=
    "pcrr7t-">&nbsp;m2sh</span><span class=
    "pcrr7t-">&nbsp;stop</span><span class=
    "pcrr7t-">&nbsp;-db</span><span class=
    "pcrr7t-">&nbsp;config.sqlite</span><span class=
    "pcrr7t-">&nbsp;-every</span>
  </div><!--l. 648-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">3.10</span>
  <a id="x1-380003.10" name="x1-380003.10"></a>Tweakable Expert
  Settings</h3><!--l. 650-->

  <p class="noindent">Many of Mongrel2's internal settings
  are configurable using the settings system. Some of these are
  dangerous to mess with, so make sure you test any changes before
  you try to run them. Setting them to 0 or negative numbers
  isn't checked, so if you make a setting and things go
  crazy, you need to not make that setting. All of these have good
  defaults so you can leave them alone unless you need to change
  them. <!--l. 657-->

  <p class="noindent">To configure your settings, you just pass
  them to the <span class="pcrro7t-">commit</span> command when you
  setup your configuration. Like this: <!--l. 660-->

  <p class="noindent"><a id="x1-38001r12" name="x1-38001r12"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 12:</span> <span class=
      "content"><span class="pplri7t-">Changing</span> <span class=
      "pplri7t-">Settings</span></span>
    </div><!--tex4ht:label?: x1-38001r12 -->
    <!--l. 661-->

    <div class="lstlisting" id="listing-10">
      <span class="label"><a id="x1-38002r1" name=
      "x1-38002r1"></a></span><span class=
      "pcrr7t-x-x-90">settings</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">{"</span><span class=
      "pcrr7t-x-x-90">zeromq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">threads</span><span class=
      "pcrr7t-x-x-90">":</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">1,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">limits</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">url_path</span><span class=
      "pcrr7t-x-x-90">":</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">1024}</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-38003r2" name=
      "x1-38003r2"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-38004r3" name=
      "x1-38004r3"></a></span><span class=
      "pcrr7t-x-x-90">commit</span><span class=
      "pcrr7t-x-x-90">(&#91;</span><span class=
      "pcrr7t-x-x-90">main</span><span class=
      "pcrr7t-x-x-90">&#93;,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">settings</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">settings</span><span class=
      "pcrr7t-x-x-90">)</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 668-->

  <p class="noindent">Mongrel2 will read these on the fly and write
  INFO log messages telling you what the settings are so you can
  debug them if they cause problems. The list of available settings
  are:

  <dl class="description">
    <dt class="description"><span class=
    "pplb7t-">control</span><span class=
    "pplb7t-">_port=ipc://run/control</span>

    <dd class="description">This is where Mongrel2 will listen with
    0MQ for control messages. You should use <span class=
    "obeylines-h verb pcrr7t-">ipc://</span> for the spec so that
    only a local user with file access can get at it.

    <dt class="description"><span class=
    "pplb7t-">limits.buffer</span><span class="pplb7t-">_size=2 *
    1024</span>

    <dd class="description">Internal IO buffers, used for things
    like proxying and handling requests. This is a <span class=
    "pplri7t-">very</span> conservative setting, so if you get HTTP
    headers greater than this, you'll want to increase this
    setting. You'll also want to shoot whoever is sending you
    those requests, because the average is 400-600 bytes.

    <dt class="description"><span class=
    "pplb7t-">limits.connection</span><span class=
    "pplb7t-">_stack</span><span class="pplb7t-">_size=32 *
    1024</span>

    <dd class="description">Size of the stack used for connection
    coroutines. If you're trying to cram a ton of connections
    into very little RAM, see how low this can go.

    <dt class="description"><span class=
    "pplb7t-">limits.content</span><span class="pplb7t-">_length=20
    * 1024</span>

    <dd class="description">Maximum allowed content length on
    submitted requests. This is, right now, a hard limit so
    requests that go over it are rejected. Later versions of
    Mongrel2 will use an upload mechanism that will allow any size
    upload.

    <dt class="description"><span class=
    "pplb7t-">limits.dir</span><span class=
    "pplb7t-">_max</span><span class="pplb7t-">_path=256</span>

    <dd class="description">Max path length you can set for Dir
    handlers.

    <dt class="description"><span class=
    "pplb7t-">limits.dir</span><span class=
    "pplb7t-">_send</span><span class="pplb7t-">_buffer=16 *
    1024</span>

    <dd class="description">Maximum buffer used for file sending
    when we need to use one.

    <dt class="description"><span class=
    "pplb7t-">limits.fdtask</span><span class="pplb7t-">_stack=100
    * 1024</span>

    <dd class="description">Stack frame size for the main IO
    reactor task. There's only one, so set it high if you
    can, but it could possibly go lower.

    <dt class="description"><span class=
    "pplb7t-">limits.handler</span><span class="pplb7t-">_stack=100
    * 1024</span>

    <dd class="description">The stack frame size for any Handler
    tasks. You probably want this high, since there's not
    many of these, but adjust and see what your system can handle.

    <dt class="description"><span class=
    "pplb7t-">limits.handler</span><span class=
    "pplb7t-">_targets=128</span>

    <dd class="description">The maximum number of connection IDs a
    message from a Handler may target. It's not smart to set
    this really high.

    <dt class="description"><span class=
    "pplb7t-">limits.header</span><span class="pplb7t-">_count=128
    * 10</span>

    <dd class="description">Maximum number of allowed headers from
    a client connection.

    <dt class="description"><span class=
    "pplb7t-">limits.host</span><span class=
    "pplb7t-">_name=256</span>

    <dd class="description">Maximum hostname for Host specifiers
    and other DNS related settings.

    <dt class="description"><span class=
    "pplb7t-">limits.mime</span><span class=
    "pplb7t-">_ext</span><span class="pplb7t-">_len=128</span>

    <dd class="description">Maximum length of MIME type extensions.

    <dt class="description"><span class=
    "pplb7t-">limits.url</span><span class=
    "pplb7t-">_path=256</span>

    <dd class="description">Max URL paths. Does not include query
    string, just path.

    <dt class="description"><span class=
    "pplb7t-">superpoll.hot</span><span class=
    "pplb7t-">_dividend=4</span>

    <dd class="description">Ratio of the total (like 1/4th, 1/8th)
    that should be in the hot selection. Set this higher if you
    have lots of idle connections; set it lower if you have more
    active connections.

    <dt class="description"><span class=
    "pplb7t-">superpoll.max</span><span class="pplb7t-">_fd=10 *
    1024</span>

    <dd class="description">Maximum possible open files. Do not set
    this above 64 * 1024, and expect it to take a bit while
    Mongrel2 sets up constant structures.

    <dt class="description"><span class=
    "pplb7t-">upload.temp</span><span class=
    "pplb7t-">_store=None</span>

    <dd class="description">This is not set by default. If you want
    large requests to reach your handlers, then set this to a
    directory they can access, and make sure they can handle it.
    Read about it in the Hacking section under Uploads. The file
    has to end in XXXXXX chars to work (read man mkstemp).

    <dt class="description"><span class=
    "pplb7t-">zeromq.threads=1</span>

    <dd class="description">Number of 0MQ IO threads to run.
    Careful, we've experienced thread bugs in 0MQ sometimes
    with high numbers of these.
  </dl>

  <h2 class="chapterHead"><span class=
  "titlemark">Chapter&nbsp;4</span><br>
  <a id="x1-390004" name="x1-390004"></a>Deploying</h2><!--l. 3-->

  <p class="noindent">I am now going to try to get you to setup a
  small, tiny, little version of a good deployment that matches the
  configuration of the site at <a href="http://mongrel2.org" class=
  "url"><span class="pcrr7t-">http://mongrel2.org</span></a>, with
  all the examples running. This configuration will give you all
  the tools you need to make automated and managed deployments, but
  it is using small scale tools. The idea is that you learn what is
  involved in a nice, easy-to-manage setup, using simple things
  first, then you can extrapolate that out into your own setup or
  something better.

  <h3 class="sectionHead"><span class="titlemark">4.1</span> <a id=
  "x1-400004.1" name="x1-400004.1"></a>Mongrel2 Deployment
  Requirements</h3><!--l. 14-->

  <p class="noindent">It may seem obvious, but I'll go over
  the things you need in order to continue on in this section:

  <dl class="description">
    <dt class="description"><span class="pplb7t-">Mongrel2</span>

    <dd class="description">I know, hard to believe, but you
    actually need to have Mongrel2 installed.

    <dt class="description"><span class="pplb7t-">m2sh</span>

    <dd class="description">Again, not sure why, but some folks
    think they don't need this. Unless you've written
    your own, you need <span class="pcrro7t-">m2sh</span>.

    <dt class="description"><span class="pplb7t-">Python</span>

    <dd class="description">Obviously, if you have <span class=
    "pcrro7t-">m2sh</span>, then you have Python, but some systems
    (like Debian) don't install all of Python. Make sure your
    Python setup is good.

    <dt class="description"><span class="pplb7t-">root</span>

    <dd class="description">You'll need root access on your
    box. Either through <span class="pcrro7t-">sudo</span> or some
    other means.

    <dt class="description"><span class="pplb7t-">Basic Python
    coding</span>

    <dd class="description">Right now, you should be able to do
    some basic Python.
  </dl><!--l. 27-->

  <p class="noindent">That will get you going at first and, as we
  go, we'll do various other setups to get our application
  working. <!--l. 30-->

  <p class="noindent"><a id="x1-40001r5" name="x1-40001r5"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 5:</span> <span class=
      "content"><span class="pplri7t-">Learning</span> <span class=
      "pplri7t-">Python</span></span>
    </div><!--tex4ht:label?: x1-40001r5 -->

    <div class="quote">
      <!--l. 31-->

      <p class="indent">Why should you learn programming? The trend
      is that if you are a system administrator who can't
      code, you are on your way out. Eventually, you'll be in
      charge of automating systems; not manually managing them, and
      if you don't believe me then what do you think all
      those managed service companies are doing? Alright, so you
      need to learn to code, but most of the books suck for really
      learning if you know nothing. <!--l. 37-->

      <p class="indent">This is why I started my own book: <a href=
      "http://learnpythonthehardway.org">Learn Python The Hard
      Way</a>, for people who know nothing about programming but
      need or want to learn. It teaches Python, but it mostly
      teaches all the things programmers actually learn before they
      learn programming. When you're done with my book,
      you'll have your &ldquo;programming brown belt&rdquo;.
      That means you can then move onto one of many other free
      online books and <span class="pplri7t-">really</span> learn
      programming, and have a higher chance of actually learning
      it. <!--l. 45-->

      <p class="indent">If you can't code Python then you can
      probably muddle through this and you may learn something, but
      learning Python will be important later. <!--l. 48-->

      <p class="indent">But <span class=
      "pplri7t-">don't</span> read &ldquo;Dive Into
      Python&rdquo;. It is a horrible introduction.
    </div>
  </div>
  <hr class="endfloat">

  <h4 class="subsectionHead"><span class="titlemark">4.1.1</span>
  <a id="x1-410004.1.1" name="x1-410004.1.1"></a>Introducing
  procer</h4><!--l. 53-->

  <p class="noindent">When I started working on this little manual,
  I wanted to get you into setting up a well-managed and automated
  deployment system. The <span class="pcrro7t-">m2sh</span> program
  does much of the automation you need, but Mongrel2 also has to
  talk to quite a few separate little pieces that run as separate
  processes. Trying to juggle all these processes without a tool to
  help is a nightmare. You end up writing init scripts and merging
  them into your boot process and all sorts of crazy antics just so
  you can run a stupid hello world demo. <!--l. 61-->

  <p class="noindent">What I needed was a &ldquo;user space process
  manager&rdquo;. These are programs that run other programs, but,
  more importantly, try to keep those other programs running
  without much human intervention. When you need to deploy a ton of
  processes that all have to be running, these USPMs are fantastic.
  They usually read some startup profile describing what needs to
  start and what they depend on, and then it kicks everything into
  gear and watches them. If any of the processes crash, they try to
  restart them. Very simple. <!--l. 68-->

  <p class="noindent">There's just one catch: all of them
  suck. There's <a href=
  "http://cr.yp.to/daemontools.html">daemontools</a>, which barely
  builds (if at all) and then assumes that daemons don't
  fork. Stupid. There's <a href=
  "http://www.fefe.de/minit/">minit</a>, which bafflingly required
  dietlibc to even compile and assumed it was going to be the one
  true init (not user space at all). There's <a href=
  "http://www.nico.schottelius.org/software/cinit/">cinit</a>,
  which got through a compile, then barfed on its documentation,
  and the end result is some huge number of weird shell scripts to
  make it work, and, again, it wants to be the one true init.
  Finally , <a href="http://smarden.org/runit/">runit</a> is some
  of the worst C code I've seen in years and has the same
  weird design as daemontools. <!--l. 78-->

  <p class="noindent">After trying every single one, I just gave
  up. Either they didn't build, were too complex, expected to
  be the one true init, poorly documented, not maintained, and
  definitely not going to work for this manual. My only choice was
  to shave a yak and write my own. <!--l. 82-->

  <p class="noindent">The end result is <span class=
  "pcrro7t-">procer</span>, which lives in <span class=
  "pcrb7t-">tools/procer</span> and does most of what you need
  in a USPM. It works a lot like daemontools or minit, but is much
  simpler, with these differences: <!--l. 86-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-41002x1">It is much simpler, with
    only a single command to start all your stuff and keep it
    running.

    <li class="enumerate" id="x1-41004x2">It will build anywhere
    Mongrel2 builds, because it reuses the <span class=
    "pcrb7t-">libm2.a</span> library from the Mongrel2 project.

    <li class="enumerate" id="x1-41006x3">It doesn't want to
    be the one true init, or even expect to be running constantly.
    You can start it and stop it and it will only run what's
    not already running.

    <li class="enumerate" id="x1-41008x4">It assumes that programs
    will always daemonize and create a PID file. This turns out to
    be way easier to manage than what daemontools does, so
    I'm sort of baffled why daemontools is how it is.

    <li class="enumerate" id="x1-41010x5">It has dependency
    management so that you can have processes start only after
    others have finished.

    <li class="enumerate" id="x1-41012x6">It still uses simple
    files to configure itself that are in separate directories.

    <li class="enumerate" id="x1-41014x7">It can be run as root
    and, like Mongrel2, it will drop privileges to the owner of the
    profile directory before it runs the command. This is
    incredibly useful because it lets you setup scripts that run as
    other users without much configuration or fuss.

    <li class="enumerate" id="x1-41016x8">It is dinky, tiny and
    well written so you can understand it, even though it's
    written in C.

    <li class="enumerate" id="x1-41018x9">Best of all, I can use it
    in this book and you won't go insane trying to install it
    or use it like the others.
  </ol><!--l. 108-->

  <p class="noindent">Of course, if you have something else you
  like then, please, use it. Anything that automates process
  management will be your friend. In this manual, to keep things
  simple and easily understood, I'll be using <span class=
  "pcrro7t-">procer</span> to tell you how to setup everything. 
  <!--l. 112-->

  <p class="noindent"><a id="x1-41019r6" name="x1-41019r6"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 6:</span> <span class=
      "content"><span class="pplri7t-">Alternatives to</span>
      <span class="pplri7t-">procer</span></span>
    </div><!--tex4ht:label?: x1-41019r6 -->

    <div class="quote">
      <!--l. 113-->

      <p class="indent">I wrote procer mostly for this book, but I
      also use it for my Mongrel2 deployments. It works for me but
      you can try other solutions. By default, Mongrel2 will work
      with either daemontools/runit style, or init.d style
      launchers. If Mongrel2 runs as a regular user, it assumes
      that you want runit style (don't fork, write to
      stdout/stderr). If you run as root, it assumes you want
      init.d style like what procer uses (fork, drop priv, chroot,
      etc.). <!--l. 120-->

      <p class="indent">You should check out <a href=
      "http://github.com/peterkeen/proclaunch">proclaunch</a> as
      another alternative that is similar to procer, and inspired
      by procer, but written in Perl with a few more features. 
      <!--l. 124-->

      <p class="indent">Either way, Mongrel2 is practical, and does
      generally the right thing with today's tools. Want to
      use daemontools? Fine, just run it <span class=
      "obeylines-h verb"><span class=
      "pcrr7t-">mongrel2</span><span class=
      "pcrr7t-">&nbsp;config.sqlite</span><span class=
      "pcrr7t-">&nbsp;server_uuid</span></span> and it'll
      work right. Want to put it in init.d or use procer or
      similar? Fine, run it as root.
    </div>
  </div>
  <hr class="endfloat">

  <h4 class="subsectionHead"><span class="titlemark">4.1.2</span>
  <a id="x1-420004.1.2" name="x1-420004.1.2"></a>Installing
  procer</h4><!--l. 132-->

  <p class="noindent">Installing procer is very easy. It's a
  single little binary and it lives in <span class=
  "pcrb7t-">tools/procer</span> in the Mongrel2 source.
  Here's how you'd install it totally from scratch as
  if you hadn't even build Mongrel2 yet: <!--l. 136-->

  <p class="noindent"><a id="x1-42001r13" name="x1-42001r13"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 13:</span> <span class=
      "content"><span class="pplri7t-">Install</span> <span class=
      "pplri7t-">procer</span></span>
    </div><!--tex4ht:label?: x1-42001r13 -->
    <!--l. 137-->

    <div class="lstlisting" id="listing-11">
      <span class="label"><a id="x1-42002r1" name=
      "x1-42002r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">projects</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-42003r2" name=
      "x1-42003r2"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">make</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">clean</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">all</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">install</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-42004r3" name=
      "x1-42004r3"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-42005r4" name=
      "x1-42005r4"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">make</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">clean</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">all</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">install</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 145-->

  <p class="noindent">That's the entire install process, and
  now procer is in <span class="pcrb7t-">/usr/local/bin</span> so
  you can use it. In the rest of this chapter you'll learn
  how to use <span class="pcrro7t-">procer</span> by just setting
  up the Mongrel2 demo completely and messing around with it.

  <h3 class="sectionHead"><span class="titlemark">4.2</span> <a id=
  "x1-430004.2" name="x1-430004.2"></a>The Plan</h3><!--l. 153-->

  <p class="noindent">We need to plan this deployment to make sure
  we get the end result correct: <!--l. 155-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-43002x1">Create a deployment area
    where everything will live.

    <li class="enumerate" id="x1-43004x2">Create a config.sqlite
    that will work with the demos in <span class=
    "pcrro7t-">examples</span>.

    <li class="enumerate" id="x1-43006x3">Setup procer to run
    Mongrel2 and the three demo Python scripts for chat,
    handlertest, and mp3stream, and have it run the fake backend
    web.py project so we have something to proxy to.

    <li class="enumerate" id="x1-43008x4">Get all the static file
    content working.

    <li class="enumerate" id="x1-43010x5">Test out that procer is
    keeping things running and play with taking things down and up
    and using <span class="pcrro7t-">m2sh</span> to work with the
    deployment.
  </ol><!--l. 165-->

  <p class="noindent">Once you have this setup working, you can
  then start to make your own deployments and tweak things as you
  need for your own applications. Remember that the goal is to get
  you to <span class="pplri7t-">automate</span> everything as much
  as possible, so you can go further than this then do it. 
  <!--l. 170-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">4.3</span> <a id=
  "x1-440004.3" name="x1-440004.3"></a>Step 1: The Deployment
  Area</h3><!--l. 172-->

  <p class="noindent">We'll need a place to put all this
  stuff and run it so that Mongrel2 can chroot there, procer knows
  where its profiles are, and its all nice and clean. For these
  instructions, we're just going to make some directories in
  your home directory, but feel free to change this up later if you
  find a better way. <!--l. 177-->

  <p class="noindent"><a id="x1-44001r14" name="x1-44001r14"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 14:</span> <span class=
      "content"><span class="pplri7t-">Make Deployment</span>
      <span class="pplri7t-">Directories</span></span>
    </div><!--tex4ht:label?: x1-44001r14 -->
    <!--l. 178-->

    <div class="lstlisting" id="listing-12">
      <span class="label"><a id="x1-44002r1" name=
      "x1-44002r1"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">go</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">first</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44003r2" name=
      "x1-44003r2"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">~/</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44004r3" name=
      "x1-44004r3"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44005r4" name=
      "x1-44005r4"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">create</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">dir</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44006r5" name=
      "x1-44006r5"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mkdir</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44007r6" name=
      "x1-44007r6"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44008r7" name=
      "x1-44008r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44009r8" name=
      "x1-44009r8"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">fill</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">it</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">with</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">directories</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">we</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">need</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44010r9" name=
      "x1-44010r9"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mkdir</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tmp</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">logs</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">static</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44011r10" name=
      "x1-44011r10"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44012r11" name=
      "x1-44012r11"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">create</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profile</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">dirs</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">each</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">thing</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44013r12" name=
      "x1-44013r12"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44014r13" name=
      "x1-44014r13"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mkdir</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mp3stream</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">handlertest</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">web</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44015r14" name=
      "x1-44015r14"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">..</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44016r15" name=
      "x1-44016r15"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44017r16" name=
      "x1-44017r16"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">setup</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">database</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">initially</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44018r17" name=
      "x1-44018r17"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">init</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44019r18" name=
      "x1-44019r18"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44020r19" name=
      "x1-44020r19"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">copy</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2_conf</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sample</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">from</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">source</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">to</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">here</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44021r20" name=
      "x1-44021r20"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cp</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">~/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">tests</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2_org</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44022r21" name=
      "x1-44022r21"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44023r22" name=
      "x1-44023r22"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">see</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">our</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">end</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">results</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44024r23" name=
      "x1-44024r23"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ls</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-44025r24" name=
      "x1-44025r24"></a></span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">logs</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">static</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tmp</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 207-->

  <p class="noindent">Hopefully, you're starting to see how
  you could easily automate this so that you don't have to do
  this all the time. I'm just showing you how to &ldquo;make
  the sausage&rdquo; so that you know where everything goes. Future
  versions of <span class="pcrro7t-">m2sh</span> will most likely
  create deployment directories like this automatically. 
  <!--l. 212-->

  <p class="noindent">What we've done here is the following:

  <ol class="enumerate1">
    <li class="enumerate" id="x1-44029x1">Setup a <span class=
    "pcrb7t-">~/deployment</span> directory we'll put
    everything in.

    <li class="enumerate" id="x1-44031x2">Created <span class=
    "pcrb7t-">run</span>, <span class="pcrb7t-">tmp</span>,
    <span class="pcrb7t-">logs</span>, and <span class=
    "pcrb7t-">profiles</span> that Mongrel2 and procer need to run.

    <li class="enumerate" id="x1-44033x3">In profiles we started
    dirs for <span class="pcrb7t-">chat</span>, <span class=
    "pcrb7t-">mp3stream</span>, <span class=
    "pcrb7t-">handlertest</span>, <span class="pcrb7t-">web</span>
    and <span class="pcrb7t-">mongrel2</span>, that procer will
    read files out of to get all our gear up and running.

    <li class="enumerate" id="x1-44035x4">Initialized the
    <span class="pcrb7t-">config.sqlite</span> file we'll be
    filling in with our modififed config.py.

    <li class="enumerate" id="x1-44037x5">Copied the <span class=
    "pcrb7t-">mongrel2</span><span class="pcrb7t-">_org.py</span>
    example file over to our deployment so we can modify it.
  </ol>

  <h3 class="sectionHead"><span class="titlemark">4.4</span> <a id=
  "x1-450004.4" name="x1-450004.4"></a>Step 2: The mongrel2.org
  Configuration</h3><!--l. 226-->

  <p class="noindent">Now we're ready to get the
  configuration working. Here's the thing, though: you should
  try to alter the configuration yourself. I've already given
  you the file and you are going to have to make the changes to
  meet the requirements for this deployment directory. Here's
  what you have to change in <span class="pcrb7t-">config.py</span>
  to make everything work right: <!--l. 231-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-45002x1">Get rid of the
    <span class="pcrro7t-">test</span><span class=
    "pcrro7t-">_directory</span> handler, since we won't need
    it, and any routes that mention it.

    <li class="enumerate" id="x1-45004x2">Change the <span class=
    "pcrro7t-">base</span> of <span class=
    "pcrro7t-">chat</span><span class=
    "pcrro7t-">_demo</span><span class="pcrro7t-">_dir</span> to
    <span class="pcrb7t-">'static/chatdemo/'</span>, which
    we'll setup at the end.

    <li class="enumerate" id="x1-45006x3">Modify the server
    <span class="pcrro7t-">chroot</span> so that it's
    <span class="pcrb7t-">/home/YOU/deployment/</span>.

    <li class="enumerate" id="x1-45008x4">Use the <span class=
    "pcrro7t-">m2sh uuid</span> command to make some new UUIDs for
    all the existing ones. This is optional, but probably a good
    idea to get in the habit now.

    <li class="enumerate" id="x1-45010x5">Change the <span class=
    "pcrro7t-">port</span> for <span class=
    "pcrro7t-">web</span><span class=
    "pcrro7t-">_app</span><span class="pcrro7t-">_proxy</span> so
    it points to 8080 instead of 80.

    <li class="enumerate" id="x1-45012x6">Finally, change any
    mention of &ldquo;mongrel2.org&rdquo; into
    &ldquo;localhost&rdquo; so that you can run it locally.
  </ol><!--l. 244-->

  <p class="noindent">Once you have that all edited, you should be
  able to run <span class="pcrro7t-">m2sh load -db</span>
  <span class="pcrro7t-">config.sqlite -config config.py</span> and
  it'll just load it up. Try using <span class=
  "pcrro7t-">m2sh</span> <span class="pcrro7t-">servers</span> and
  <span class="pcrro7t-">m2sh hosts</span> to take a peek. 
  <!--l. 249-->

  <p class="noindent">To test it out at this stage you can just run
  the config.sqlite that you did with these commands: <!--l. 252-->

  <p class="noindent"><a id="x1-45013r15" name="x1-45013r15"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 15:</span> <span class=
      "content"><span class="pplri7t-">Testing The Initial</span>
      <span class="pplri7t-">Configuration</span></span>
    </div><!--tex4ht:label?: x1-45013r15 -->
    <!--l. 253-->

    <div class="lstlisting" id="listing-13">
      <span class="label"><a id="x1-45014r1" name=
      "x1-45014r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">start</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-45015r2" name=
      "x1-45015r2"></a></span><span class=
      "pcrr7t-x-x-90">^</span><span class=
      "pcrr7t-x-x-90">C</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-45016r3" name=
      "x1-45016r3"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">start</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-45017r4" name=
      "x1-45017r4"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">less</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">logs</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">error</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-45018r5" name=
      "x1-45018r5"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">stop</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">murder</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 262-->

  <p class="noindent">That's enough to make sure it runs, but
  you've got nothing running, so it mostly won't work
  at all. Just start up and then kill it right after.

  <h3 class="sectionHead"><span class="titlemark">4.5</span> <a id=
  "x1-460004.5" name="x1-460004.5"></a>Step 3: Setup procer</h3>
  <!--l. 269-->

  <p class="noindent">Now we want to make <span class=
  "pcrro7t-">procer</span> start everything for us and keep it
  running. How <span class="pcrro7t-">procer</span> works is you
  put a few special files into a directory in <span class=
  "pcrb7t-">profiles</span>. This directory (say <span class=
  "pcrb7t-">chat</span>) is the profile for that app. When you
  start <span class="pcrro7t-">procer</span>, you point it at the
  main <span class="pcrb7t-">profiles</span> directory and it tries
  to run it. It's dead simple and very easy to automate, so
  we'll do it by hand and then you can do some automation
  later. <!--l. 277-->

  <p class="noindent">Let's first setup a basic config that
  gets our skeleton profiles and make sure procer can run
  everything: <!--l. 280-->

  <p class="noindent"><a id="x1-46001r16" name="x1-46001r16"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 16:</span> <span class=
      "content"><span class="pplri7t-">Skeleton procer</span>
      <span class="pplri7t-">Setup</span></span>
    </div><!--tex4ht:label?: x1-46001r16 -->
    <!--l. 281-->

    <div class="lstlisting" id="listing-14">
      <span class="label"><a id="x1-46002r1" name=
      "x1-46002r1"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46003r2" name=
      "x1-46003r2"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ls</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46004r3" name=
      "x1-46004r3"></a></span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">handlertest</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mp3stream</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">web</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46005r4" name=
      "x1-46005r4"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46006r5" name=
      "x1-46006r5"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">make</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">all</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">restart</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">settings</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46007r6" name=
      "x1-46007r6"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">in</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&#8902;;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">do</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">touch</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">restart</span><span class=
      "pcrr7t-x-x-90">;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">done</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46008r7" name=
      "x1-46008r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46009r8" name=
      "x1-46009r8"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">make</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">all</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">empty</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">dependencies</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46010r9" name=
      "x1-46010r9"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">in</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&#8902;;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">do</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">touch</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">depends</span><span class=
      "pcrr7t-x-x-90">;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">done</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46011r10" name=
      "x1-46011r10"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46012r11" name=
      "x1-46012r11"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">setup</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pid_files</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">to</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">some</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sort</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">of</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">default</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46013r12" name=
      "x1-46013r12"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">in</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&#8902;;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">do</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">echo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">PWD</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">pid_file</span><span class=
      "pcrr7t-x-x-90">;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">done</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46014r13" name=
      "x1-46014r13"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">pid_file</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46015r14" name=
      "x1-46015r14"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46016r15" name=
      "x1-46016r15"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">get</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">script</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">setup</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">to</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">do</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">nothing</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46017r16" name=
      "x1-46017r16"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">in</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&#8902;;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">do</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">echo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">#!/</span><span class=
      "pcrr7t-x-x-90">bin</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">sh</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">done</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46018r17" name=
      "x1-46018r17"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">in</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&#8902;;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">do</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chmod</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">u</span><span class=
      "pcrr7t-x-x-90">+</span><span class=
      "pcrr7t-x-x-90">x</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">i</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">done</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46019r18" name=
      "x1-46019r18"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46020r19" name=
      "x1-46020r19"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">check</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">out</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">what</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">we</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">did</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46021r20" name=
      "x1-46021r20"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ls</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class="pcrr7t-x-x-90">lR</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 305-->

  <p class="noindent">With all of that, you can then try to run
  <span class="pcrro7t-">procer</span> to watch it fail but still
  try to run everything: <!--l. 308-->

  <div class="lstlisting" id="listing-15">
    <span class="label"><a id="x1-46022r1" name=
    "x1-46022r1"></a></span><span class=
    "pcrr7t-">&gt;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">sudo</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">procer</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr8c-">$</span><span class="pcrr7t-">PWD</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr8c-">$</span><span class="pcrr7t-">PWD</span><span class=
    "pcrr7t-">/../</span><span class=
    "pcrr7t-">run</span><span class="pcrr7t-">/</span><span class=
    "pcrr7t-">procer</span><span class=
    "pcrr7t-">.</span><span class="pcrr7t-">pid</span><span class=
    "pcrr7t-">&nbsp;</span><br>
    <span class="label"><a id="x1-46023r2" name=
    "x1-46023r2"></a></span><span class=
    "pcrr7t-">&gt;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">less</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">error</span><span class=
    "pcrr7t-">.</span><span class="pcrr7t-">log</span>
  </div><!--l. 313-->

  <p class="noindent">This is assuming that you are still in the
  <span class="pcrb7t-">profiles</span> directory. You should see
  the file <span class="pcrb7t-">error.log</span> get created and
  probably some messages printed to the screen. Just ignore any
  mention of Mongrel2 since that's probably just cruft from
  the <span class="pcrb7t-">libm2.a</span> we haven't
  removed. <!--l. 319-->

  <p class="noindent">Take a look in the <span class=
  "pcrb7t-">error.log</span> and you'll see it's not
  necessarily errors but information on how things were run. You
  should see something like this for each profile: <!--l. 323-->

  <p class="noindent"><a id="x1-46024r17" name="x1-46024r17"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 17:</span> <span class=
      "content"><span class="pplri7t-">First Dummy Run Of</span>
      <span class="pplri7t-">procer</span></span>
    </div><!--tex4ht:label?: x1-46024r17 -->
    <!--l. 324-->

    <div class="lstlisting" id="listing-16">
      <span class="label"><a id="x1-46025r1" name=
      "x1-46025r1"></a></span><span class=
      "pcrr7t-x-x-90">DEBUG</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">c</span><span class=
      "pcrr7t-x-x-90">:232:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Loading</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">5</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">actions</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46026r2" name=
      "x1-46026r2"></a></span><span class=
      "pcrr7t-x-x-90">DEBUG</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">c</span><span class=
      "pcrr7t-x-x-90">:83:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">STARTED</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46027r3" name=
      "x1-46027r3"></a></span><span class=
      "pcrr7t-x-x-90">ERROR</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Failed</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">to</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">open</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">PID</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">file</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">zedshaw</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">reading</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46028r4" name=
      "x1-46028r4"></a></span><span class=
      "pcrr7t-x-x-90">ERROR</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Failed</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">to</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">open</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">PID</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">file</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">zedshaw</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">reading</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46029r5" name=
      "x1-46029r5"></a></span><span class=
      "pcrr7t-x-x-90">INFO</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">No</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">previous</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">running</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">continuing</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">on</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46030r6" name=
      "x1-46030r6"></a></span><span class=
      "pcrr7t-x-x-90">DEBUG</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">c</span><span class=
      "pcrr7t-x-x-90">:37:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ACTION</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">command</span><span class=
      "pcrr7t-x-x-90">=/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">zedshaw</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pid_file</span><span class=
      "pcrr7t-x-x-90">=/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">zedshaw</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">restart</span><span class=
      "pcrr7t-x-x-90">=1,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">depends</span><span class=
      "pcrr7t-x-x-90">=(</span><span class=
      "pcrr7t-x-x-90">null</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46031r7" name=
      "x1-46031r7"></a></span><span class=
      "pcrr7t-x-x-90">DEBUG</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">c</span><span class=
      "pcrr7t-x-x-90">:56:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">WAITING</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">FOR</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">CHILD</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46032r8" name=
      "x1-46032r8"></a></span><span class=
      "pcrr7t-x-x-90">INFO</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Now</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">running</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">as</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">UID</span><span class=
      "pcrr7t-x-x-90">:1000,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">GID</span><span class=
      "pcrr7t-x-x-90">:1000</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46033r9" name=
      "x1-46033r9"></a></span><span class=
      "pcrr7t-x-x-90">DEBUG</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">c</span><span class=
      "pcrr7t-x-x-90">:60:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Command</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ran</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">and</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">exited</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">successfully</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">now</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">looking</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">PID</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">file</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46034r10" name=
      "x1-46034r10"></a></span><span class=
      "pcrr7t-x-x-90">ERROR</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">didn</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">t</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">make</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pidfile</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">zedshaw</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">.</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 338-->

  <p class="noindent">I've cleaned this up a bit and, again,
  ignore that it's saying &ldquo;Mongrel2&rdquo;;
  that's just cruft from the library since it was originally
  designed for Mongrel2. What you can see here is the following:

  <ol class="enumerate1">
    <li class="enumerate" id="x1-46036x1">It starts up and says it
    found 5 profiles.

    <li class="enumerate" id="x1-46038x2">It starts chat, and says
    there's no PID file so it's good to continue.

    <li class="enumerate" id="x1-46040x3">It reports what ACTION
    it's running, so you can see the config.

    <li class="enumerate" id="x1-46042x4">It spawns off your
    <span class="pcrb7t-">run</span> script, <span class=
    "pplri7t-">drops privilege</span> and says it's WAITING
    for your script to exit.

    <li class="enumerate" id="x1-46044x5">After your script runs,
    it looks for the PID file you gave in <span class=
    "pcrb7t-">pid</span><span class="pcrb7t-">_file</span> and, if
    it's not there, it exits that action.

    <li class="enumerate" id="x1-46046x6">It does this for all of
    them and, since none of them run right, <span class=
    "pcrro7t-">procer</span> exits.
  </ol><!--l. 352-->

  <p class="noindent">Next up, let's get Mongrel2 running
  inside <span class="pcrro7t-">procer</span>: <!--l. 354-->

  <p class="noindent"><a id="x1-46047r18" name="x1-46047r18"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 18:</span> <span class=
      "content"><span class="pplri7t-">procer Config For</span>
      <span class="pplri7t-">Mongrel2</span></span>
    </div><!--tex4ht:label?: x1-46047r18 -->
    <!--l. 355-->

    <div class="lstlisting" id="listing-17">
      <span class="label"><a id="x1-46048r1" name=
      "x1-46048r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">~/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46049r2" name=
      "x1-46049r2"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">make</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">as</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">root</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46050r3" name=
      "x1-46050r3"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chown</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">root</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">root</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46051r4" name=
      "x1-46051r4"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46052r5" name=
      "x1-46052r5"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">tell</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">where</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">puts</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">its</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">pid_file</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46053r6" name=
      "x1-46053r6"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">notice</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">not</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">on</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">this</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46054r7" name=
      "x1-46054r7"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">echo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">PWD</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">pid_file</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46055r8" name=
      "x1-46055r8"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46056r9" name=
      "x1-46056r9"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">make</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">script</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">start</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">notice</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">on</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">this</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46057r10" name=
      "x1-46057r10"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">echo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">PWD</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46058r11" name=
      "x1-46058r11"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">echo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">start</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46059r12" name=
      "x1-46059r12"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46060r13" name=
      "x1-46060r13"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">check</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">out</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">results</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46061r14" name=
      "x1-46061r14"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46062r15" name=
      "x1-46062r15"></a></span><span class=
      "pcrr7t-x-x-90">#!/</span><span class=
      "pcrr7t-x-x-90">bin</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46063r16" name=
      "x1-46063r16"></a></span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">YOU</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46064r17" name=
      "x1-46064r17"></a></span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">start</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 376-->

  <p class="noindent">Obviously, you don't have to use a
  series of <span class="pcrro7t-">echo</span> commands to make
  these scripts. You can edit them just fine, we're just
  doing it this way so that you can follow along easier. 
  <!--l. 380-->

  <p class="noindent">Now, make sure you don't have any other
  Mongrel2 processes running, and then start procer again to see if
  it starts this configuration correctly. <!--l. 385-->

  <p class="noindent"><a id="x1-46065r19" name="x1-46065r19"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 19:</span> <span class=
      "content"><span class="pplri7t-">Using procer To Run</span>
      <span class="pplri7t-">Mongrel2</span></span>
    </div><!--tex4ht:label?: x1-46065r19 -->
    <!--l. 386-->

    <div class="lstlisting" id="listing-18">
      <span class="label"><a id="x1-46066r1" name=
      "x1-46066r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">~/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46067r2" name=
      "x1-46067r2"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">clear</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">out</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">the</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">error</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">testing</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46068r3" name=
      "x1-46068r3"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">rm</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">error</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46069r4" name=
      "x1-46069r4"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46070r5" name=
      "x1-46070r5"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">start</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46071r6" name=
      "x1-46071r6"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">PWD</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">PWD</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46072r7" name=
      "x1-46072r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46073r8" name=
      "x1-46073r8"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">see</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">if</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">is</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">running</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46074r9" name=
      "x1-46074r9"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ps</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ax</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">|</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">grep</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46075r10" name=
      "x1-46075r10"></a></span><span class=
      "pcrr7t-x-x-90">17934</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">?</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Ss</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">0:00</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">zedshaw</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">zedshaw</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46076r11" name=
      "x1-46076r11"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46077r12" name=
      "x1-46077r12"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">see</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">if</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">is</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">running</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46078r13" name=
      "x1-46078r13"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ps</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ax</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">|</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">grep</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-46079r14" name=
      "x1-46079r14"></a></span><span class=
      "pcrr7t-x-x-90">17944</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">?</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Ssl</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">0:00</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ba0019c0</span><span class=
      "pcrr7t-x-x-90">-9140-4</span><span class=
      "pcrr7t-x-x-90">f82</span><span class=
      "pcrr7t-x-x-90">-80</span><span class=
      "pcrr7t-x-x-90">ca</span><span class=
      "pcrr7t-x-x-90">-0</span><span class=
      "pcrr7t-x-x-90">f4f2e81def7</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 405-->

  <p class="noindent">To watch <span class="pcrro7t-">procer</span>
  in action, try doing <span class="pcrro7t-">m2sh stop -db
  config.sqlite -host</span> <span class="pcrro7t-">localhost
  -murder</span> and then look at <span class=
  "pcrb7t-">profiles/error.log</span> and watch Mongrel2 come right
  back.

  <h4 class="subsectionHead"><span class="titlemark">4.5.1</span>
  <a id="x1-470004.5.1" name="x1-470004.5.1"></a>The Python
  Examples</h4><!--l. 412-->

  <p class="noindent">We've got a good setup of <span class=
  "pcrro7t-">procer</span> going and it keeps Mongrel2 running, so
  let's setup a similar thing for each of our little Python
  demos that we'll need. In order to do this, though, we sort
  of have to &ldquo;hack in&rdquo; making them daemonize and create
  PID files with a little shell script help. Let's start with
  the <span class="pcrro7t-">chat</span> demo and, assuming your
  mongrel2 source is in <span class=
  "pcrb7t-">~/projects/mongrel2</span>, you will change
  <span class="pcrb7t-">profiles/chat/run</span> to be like this: 
  <!--l. 420-->

  <p class="noindent"><a id="x1-47001r20" name="x1-47001r20"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 20:</span> <span class=
      "content"><span class="pplri7t-">Run Script For Chat</span>
      <span class="pplri7t-">Demo</span></span>
    </div><!--tex4ht:label?: x1-47001r20 -->
    <!--l. 421-->

    <div class="lstlisting" id="listing-19">
      <span class="label"><a id="x1-47002r1" name=
      "x1-47002r1"></a></span><span class=
      "pcrro7t-x-x-90">#</span><span class=
      "pcrro7t-x-x-90">!/</span><span class=
      "pcrro7t-x-x-90">bin</span><span class=
      "pcrro7t-x-x-90">/</span><span class=
      "pcrro7t-x-x-90">sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47003r2" name=
      "x1-47003r2"></a></span><span class=
      "pcrr7t-x-x-90">set</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">e</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47004r3" name=
      "x1-47004r3"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47005r4" name=
      "x1-47005r4"></a></span><span class=
      "pcrr7t-x-x-90">DEPLOY</span><span class=
      "pcrr7t-x-x-90">=/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">YOU</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47006r5" name=
      "x1-47006r5"></a></span><span class=
      "pcrr7t-x-x-90">SOURCE</span><span class=
      "pcrr7t-x-x-90">=/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">YOU</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">projects</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47007r6" name=
      "x1-47007r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47008r7" name=
      "x1-47008r7"></a></span><span class=
      "pcrb7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">SOURCE</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47009r8" name=
      "x1-47009r8"></a></span><span class=
      "pcrb7t-x-x-90">nohup</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">u</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">2&gt;&amp;1</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&amp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47010r9" name=
      "x1-47010r9"></a></span><span class=
      "pcrb7t-x-x-90">echo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">!</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">DEPLOY</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 434-->

  <p class="noindent">This little script uses some funky features
  you might not be familiar with, but which are nice to learn, so
  let's take a look:

  <ol class="enumerate1">
    <li class="enumerate" id="x1-47012x1">The first trick is
    <span class="pcrro7t-">set -e</span>, which tells bash to bail
    if there's any errors in your script. This is a
    <span class="pplri7t-">huge</span> life saver in system
    scripts.

    <li class="enumerate" id="x1-47014x2">Next, you point some
    variables at where the deployment and Mongrel2 source live,
    remembering to not type YOU but your username.

    <li class="enumerate" id="x1-47016x3">After that, you run the
    <span class="pcrb7t-">chat.py</span> using a program called
    <span class="pcrro7t-">nohup</span>. This basically daemonizes
    your script by redirecting output and preventing the program
    from exiting, and then you background it with <span class=
    "obeylines-h verb pcrr7t-">&amp;</span>.

    <li class="enumerate" id="x1-47018x4">The final thing we do is
    echo the magic variable <span class=
    "obeylines-h verb pcrr7t-">$!</span> (the PID of the last
    process started in the background) to the <span class=
    "pcrb7t-">chat.pid</span> file in the profile directory.
  </ol><!--l. 452-->

  <p class="noindent">When you run this manually, you should see
  something like this: <!--l. 454-->

  <div class="lstlisting" id="listing-20">
    <span class="label"><a id="x1-47019r1" name=
    "x1-47019r1"></a></span><span class=
    "pcrr7t-">deployment</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&gt;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">./</span><span class=
    "pcrr7t-">profiles</span><span class=
    "pcrr7t-">/</span><span class="pcrr7t-">chat</span><span class=
    "pcrr7t-">/</span><span class="pcrr7t-">run</span><span class=
    "pcrr7t-">&nbsp;</span><br>
    <span class="label"><a id="x1-47020r2" name=
    "x1-47020r2"></a></span><span class=
    "pcrr7t-">nohup</span><span class=
    "pcrr7t-">:</span><span class="pcrr7t-">&nbsp;</span><span class="pcrr7t-">redirecting</span><span class="pcrr7t-">&nbsp;</span><span class="pcrr7t-">stderr</span><span class="pcrr7t-">&nbsp;</span><span class="pcrr7t-">to</span><span class="pcrr7t-">&nbsp;</span><span class="pcrr7t-">stdout</span><span class="pcrr7t-">&nbsp;</span><br>
    <span class="label"><a id="x1-47021r3" name=
    "x1-47021r3"></a></span><span class="pcrr7t-">&nbsp;</span><br>
    <span class="label"><a id="x1-47022r4" name=
    "x1-47022r4"></a></span><span class=
    "pcrr7t-">deployment</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&gt;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">ps</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">ax</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">|</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">grep</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">chat</span><span class="pcrr7t-">&nbsp;</span><br>
    <span class="label"><a id="x1-47023r5" name=
    "x1-47023r5"></a></span><span class=
    "pcrr7t-">19305</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">pts</span><span class="pcrr7t-">/1</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">Sl</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">0:00</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">python</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">chat</span><span class="pcrr7t-">.</span><span class=
    "pcrr7t-">py</span><span class="pcrr7t-">&nbsp;</span><br>
    <span class="label"><a id="x1-47024r6" name=
    "x1-47024r6"></a></span><span class="pcrr7t-">&nbsp;</span><br>
    <span class="label"><a id="x1-47025r7" name=
    "x1-47025r7"></a></span><span class=
    "pcrr7t-">deployment</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">&gt;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">kill</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">-</span><span class="pcrr7t-">TERM</span><span class=
    "pcrr7t-">&nbsp;</span><span class="pcrr7t-">19305</span>
  </div><!--l. 464-->

  <p class="noindent">After all that, you can then try out
  <span class="pcrro7t-">procer</span> again to see if it properly
  runs the chat demo as well as mongrel2: <!--l. 467-->

  <p class="noindent"><a id="x1-47026r21" name="x1-47026r21"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 21:</span> <span class=
      "content"><span class="pplri7t-">Running procer With
      Chat</span> <span class="pplri7t-">Demo</span></span>
    </div><!--tex4ht:label?: x1-47026r21 -->
    <!--l. 468-->

    <div class="lstlisting" id="listing-21">
      <span class="label"><a id="x1-47027r1" name=
      "x1-47027r1"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">to</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">get</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">stuff</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">started</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47028r2" name=
      "x1-47028r2"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sudo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">PWD</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">PWD</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47029r3" name=
      "x1-47029r3"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47030r4" name=
      "x1-47030r4"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">see</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">if</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">it</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">all</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">running</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47031r5" name=
      "x1-47031r5"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ps</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ax</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">|</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">grep</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47032r6" name=
      "x1-47032r6"></a></span><span class=
      "pcrr7t-x-x-90">19607</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">?</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Ss</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">0:00</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">zedshaw</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">zedshaw</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">run</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">procer</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47033r7" name=
      "x1-47033r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47034r8" name=
      "x1-47034r8"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ps</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ax</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">|</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">grep</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47035r9" name=
      "x1-47035r9"></a></span><span class=
      "pcrr7t-x-x-90">19621</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">?</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Ssl</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">0:00</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ba0019c0</span><span class=
      "pcrr7t-x-x-90">-9140-4</span><span class=
      "pcrr7t-x-x-90">f82</span><span class=
      "pcrr7t-x-x-90">-80</span><span class=
      "pcrr7t-x-x-90">ca</span><span class=
      "pcrr7t-x-x-90">-0</span><span class=
      "pcrr7t-x-x-90">f4f2e81def7</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47036r10" name=
      "x1-47036r10"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47037r11" name=
      "x1-47037r11"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ps</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ax</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">|</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">grep</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47038r12" name=
      "x1-47038r12"></a></span><span class=
      "pcrr7t-x-x-90">19609</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">?</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Sl</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">0:00</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47039r13" name=
      "x1-47039r13"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47040r14" name=
      "x1-47040r14"></a></span><span class=
      "pcrr7t-x-x-90">#</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">try</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">killing</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">to</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">see</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">if</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">it</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">comes</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">back</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47041r15" name=
      "x1-47041r15"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">kill</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">TERM</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">`</span><span class=
      "pcrr7t-x-x-90">cat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span><span class=
      "pcrr8c-x-x-90">`</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47042r16" name=
      "x1-47042r16"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47043r17" name=
      "x1-47043r17"></a></span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ps</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ax</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">|</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">grep</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47044r18" name=
      "x1-47044r18"></a></span><span class=
      "pcrr7t-x-x-90">19669</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">?</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Sl</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">0:00</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">.</span><span class="pcrr7t-x-x-90">py</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 490-->

  <p class="noindent">If you go look at <span class=
  "pcrb7t-">profiles/error.log</span>, you'll see that
  <span class="pcrro7t-">procer</span> is also running each of them
  as the right user, with chat being run as you, but Mongrel2 being
  run as root so it can chroot/drop privileges properly. 
  <!--l. 494-->

  <p class="noindent">Rather than give you a walk through each of
  these setups, here's the run scripts for the remaining
  files: <!--l. 497-->

  <p class="noindent"><a id="x1-47045r22" name="x1-47045r22"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 22:</span> <span class=
      "content"><span class="pplri7t-">Remaining Run</span>
      <span class="pplri7t-">Scripts</span></span>
    </div><!--tex4ht:label?: x1-47045r22 -->
    <span class=
    "pcrb7t-x-x-90">profiles/handlertest/run</span>_________________________________________<!--l. 501-->

    <div class="lstlisting" id="listing-22">
      <span class="label"><a id="x1-47046r1" name=
      "x1-47046r1"></a></span><span class=
      "pcrro7t-x-x-90">#</span><span class=
      "pcrro7t-x-x-90">!/</span><span class=
      "pcrro7t-x-x-90">bin</span><span class=
      "pcrro7t-x-x-90">/</span><span class=
      "pcrro7t-x-x-90">sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47047r2" name=
      "x1-47047r2"></a></span><span class=
      "pcrr7t-x-x-90">set</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">e</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47048r3" name=
      "x1-47048r3"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47049r4" name=
      "x1-47049r4"></a></span><span class=
      "pcrr7t-x-x-90">DEPLOY</span><span class=
      "pcrr7t-x-x-90">=/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">YOU</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47050r5" name=
      "x1-47050r5"></a></span><span class=
      "pcrr7t-x-x-90">SOURCE</span><span class=
      "pcrr7t-x-x-90">=/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">YOU</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">projects</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47051r6" name=
      "x1-47051r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47052r7" name=
      "x1-47052r7"></a></span><span class=
      "pcrb7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">SOURCE</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">http_0mq</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47053r8" name=
      "x1-47053r8"></a></span><span class=
      "pcrb7t-x-x-90">nohup</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">u</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">http</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">2&gt;&amp;1</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">http</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&amp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47054r9" name=
      "x1-47054r9"></a></span><span class=
      "pcrb7t-x-x-90">echo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">!</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">DEPLOY</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">handlertest</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">handlertest</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span>
    </div><!--l. 513-->

    <p class="noindent"><span class=
    "pcrb7t-x-x-90">profiles/mp3stream/run</span>__________________________________________<!--l. 516-->

    <div class="lstlisting" id="listing-23">
      <span class="label"><a id="x1-47055r1" name=
      "x1-47055r1"></a></span><span class=
      "pcrro7t-x-x-90">#</span><span class=
      "pcrro7t-x-x-90">!/</span><span class=
      "pcrro7t-x-x-90">bin</span><span class=
      "pcrro7t-x-x-90">/</span><span class=
      "pcrro7t-x-x-90">sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47056r2" name=
      "x1-47056r2"></a></span><span class=
      "pcrr7t-x-x-90">set</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">e</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47057r3" name=
      "x1-47057r3"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47058r4" name=
      "x1-47058r4"></a></span><span class=
      "pcrr7t-x-x-90">DEPLOY</span><span class=
      "pcrr7t-x-x-90">=/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">YOU</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47059r5" name=
      "x1-47059r5"></a></span><span class=
      "pcrr7t-x-x-90">SOURCE</span><span class=
      "pcrr7t-x-x-90">=/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">YOU</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">projects</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47060r6" name=
      "x1-47060r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47061r7" name=
      "x1-47061r7"></a></span><span class=
      "pcrb7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">SOURCE</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mp3stream</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47062r8" name=
      "x1-47062r8"></a></span><span class=
      "pcrb7t-x-x-90">nohup</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">u</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">handler</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">2&gt;&amp;1</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mp3stream</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&amp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47063r9" name=
      "x1-47063r9"></a></span><span class=
      "pcrb7t-x-x-90">echo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">!</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">DEPLOY</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mp3stream</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mp3stream</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span>
    </div><!--l. 529-->

    <p class="noindent"><span class=
    "pcrb7t-x-x-90">profiles/web/run</span>________________________________________________<!--l. 531-->

    <div class="lstlisting" id="listing-24">
      <span class="label"><a id="x1-47064r1" name=
      "x1-47064r1"></a></span><span class=
      "pcrro7t-x-x-90">#</span><span class=
      "pcrro7t-x-x-90">!/</span><span class=
      "pcrro7t-x-x-90">bin</span><span class=
      "pcrro7t-x-x-90">/</span><span class=
      "pcrro7t-x-x-90">sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47065r2" name=
      "x1-47065r2"></a></span><span class=
      "pcrr7t-x-x-90">set</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">e</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47066r3" name=
      "x1-47066r3"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47067r4" name=
      "x1-47067r4"></a></span><span class=
      "pcrr7t-x-x-90">DEPLOY</span><span class=
      "pcrr7t-x-x-90">=/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">YOU</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">deployment</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47068r5" name=
      "x1-47068r5"></a></span><span class=
      "pcrr7t-x-x-90">SOURCE</span><span class=
      "pcrr7t-x-x-90">=/</span><span class=
      "pcrr7t-x-x-90">home</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">YOU</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">projects</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47069r6" name=
      "x1-47069r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47070r7" name=
      "x1-47070r7"></a></span><span class=
      "pcrb7t-x-x-90">cd</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">SOURCE</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47071r8" name=
      "x1-47071r8"></a></span><span class=
      "pcrb7t-x-x-90">nohup</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">python</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">u</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">www</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">py</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">2&gt;&amp;1</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">www</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">log</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&amp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-47072r9" name=
      "x1-47072r9"></a></span><span class=
      "pcrb7t-x-x-90">echo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">!</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">$</span><span class=
      "pcrr7t-x-x-90">DEPLOY</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">profiles</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">web</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">web</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">pid</span>
    </div>
  </div>
  <hr class="endfloat">

  <h4 class="subsectionHead"><span class="titlemark">4.5.2</span>
  <a id="x1-480004.5.2" name="x1-480004.5.2"></a>Testing The New
  Setup</h4><!--l. 548-->

  <p class="noindent">Once everything is running and <span class=
  "pcrro7t-">procer</span> is maintaining it, you just need to see
  if things work. Here's some curl commands to try: 
  <!--l. 551-->

  <p class="noindent"><a id="x1-48001r23" name="x1-48001r23"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 23:</span> <span class=
      "content"><span class="pplri7t-">Testing With</span>
      <span class="pplri7t-">Curl</span></span>
    </div><!--tex4ht:label?: x1-48001r23 -->
    <!--l. 552-->

    <div class="lstlisting" id="listing-25">
      <span class="label"><a id="x1-48002r1" name=
      "x1-48002r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">curl</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">http</span><span class=
      "pcrr7t-x-x-90">://</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">:6767/</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-48003r2" name=
      "x1-48003r2"></a></span><span class=
      "pcrr7t-x-x-90">Hello</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">World</span><span class=
      "pcrr7t-x-x-90">!</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-48004r3" name=
      "x1-48004r3"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">curl</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">http</span><span class=
      "pcrr7t-x-x-90">://</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">:6767/</span><span class=
      "pcrr7t-x-x-90">handlertest</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-48005r4" name=
      "x1-48005r4"></a></span><span class=
      "pcrr7t-x-x-90">...</span>
    </div>
  </div>
  <hr class="endfloat">

  <h4 class="subsectionHead"><span class="titlemark">4.5.3</span>
  <a id="x1-490004.5.3" name="x1-490004.5.3"></a>Nice Features of
  Procer</h4><!--l. 563-->

  <p class="noindent">There's some nice subtle features you
  get from using <span class="pcrro7t-">procer</span> to run your
  stuff:

  <dl class="description">
    <dt class="description"><span class="pplb7t-">Faster
    Development</span>

    <dd class="description">A great thing about <span class=
    "pcrro7t-">procer</span> is once you get all of this setup, it
    cuts down on a lot of your setup time and development time
    because it will <span class="pplri7t-">properly</span> restart
    things for you. This means you can simply make changes to code
    or configs, and then just kill the process and procer will kick
    it back over automatically.

    <dt class="description"><span class="pplb7t-">Easy
    Automation</span>

    <dd class="description">You should start to see how you could
    automate creating profiles for new processes since the setup is
    consistent.

    <dt class="description"><span class=
    "pcrb7t-">profiles/run.log</span>

    <dd class="description">All your commands will have their
    output sent to this file so you can see how they might be
    blowing up in your scripts.

    <dt class="description"><span class="pplb7t-">Restart State
    Maintained</span>

    <dd class="description">Since procer is just tracking PID files
    and processes, if you shut it down, it won't kill the
    world. When you start it back up, it just starts new stuff or
    stuff it needs, then goes back to supervising. This means you
    can change the configs for procer then just kick it over and
    it'll do the right thing.
  </dl><!--l. 583-->

  <p class="noindent">The key thing, though, is that you now have
  the whole application for the mongrel2.org demo up and running,
  including automated process management, configuration, and
  managing everything. <!--l. 587-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">4.6</span> <a id=
  "x1-500004.6" name="x1-500004.6"></a>Step 4: Static Content</h3>
  <!--l. 589-->

  <p class="noindent">The final thing we have to do is get the
  static content we need to try out the chat demo: <!--l. 592-->

  <p class="noindent"><a id="x1-50001r24" name="x1-50001r24"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 24:</span> <span class=
      "content"><span class="pplri7t-">Setting Up Static</span>
      <span class="pplri7t-">Content</span></span>
    </div><!--tex4ht:label?: x1-50001r24 -->
    <!--l. 593-->

    <div class="lstlisting" id="listing-26">
      <span class="label"><a id="x1-50002r1" name=
      "x1-50002r1"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">cp</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">~/</span><span class=
      "pcrr7t-x-x-90">projects</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">examples</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chat</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">static</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">static</span><span class=
      "pcrr7t-x-x-90">/</span><span class=
      "pcrr7t-x-x-90">chatdemo</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-50003r2" name=
      "x1-50003r2"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">m2sh</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">stop</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">db</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">config</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sqlite</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">host</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">murder</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-50004r3" name=
      "x1-50004r3"></a></span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">curl</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">I</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">http</span><span class=
      "pcrr7t-x-x-90">://</span><span class=
      "pcrr7t-x-x-90">localhost</span><span class=
      "pcrr7t-x-x-90">:6767/</span><span class=
      "pcrr7t-x-x-90">chatdemo</span><span class=
      "pcrr7t-x-x-90">/</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 600-->

  <p class="noindent">If you get a good response then you should be
  able to go to <a href="http://localhost:6767/chatdemo/" class=
  "url"><span class=
  "pcrr7t-">http://localhost:6767/chatdemo/</span></a> and the chat
  should work. Notice also that you just killed mongrel2 with
  <span class="pcrro7t-">m2sh</span> and it came back because of
  <span class="pcrro7t-">procer</span>. If you do your curl check
  too fast, you might miss it, so just wait a bit.

  <h3 class="sectionHead"><span class="titlemark">4.7</span> <a id=
  "x1-510004.7" name="x1-510004.7"></a>Step 5: Testing And
  Troubleshooting</h3><!--l. 608-->

  <p class="noindent">You should have been testing the
  configuration as you went, but the main things to test are: 
  <!--l. 611-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-51002x1">The /chatdemo/ works and
    you can send messages. Try a few different browsers.

    <li class="enumerate" id="x1-51004x2">You can get a simple
    message from the /handlertest/ and that's about it.

    <li class="enumerate" id="x1-51006x3">See if you can get the
    mp3streamer to stream some mp3s. Put a few in its directory,
    then kill it so <span class="pcrro7t-">procer</span> brings it
    back. Then, point <span class="pcrro7t-">mplayer</span> at
    <a href="http://localhost:6767/mp3stream" class=
    "url"><span class=
    "pcrr7t-">http://localhost:6767/mp3stream</span></a> and it
    should work.

    <li class="enumerate" id="x1-51008x4">Check that you can make
    the proxy go to the web.py app you start in the chat
    demo's directory.

    <li class="enumerate" id="x1-51010x5">See if you can stop
    things and have <span class="pcrro7t-">procer</span> bring them
    back.

    <li class="enumerate" id="x1-51012x6">Stop <span class=
    "pcrro7t-">procer</span> and then start it again to see if it
    properly doesn't step on things.
  </ol><!--l. 626-->

  <p class="noindent">If you run into problems, make sure that you
  can run each little piece and that the files you were supposed to
  make are correct. The best tool to use is <span class=
  "pcrro7t-">diff</span>. <!--l. 630-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">4.8</span> <a id=
  "x1-520004.8" name="x1-520004.8"></a>Further Improvements</h3>
  <!--l. 632-->

  <p class="noindent">That ends this chapter, and at this point you
  should know how to setup nearly everything Mongrel2 has to offer
  right now. You should have a good idea of how <span class=
  "pcrro7t-">procer</span> will work or not for your real
  deployments, and how it's used by me for my own
  deployments. <!--l. 637-->

  <p class="noindent">A <span class="pplri7t-">major</span>
  improvement that we may eventually make is automating setup of
  <span class="pcrro7t-">procer</span> profiles, and just better
  overall management of the profiles with <span class=
  "pcrro7t-">m2sh</span>. If you feel like hacking on that, just go
  ahead and try and let us know. <!--l. 642-->

  <p class="noindent">Other than that, automate, automate,
  automate. <!--l. 644-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">4.9</span> <a id=
  "x1-530004.9" name="x1-530004.9"></a>Deployment Tips</h3>
  <!--l. 646-->

  <p class="noindent">Mongrel2 enforces the correct behavior when
  you run as root, which is to drop priv and chroot. This makes the
  server more secure, and it also simplifies your deployments.
  Since everything you do always runs in a chroot, you now just
  need to rsync that chroot directory, or put it into a git or hg
  repo, and you're set. You're literally forced to make
  your deployments portable to different directories and systems. 
  <!--l. 652-->

  <p class="noindent">As of the 1.0 push for Mongrel2, we
  haven't done much work on how you deploy all the different
  languages. They sort of sprung up during development and our plan
  is to expand that out in the 2.0 version so that deployment is
  very well documented for all the different languages we support.
  That means you'll probably run into some snags and things
  we didn't anticipate. <!--l. 658-->

  <p class="noindent">The following are some general points
  we've come up with while deploying our own apps, with more
  to come as we work on the 2.0 version: <!--l. 661-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-53002x1">Don't run things as
    root if you can. It's bad habit that everyone tries to do
    their sysadmin completely as root, so Mongrel2 is designed to
    be run very easily as under a regular user account. The only
    time you really should be running as root is when you do a
    quick -sudo to m2sh to start <span class=
    "pcrb7t-">mongrel2</span> up so it can chroot.

    <li class="enumerate" id="x1-53004x2">Use the chroot to keep
    your deployment simpler. I literally do all my work locally and
    then just rsync my changes up to my remote staging server.
    Everything has to live in the chroot anyway, and the chroot
    enforces that it is completely self-contained.

    <li class="enumerate" id="x1-53006x3">Use Python's
    virtualenv or anything similar to get yourself a totally local
    environment. Too many systems, such as OSX, have very outdated
    packages and will change versions on you without telling you.
    The best way to make sure your software keeps working (and
    works as one cohesive deployment) is to use a virtualenv inside
    your chroot. It should even work cross-platform if you
    don't have compiled packages in there.

    <li class="enumerate" id="x1-53008x4">Create a user for your
    application and live in there. I don't have any root
    access on my stuff. <span class="pplri7t-">Everything</span> is
    run as a user named after the website, and is deployed right in
    the /home/USER directory. I login as that user, manage as that
    user, and I don't give them sudo access. For the times
    when I need to sudo to restart or run Mongrel2, I then use a
    separate login that I have open (with screen) and do it there.
    This reduces your risk of hacks, but also just simplifies
    things. It's no problem for me to move my configuration
    over to new machines with this setup, or deploy clusters. I
    know that as long as there's the right user on the
    target, I'm set.

    <li class="enumerate" id="x1-53010x5">Use <a href=
    "http://www.gnu.org/software/screen/">GNU screen</a> or die.

    <li class="enumerate" id="x1-53012x6">Keep your config.sqlite
    and the .py file in your chroot, and keep your content and
    everything else under that. This makes sure that the config
    isn't accessible outside your content directories.
    Mongrel2 helps you get this right by not allowing certain Dir
    configurations that would expose your chroot to the world.
  </ol><!--l. 694-->

  <p class="noindent">There's a few additional tips for
  people who want to use alternative process supervision like
  daemontools, runit, or init.d setups. No matter what you use, you
  should probably follow this advice: <!--l. 698-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-53014x1">Whatever you use for
    process management, make sure it can run stuff as <span class=
    "pplri7t-">not</span> root and can do chroot for you. If
    you're running your Mongrel2 as root, you're doing
    it wrong. Actually, if you're running any services as
    root that don't absolutely need to be, you're doing
    it wrong.

    <li class="enumerate" id="x1-53016x2">Mongrel2 is happy to run
    as a regular user, and assumes that if you do not run as root,
    then you probably want to run under daemontools or similar. It
    won't chroot or drop priv and logs to stdout/stderr.

    <li class="enumerate" id="x1-53018x3">If you need to bind to
    port 80 but run under daemontools as a regular user, then use
    <a href=
    "http://manpages.ubuntu.com/manpages/lucid/man1/privbind.1.html">
    privbind</a> to do it. This tool will run any command, like
    <span class="pcrb7t-">mongrel2</span> but it does it in a way
    that lets the executable grab ports below 1024. This
    restriction on ports is actually really stupid so don't
    worry about doing this.

    <li class="enumerate" id="x1-53020x4">Make sure your process
    monitor is not a single point of failure. Some of them out
    there will take your whole world down if they crash. Try doing
    a harsh <span class="pcrro7t-">kill</span> on your process
    manager and see how it behaves. As much as they like to tell
    you not to worry about this because they &rdquo;run
    forever&rdquo;, everything has bugs and stupid people tend to
    kill things they don't get. If taking one process down
    nukes your whole server, then that's a bad design.
  </ol><!--l. 724-->

  <p class="noindent">As we work on the next phase of Mongrel2
  development, this will improve, so watch for news about
  deployment and real applications. <!--l. 1-->

  <p class="noindent">

  <h2 class="chapterHead"><span class=
  "titlemark">Chapter&nbsp;5</span><br>
  <a id="x1-540005" name="x1-540005"></a>Hacking</h2><!--l. 3-->

  <p class="noindent">This chapter is all about making cool things
  with Mongrel2. It covers all the non-deployment features that you
  get from the browser's side and the handler/backend side of
  your application. I'll show you how the chat demo works for
  the async web sockets. I'll get into writing your own
  handlers using a few other demos. I'll cover some of the
  interesting things you can do with Mongrel2 you can't do
  with other servers. Finally, I'll get into practical
  things, when to do proxying and when to use a 0MQ handler. 
  <!--l. 10-->

  <p class="noindent">For the majority of this chapter, I'll
  be using Python, but the demos should translate to the other
  languages that are implemented. I'll periodically show how
  another language does one of the demos, so you can get the idea
  that Mongrel2 is <span class="pplri7t-">language</span>
  <span class="pplri7t-">agnostic</span>. In no way should you take
  me using Python in this chapter to mean you can't use
  something else for your handlers. <!--l. 16-->

  <p class="noindent">Currently supported languages are:

  <dl class="description">
    <dt class="description"><span class="pplb7t-">Python</span>

    <dd class="description">When you installed the <span class=
    "pcrro7t-">m2sh</span> gear, you also got a <span class=
    "pcrro7t-">mongrel2</span> Python library.

    <dt class="description"><span class="pplb7t-">Ruby</span>

    <dd class="description">Probably the most extensively supported
    language, with good Rack support, by <a href=
    "http://github.com/perplexes/m2r">perplexes on github</a>.

    <dt class="description"><span class="pplb7t-">C++</span>

    <dd class="description">C++ support by <a href=
    "http://github.com/akrennmair/mongrel2-cpp">akrennmair on
    github</a>.

    <dt class="description"><span class="pplb7t-">PHP</span>

    <dd class="description">PHP support by <a href=
    "http://github.com/winks/m2php">winks on github</a>.

    <dt class="description"><span class="pplb7t-">C</span>

    <dd class="description">You can also write handlers in C using
    the Mongrel2 library, but it's really rough, and not
    recommended yet. A C library will come, though.

    <dt class="description"><span class="pplb7t-">Others?</span>

    <dd class="description"><a href="http://zeromq.org">ZeroMQ</a>
    supports Ada, Basic, C, C++, Common Lisp, Erlang, Go, Haskell,
    Java, Lua, .NET, Objective-C, ooc, Perl, PHP, Python, and Ruby,
    so after reading this chapter you can easily write handlers in
    any of those languages too.
  </dl><!--l. 27-->

  <p class="noindent">However, no matter how many languages
  Mongrel2 supports, you will still have applications that
  can't fit into 0MQ handlers and just work better as classic
  web apps, either because you've already written them and
  have existing infrastructure, or because of some architectural
  issues that require it to run traditionally. Because of that,
  Mongrel2 supports <span class="pplri7t-">HTTP proxying</span>,
  which allows you to route requests to basic web server backends
  that don't support 0MQ. <!--l. 33-->

  <p class="noindent"><a id="x1-54001r7" name="x1-54001r7"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 7:</span> <span class=
      "content"><span class="pplri7t-">What About</span>
      <span class=
      "pplri7t-">FastCGI/AJP/CGI/SCGI/WSGI/Rack?</span></span>
    </div><!--tex4ht:label?: x1-54001r7 -->

    <div class="quote">
      <!--l. 34-->

      <p class="indent">Nothing prevents you from writing your own
      connector between Mongrel2 and your deployment protocol of
      choice. If you need to run FastCGI or AJP in your
      environment, then your best bet is to just make a handler
      that translates Mongrel2 requests to the protocol you need
      and back. The Mongrel2 format is very easy to parse and
      translate, so you should be able to do it with no problem.
      The Ruby library already supports Rack as an example, and
      Python will support WSGI soon. <!--l. 41-->

      <p class="indent">However, Mongrel2 itself doesn't
      support any of these directly. Doing so would bring back the
      language specific infections that cause other web servers to
      go south. The design of most of these protocols tends to be
      either before the modern web, or specific to one particular
      language. Instead of trying to cater to all the possible
      languages out there, Mongrel2 just gives the tools to connect
      to it yourself.
    </div>
  </div>
  <hr class="endfloat">

  <h3 class="sectionHead"><span class="titlemark">5.1</span> <a id=
  "x1-550005.1" name="x1-550005.1"></a>Front-end Goodies</h3>
  <!--l. 51-->

  <p class="noindent">Mongrel2 supports your standard web server
  features like serving files, routing requests to another HTTP
  server, multiple host matching, good 304 support, and just
  generally being able to interact with a browser like normal.
  You've seen most of these features as you setup and
  deployed a Mongrel2 configuration, but let's go through
  some of them in more detail so you know what's possible. 
  <!--l. 58-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">5.1.1</span>
  <a id="x1-560005.1.1" name="x1-560005.1.1"></a>HTTP</h4>
  <!--l. 60-->

  <p class="noindent">Mongrel2 uses the original Mongrel parser
  that powers quite a few other web servers and large, successful
  websites. This parser is rock solid, dead accurate, and by design
  blocks a lot of security attacks. For the most part you
  don't have to worry about this and just need to know
  Mongrel2 is using the same stable HTTP processing that has been
  working great for many years. <!--l. 65-->

  <p class="noindent">Another way to put this is if Mongrel2 says
  your request is invalid, it most definitely is. <!--l. 67-->

  <p class="noindent"><a id="x1-56001r8" name="x1-56001r8"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 8:</span> <span class=
      "content"><span class="pplri7t-">Idiots and RFC</span>
      <span class="pplri7t-">Implementers</span></span>
    </div><!--tex4ht:label?: x1-56001r8 -->

    <div class="quote">
      <!--l. 68-->

      <p class="indent">I don't know why, but people who
      implement RFCs pick up very weird cargo cult beliefs peddled
      by the people who write the standards. In HTTP it was two
      things which the creators of HTTP have actually back-peddled
      on: Accept everything, and keep-alives with pipe-lines. 
      <!--l. 73-->

      <p class="indent">The truth is, if you want a secure server
      of <span class="pplri7t-">any</span> kind, blindly accepting
      every single thing any idiot sends you is going to open your
      server up to a huge number of attacks. If you look at every
      attack on existing HTTP servers you'll find that about
      80% of them are exploiting ambiguous parts of the HTTP
      grammar to pass through malicious content or overflow
      buffers. In Mongrel2 we use a parser that rejects invalid
      requests from first basic principles using technology
      that's 30 years old and backed by solid mathematics.
      Not only does Mongrel2 reject bad requests, but it can tell
      you <span class="pplri7t-">why</span> the request was bad,
      just like a compiler. This doesn't mean Mongrel2 is
      ruthless, but it definitely doesn't tolerate ambiguity
      or stupidity. <!--l. 84-->

      <p class="indent">Mongrel2 completey supports keep-alives
      because now, since it's not using Ruby <span class=
      "pplri7t-">at all</span> it can scale up beyond 1024 file
      descriptors. Ruby was limited in the number of open files a
      process could have, so the original Mongrel had to break
      keep-alive and kill connections in order to save itself from
      greedy browsers that never close them. Mongrel2 doesn't
      have this limitation, so it uses full keep-alives and has a
      dead accurate state machine to manage them correctly. 
      <!--l. 91-->

      <p class="indent">Where problems come in is with pipe-lined
      requests, meaning a browser sends a bunch of requests in a
      big blast, then hangs out for all the responses. This was
      such a horrible stupid idea that pretty much everone gets it
      wrong and doesn't support it fully, if at all. The
      reason is it's much too easy to blast a server with a
      ton of request, wait a bit so they hit proxied backends, and
      then close the socket. The web server and the backends are
      now screwed having to handle these requests which will go
      nowhere. <!--l. 99-->

      <p class="indent">Mongrel2 does <span class=
      "pplri7t-">not</span> support pipe-lined requests. It sends
      one, and waits for the reponse, and if you want more, then
      tough. Screw you because it has <span class=
      "pplri7t-">no</span> advantage for Mongrel2 and dubious
      advantages to you. It is simply one more attack vector for
      the server and is rejected outright. <!--l. 104-->

      <p class="indent">These two things are rejected outright by
      Mongrel2 simply because they are stupid ideas and in 2010
      nobody should be writing clients so badly that they need
      these features.
    </div>
  </div>
  <hr class="endfloat">

  <h4 class="subsectionHead"><span class="titlemark">5.1.2</span>
  <a id="x1-570005.1.2" name="x1-570005.1.2"></a>Proxying</h4>
  <!--l. 110-->

  <p class="noindent">You've already seen configurations that
  have the Proxy routes working, so it should be easy to understand
  what's going on. You just create routes to backends that
  are HTTP servers and Mongrel2 shuttles requests to them, then
  proxies responses back. <!--l. 114-->

  <p class="noindent">The Proxying support in Mongrel2 is accurate,
  but it's not very capable right now. For example,
  there's not round-robin backend selection, or page caching,
  or other things you might need for more serious deployments.
  Those features will come eventually, though. <!--l. 118-->

  <p class="noindent">What you do get with Mongrel2's
  proxying, though, is a dead accurate way of slicing up your
  application by routes. Other web servers make you go through
  great pain in order to have some URLs go to a proxy and others go
  to handlers or directories. They make you use odd &ldquo;file
  syntax&rdquo;, weird pseudo-turing logic if-statements, and other
  odd hacks to get flexible route selection. They also tend to not
  maintain keep-alives properly between proxy requests and other
  requests. <!--l. 125-->

  <p class="noindent">Mongrel2 uses the exact same routing syntax
  for all backends and has no distinction between them. It also
  properly does keep-alives for as long as it is efficient to do
  so. <!--l. 128-->

  <p class="noindent"><a id="x1-57001r9" name="x1-57001r9"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 9:</span> <span class=
      "content"><span class="pplri7t-">Proxying And 0MQ Handlers
      Are Like</span> <span class="pplri7t-">mod</span><span class=
      "pplri7t-">_*</span></span>
    </div><!--tex4ht:label?: x1-57001r9 -->

    <div class="quote">
      <!--l. 129-->

      <p class="indent">A quick note for people coming from other
      web servers. If you use nginx then you are probably familiar
      with the concept of proxying to a &rdquo;backend&rdquo; like
      Ruby on Rails or Django. If you use PHP or another language,
      you may be used to a system like <span class=
      "pcrro7t-">mod</span><span class="pcrro7t-">_php</span> which
      manages your code for you and reloads when you make changes.
      If you use Apache, then you probably think in terms of
      &rdquo;virtual hosts&rdquo; and &rdquo;mod_rewrite
      rules&rdquo;. <!--l. 135-->

      <p class="indent">In Mongrel2 all the same concepts are
      there, it's just cleaned up. If you want Mongrel2 to
      &rdquo;nginx/mod_rewrite style&rdquo; talk to another backend
      web server, then that's Proxying. If you want to have
      fast backend handlers then that's 0MQ Handlers. 
      <!--l. 139-->

      <p class="indent">We really don't have anything like
      mod_php because the whole idea of embedding a programming
      language runtime inside Mongrel2 would defeat the point of
      making it language agnostic.
    </div>
  </div>
  <hr class="endfloat">

  <h4 class="subsectionHead"><span class="titlemark">5.1.3</span>
  <a id="x1-580005.1.3" name="x1-580005.1.3"></a>WebSockets</h4>
  <!--l. 145-->

  <p class="noindent">Mongrel2 supports WebSockets, in that if
  someone connects with a WebSocket, then it will get sent to
  handlers that use 0MQ and they can interact with it like every
  other request. WebSockets are the least supported, though, since
  they aren't fully baked and nobody's bothered to
  write helper gear for handlers. They work, in theory, but
  haven't really been tried in practice. <!--l. 150-->

  <p class="noindent">If you try them out and find things that need
  fixing, let us know. <!--l. 152-->

  <p class="noindent"><a id="x1-58001r10" name="x1-58001r10"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 10:</span> <span class=
      "content"><span class="pplri7t-">Death To</span> <span class=
      "pplri7t-">WebSockets</span></span>
    </div><!--tex4ht:label?: x1-58001r10 -->

    <div class="quote">
      <!--l. 153-->

      <p class="indent">I am getting sick of these &ldquo;Backroom
      RFCs&rdquo; that are crafted around a bunch of huge
      companies' crap implementations found in their existing
      products rather than things real programmers need. WebSockets
      is yet another example of this, with so many odd features and
      annoying agendas that I hope it fails miserably. 
      <!--l. 158-->

      <p class="indent">First, it actually specifies <span class=
      "pplri7t-">Unicode</span> for the wire protocol in the HTTP
      headers. This is such a monumental bad idea and will break so
      many web servers and browsers that I'm baffled how it
      got into the standard. The only thing I can think of is some
      &ldquo;reverse colonialist&rdquo; who thinks the world should
      a happy rainbow of Unicode demanded it be in there. Unicode
      in the wire protocol adds no linguistic value (nobody reads
      headers), complicates servers, adds security concerns because
      Unicode is ambiguous, and also violates the existing HTTP
      standard which specifies ASCII for the wire protocol. As
      I've said before in this manual, writing protocols is
      hard enough without having to translate and deal with weird
      UTF-8 Unicode bizarreness. <!--l. 167-->

      <p class="indent">Second, there is an idiotic
      &ldquo;encryption&rdquo; mechanism for a key exchange that
      can only be described as completely damaged and amateurish.
      The scheme involves taking a regular number and then mixing
      in non-number characters, so <span class=
      "obeylines-h verb pcrr7t-">1234</span> becomes <span class=
      "obeylines-h verb pcrr7t-">1@%^2&#8902;(34</span> and then is
      &ldquo;decrypted&rdquo; by just reading only the digits. Yes,
      this encryption is so advanced you can do it in your head
      visually. I'm sorry, but any obfuscation that can be
      done by an 11 year old on paper is not encryption and should
      not be used at all. Again, this smacks of some
      &ldquo;clever&rdquo; feature one of the many corporations out
      there invented and not something any real programmer needs. 
      <!--l. 175-->

      <p class="indent">There's more, but these two alone are
      enough to decide to hold off on WebSockets until they get
      their head straight and specify something that mere mortals
      can hope to implement.
    </div>
  </div>
  <hr class="endfloat">

  <h4 class="subsectionHead"><span class="titlemark">5.1.4</span>
  <a id="x1-590005.1.4" name="x1-590005.1.4"></a>JSSocket</h4>
  <!--l. 181-->

  <p class="noindent">The Mongrel2 chat demo uses JSSocket to do
  its magic, and it works great, but it requires Flash and, oh,
  man, do I absolutely hate Flash. However, it works, and works
  now, and works in every browser, even really old, busted ones.
  That means it's the first thing we implemented and the one
  we'll keep for a while until it proves itself not useful.
  The chat demo we'll cover will show you how to hook this up
  for fast async messaging and presence detection. <!--l. 188-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">5.1.5</span>
  <a id="x1-600005.1.5" name="x1-600005.1.5"></a>Long Poll</h4>
  <!--l. 190-->

  <p class="noindent">Mongrel2 just works as if everything is an
  HTTP long poll, it's just that normal request/responses are
  super fast long polls. For the most part you don't even
  need to know this exists; it's just how things are and they
  make perfect sense. You get requests from a certain server with a
  certain connected identity, and then you send stuff to that
  target. That's it. If you send it one response, or a stream
  of them, or setup a long poll configuration, then that's up
  to you. <!--l. 197-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">5.1.6</span>
  <a id="x1-610005.1.6" name="x1-610005.1.6"></a>Streaming</h4>
  <!--l. 199-->

  <p class="noindent">Because everything in Mongrel2 is
  asynchronous, and it allows you to target any connected listeners
  from your handlers, even with partial messages, you can easily do
  efficient streaming applications. ZeroMQ is an incredibly
  efficient transport mechanism, and with it you can send tons of
  information to many browsers or clients at once. This means
  streaming video and MP3 streams to listeners is very trivial.
  We'll cover the mp3stream example where you get to see a
  simple implementation of the ICY MP3 streaming protocol. 
  <!--l. 206-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">5.1.7</span>
  <a id="x1-620005.1.7" name="x1-620005.1.7"></a>N:M Responses</h4>
  <!--l. 208-->

  <p class="noindent">What makes streaming, async messaging, and
  long poll designs so efficient in Mongrel2 is that you can send
  <span class="pplri7t-">one</span> message and target up to 128
  clients with that one message. This means sending large scale
  replies to many browsers requires less copying of the message and
  less transports. <!--l. 212-->

  <p class="noindent">In addition to this, you can setup Mongrel2
  with the help of some 0MQ to send one request from a browser to
  as many target handlers as you like. You can even send them
  messages using <a href=
  "http://code.google.com/p/openpgm/">OpenPGM</a> for sending UDP
  messages reliably to clusters of computers. <!--l. 217-->

  <p class="noindent">This means that Mongrel2 is the only web
  server capable of sending one request from a browser to N
  backends at once, and then return the replies from these handlers
  to M browsers. Not exactly sure what you could write with that,
  but it's probably something really damn cool. <!--l. 222-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">5.1.8</span>
  <a id="x1-630005.1.8" name="x1-630005.1.8"></a>Async Uploads</h4>
  <!--l. 224-->

  <p class="noindent">Mongrel2 also solves the problem of large
  uploads choking your server because you can't stop them
  before they're complete. Mongrel2 will stream large
  requests to temporary files, but it sends your handlers an
  initial &ldquo;upload started&rdquo; message. When the upload is
  done, you get a final &ldquo;upload finished&rdquo; message. If,
  at any time, you want to kill the upload, you just send a
  0-length reply (the official KILL MESSAGE) and the whole thing is
  aborted and cleaned up. <!--l. 233-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">5.2</span> <a id=
  "x1-640005.2" name="x1-640005.2"></a>Introduction to ZeroMQ</h3>
  <!--l. 235-->

  <p class="noindent">Learning to use <a href=
  "http://zeromq.org">ZeroMQ</a> is a bit outside the scope of this
  book, but I'll give you a quick introduction to it so that
  you can explore it further. It is a very simple system, so
  hopefully you can figure it out from here. <!--l. 239-->

  <p class="noindent">What ZeroMQ ends up being is &ldquo;sockets
  the way programmers think sockets work&rdquo;. Programmers
  usually hear about TCP or UDP sockets and they think in a
  na&iuml;ve way that they work like this:

  <dl class="description">
    <dt class="description"><span class="pplb7t-">TCP</span>

    <dd class="description">Programmers think these are streamed
    sequential messages, so if they send a &ldquo;message&rdquo;
    that's 10k long then when the receiver gets it and read
    from the TCP socket they get a single 10k message in reply.
    This only works in small messages and not on the Internet, so
    it's easy to see how it would seem to work that way. The
    reality is that you can get messages of any size, and without
    some framing mechanism you wouldn't know where one
    messages ends or beings. TCP is a <span class=
    "pplri7t-">streaming protocol</span>.

    <dt class="description"><span class="pplb7t-">UDP</span>

    <dd class="description">Programmers think UDP sockets are
    single, fast, <span class="pplri7t-">reliable</span> messages
    that can be sent to one or more target clients. They at least
    know UDP has a fixed upper bound size, but they don't get
    that UDP is very unreliable and that the addressing is fairly
    weak.
  </dl><!--l. 258-->

  <p class="noindent">What ZeroMQ does is create an API that looks
  a lot like sockets, and feels the same, but gives you the
  messaging styles you actually want. By simply specifying the type
  of socket when you call <a href=
  "http://api.zeromq.org/zmq_socket.html">zmq_socket</a> you can
  have multicast, request/reply, and many other styles.
  Here's the list of ones currently implemented (as
  documented in <span class="pcrro7t-">man zmq</span><span class=
  "pcrro7t-">_socket</span>):

  <dl class="description">
    <dt class="description"><span class=
    "pcrb7t-">ZMQ</span><span class=
    "pcrb7t-">_REQ</span><span class="pplb7t-">/</span><span class=
    "pcrb7t-">ZMQ</span><span class="pcrb7t-">_REP</span>

    <dd class="description">Your classic, strict, REQuest/REPly
    sockets, that work much like HTTP request/response semantics.
    These are more strict and lock-step, but are slower because of
    the extra overhead in keeping the state organized.

    <dt class="description"><span class=
    "pcrb7t-">ZMQ</span><span class=
    "pcrb7t-">_PUB</span><span class="pplb7t-">/</span><span class=
    "pcrb7t-">ZMQ</span><span class="pcrb7t-">_SUB</span>

    <dd class="description">These are PUBlish/SUBscribe sockets and
    work as a decentralized asynchronous messaging. PUB sockets
    just send out messages to multiple subscribers, without
    expecting a reply. SUB sockets just read messages that are sent
    to them, and can subscribe to prefixes on the messages.

    <dt class="description"><span class=
    "pcrb7t-">ZMQ</span><span class=
    "pcrb7t-">_PUSH</span><span class=
    "pplb7t-">/</span><span class="pcrb7t-">ZMQ</span><span class=
    "pcrb7t-">_PULL</span>

    <dd class="description">PUSH/PULL sockets are more like
    asynchronous round-robin sockets. They work like PUB/SUB, but
    instead of the message going to all subscribers that are
    subscribed or not, a PUSH/PULL socket will have a message go to
    just one of the receivers in a cluster. This is a lot like
    having a round-robin proxy configuration in your web server.

    <dt class="description"><span class=
    "pcrb7t-">ZMQ</span><span class="pcrb7t-">_PAIR</span>

    <dd class="description">A PAIR is just a direct connection
    between two peers, basically like a better TCP connection.
  </dl><!--l. 281-->

  <p class="noindent">The next thing ZeroMQ does is it separates
  these types of <span class="pplri7t-">messaging</span> from the
  underlying transport protocol and gives you a simple URL-like
  syntax for specifying that: <span class=
  "pcrro7t-">tcp://127.0.0.1:9999/</span> for example. The types of
  transports that you can use when you call <a href=
  "http://api.zeromq.org/zmq_bind.html">zmq_bind</a> and <a href=
  "http://api.zeromq.org/zmq_connect.html">zmq_connect</a> are:

  <dl class="description">
    <dt class="description"><span class="pcrb7t-">tcp://</span>

    <dd class="description">This is a plain old TCP socket with a
    host and portnumber.

    <dt class="description"><span class="pcrb7t-">ipc://</span>

    <dd class="description">This uses Unix inter-process
    communication like domain sockets, mq, or whatever is
    available.

    <dt class="description"><span class="pcrb7t-">pgm://</span>

    <dd class="description">Reliable multicast messaging that uses
    raw IP layering and requires special privileges.

    <dt class="description"><span class="pcrb7t-">epgm://</span>

    <dd class="description">The &ldquo;encapsulated&rdquo; version
    that uses regular UDP to do reliable multicast messaging.
  </dl><!--l. 293-->

  <p class="noindent">Finally, ZeroMQ divorces who binds and
  connects from the above two configurations. This means that,
  unlike classic sockets, who connects and who binds doesn't
  matter for the direction or kind of message. All that really
  matters is whether the connection makes sense for your
  application. For example, in Mongrel2 the server does a bind on
  the handler ports so that handlers can connect at will, which
  gives your handlers a nice &ldquo;zero config&rdquo; setup.
  Mongrel2 doesn't need to know about handlers; they just
  need to know about Mongrel2. <!--l. 302-->

  <p class="noindent">How this last part works, and why it works,
  is that when clients or servers connect or disconnect, ZeroMQ
  <span class="pplri7t-">doesn't blow up</span>. In TCP, if I
  have a server, and then 10 clients connect, when one of them
  disconnects in the middle of a message I lose the message and get
  an error. With ZeroMQ, clients connecting to a socket don't
  trigger an event, and disconnecting doesn't do anything
  other than hold or drop messages. This is why you don't
  have to care about who binds or connects, because it's just
  an addressing mechanism, not a <span class="pplri7t-">state
  management</span> mechanism. <!--l. 311-->

  <p class="noindent">Another way to put this feature is
  there's no <span class="pplri7t-">accept</span> in ZeroMQ.
  Clients connect and go at will and the server is just reading
  messages off when they're available or sending them out for
  clients. <!--l. 316-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">5.2.1</span>
  <a id="x1-650005.2.1" name="x1-650005.2.1"></a>A Quick Python
  ZeroMQ Example</h4><!--l. 318-->

  <p class="noindent">I've written a simple abstraction over
  ZeroMQ that fits the Mongrel2 usage of it, but I think learning
  how you'd write your own ZeroMQ simple echo server in
  Python will help you get a handle on it. First the client then
  the server: <!--l. 322-->

  <p class="noindent"><a id="x1-65001r25" name="x1-65001r25"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 25:</span> <span class=
      "content"><span class="pplri7t-">Simple Python ZeroMQ</span>
      <span class="pplri7t-">Client</span></span>
    </div><!--tex4ht:label?: x1-65001r25 -->
    <!--l. 323-->

    <div class="lstlisting" id="listing-27">
      <span class="label"><a id="x1-65002r1" name=
      "x1-65002r1"></a></span><span class=
      "pcrr7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65003r2" name=
      "x1-65003r2"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65004r3" name=
      "x1-65004r3"></a></span><span class=
      "pcrr7t-x-x-90">ctx</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">Context</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65005r4" name=
      "x1-65005r4"></a></span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ctx</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">socket</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">SUB</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65006r5" name=
      "x1-65006r5"></a></span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">connect</span><span class=
      "pcrr7t-x-x-90">("</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:5566")</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65007r6" name=
      "x1-65007r6"></a></span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">setsockopt</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">SUBSCRIBE</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">''</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65008r7" name=
      "x1-65008r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65009r8" name=
      "x1-65009r8"></a></span><span class=
      "pcrr7t-x-x-90">msg</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">recv</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65010r9" name=
      "x1-65010r9"></a></span><span class=
      "pcrr7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">MSG</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">",</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">repr</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">msg</span><span class=
      "pcrr7t-x-x-90">)</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 337-->

  <p class="noindent"><a id="x1-65011r26" name="x1-65011r26"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 26:</span> <span class=
      "content"><span class="pplri7t-">Simple Python ZeroMQ</span>
      <span class="pplri7t-">Server</span></span>
    </div><!--tex4ht:label?: x1-65011r26 -->
    <!--l. 338-->

    <div class="lstlisting" id="listing-28">
      <span class="label"><a id="x1-65012r1" name=
      "x1-65012r1"></a></span><span class=
      "pcrr7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65013r2" name=
      "x1-65013r2"></a></span><span class=
      "pcrr7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">time</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65014r3" name=
      "x1-65014r3"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65015r4" name=
      "x1-65015r4"></a></span><span class=
      "pcrr7t-x-x-90">ctx</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">Context</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65016r5" name=
      "x1-65016r5"></a></span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ctx</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">socket</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">PUB</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65017r6" name=
      "x1-65017r6"></a></span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">bind</span><span class=
      "pcrr7t-x-x-90">("</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:5566")</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65018r7" name=
      "x1-65018r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65019r8" name=
      "x1-65019r8"></a></span><span class=
      "pcrr7t-x-x-90">while</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">True</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65020r9" name=
      "x1-65020r9"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">send</span><span class=
      "pcrr7t-x-x-90">("</span><span class=
      "pcrr7t-x-x-90">HELLO</span><span class=
      "pcrr7t-x-x-90">")</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65021r10" name=
      "x1-65021r10"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">time</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sleep</span><span class=
      "pcrr7t-x-x-90">(1)</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 353-->

  <p class="noindent">You can then run these two in different
  windows and they will talk to each other. Try playing around with
  different socket types and transports to see what they do. Notice
  that for a PUB/SUB setup we have to use <span class=
  "pcrro7t-">setsockopt</span> to subscribe the nothing
  (<span class="obeylines-h verb pcrr7t-">''</span>). This is the
  same no matter what language you use. <!--l. 359-->

  <p class="noindent">Here's an example that does the same
  thing but with REQ/REP style of messages. <!--l. 361-->

  <p class="noindent"><a id="x1-65022r27" name="x1-65022r27"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 27:</span> <span class=
      "content"><span class="pplri7t-">ZeroMQ REQ/REP</span>
      <span class="pplri7t-">Client</span></span>
    </div><!--tex4ht:label?: x1-65022r27 -->
    <!--l. 362-->

    <div class="lstlisting" id="listing-29">
      <span class="label"><a id="x1-65023r1" name=
      "x1-65023r1"></a></span><span class=
      "pcrr7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65024r2" name=
      "x1-65024r2"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65025r3" name=
      "x1-65025r3"></a></span><span class=
      "pcrr7t-x-x-90">ctx</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">Context</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65026r4" name=
      "x1-65026r4"></a></span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ctx</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">socket</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">REQ</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65027r5" name=
      "x1-65027r5"></a></span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">connect</span><span class=
      "pcrr7t-x-x-90">("</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:5566")</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65028r6" name=
      "x1-65028r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65029r7" name=
      "x1-65029r7"></a></span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">send</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">HI</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">FROM</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">CLIENT</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65030r8" name=
      "x1-65030r8"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65031r9" name=
      "x1-65031r9"></a></span><span class=
      "pcrr7t-x-x-90">msg</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">recv</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65032r10" name=
      "x1-65032r10"></a></span><span class=
      "pcrr7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">MSG</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">",</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">repr</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">msg</span><span class=
      "pcrr7t-x-x-90">)</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 377-->

  <p class="noindent"><a id="x1-65033r28" name="x1-65033r28"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 28:</span> <span class=
      "content"><span class="pplri7t-">ZeroMQ REQ/REP</span>
      <span class="pplri7t-">Server</span></span>
    </div><!--tex4ht:label?: x1-65033r28 -->
    <!--l. 378-->

    <div class="lstlisting" id="listing-30">
      <span class="label"><a id="x1-65034r1" name=
      "x1-65034r1"></a></span><span class=
      "pcrr7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65035r2" name=
      "x1-65035r2"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65036r3" name=
      "x1-65036r3"></a></span><span class=
      "pcrr7t-x-x-90">ctx</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">Context</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65037r4" name=
      "x1-65037r4"></a></span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ctx</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">socket</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">zmq</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">REP</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65038r5" name=
      "x1-65038r5"></a></span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">bind</span><span class=
      "pcrr7t-x-x-90">("</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:5566")</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65039r6" name=
      "x1-65039r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65040r7" name=
      "x1-65040r7"></a></span><span class=
      "pcrr7t-x-x-90">while</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">True</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65041r8" name=
      "x1-65041r8"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">GOT</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">BACK</span><span class=
      "pcrr7t-x-x-90">",</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">repr</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">recv</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-65042r9" name=
      "x1-65042r9"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">send</span><span class=
      "pcrr7t-x-x-90">("</span><span class=
      "pcrr7t-x-x-90">HELLO</span><span class=
      "pcrr7t-x-x-90">")</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 391-->

  <p class="noindent">As you can see when you run this, it's
  more like your classic web server style of messaging, where a
  client requests something with an initial message, and the server
  replies. Try getting the order wrong and see how ZeroMQ aborts
  and tells you it's wrong. REQ sockets <span class=
  "pplri7t-">must</span> send first then recv, and REP sockets
  <span class="pplri7t-">must</span> recv then send. <!--l. 396-->

  <p class="noindent"><a id="x1-65043r11" name="x1-65043r11"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 11:</span> <span class=
      "content"><span class="pplri7t-">There's Always a Size
      in ZeroMQ</span> <span class="pplri7t-">Land</span></span>
    </div><!--tex4ht:label?: x1-65043r11 -->

    <div class="quote">
      <!--l. 397-->

      <p class="indent">The lack of a reliable framing mechanism in
      TCP was a crime against humanity. What I mean by a
      &ldquo;frame&rdquo; is a simple indicator that a message in a
      stream has a certain length. If you preface each message in
      TCP with the length of the data you're about to send
      then you avoid all manner of annoyance, attacks, and bugs.
      Something as simple as a single byte that says you're
      sending up to 128 more bytes, with an extra bit to indicate
      the last byte would have saved the world much pain. 
      <!--l. 404-->

      <p class="indent">This is basically what ZeroMQ has done, and
      so much more. ZeroMQ pulls out all the tricks to make sure
      that the message you receive is totally cooked, fully sized,
      and transports it faster than TCP can actually send it. It
      does this by framing things intelligently, using compression,
      reducing copying, and just generally being awesome. 
      <!--l. 409-->

      <p class="indent">Of course, the only limitation is that it
      can't really <span class="pplri7t-">stream</span>
      things. But then again, nobody really does true streaming.
      They always end up having to bolt on some framing of some
      kind.
    </div>
  </div>
  <hr class="endfloat">

  <h3 class="sectionHead"><span class="titlemark">5.3</span> <a id=
  "x1-660005.3" name="x1-660005.3"></a>Handler ZeroMQ Format</h3>
  <!--l. 416-->

  <p class="noindent">You've had the world's fastest
  crash course in <a href="http://zeromq.org">ZeroMQ</a> and now
  you're ready to see how Mongrel2 talks to your handlers
  with it. I won't really call this a &ldquo;protocol&rdquo;,
  since ZeroMQ is really doing the protocol, and we just pull fully
  baked messages out of it. Instead, this is just a format, as if
  you got strings out of a file or something similar. This message
  format is designed to accomplish a few things in the simplest way
  possible: <!--l. 422-->

  <p class="noindent">

  <ol class="enumerate1">
    <li class="enumerate" id="x1-66002x1">Be usable from languages
    that are statically compiled or scripting languages.

    <li class="enumerate" id="x1-66004x2">Be safe from buffer
    overflows if done right, or easy to do right.

    <li class="enumerate" id="x1-66006x3">Be easy to understand and
    require very little code.

    <li class="enumerate" id="x1-66008x4">Be language agnostic and
    use a data format everyone can accept without complaining that
    it should be done with their favorite<span class=
    "footnote-mark"><a href="book-final6.html#fn1x7"><sup class=
    "textsuperscript">1</sup></a></span><a id="x1-66009f1" name=
    "x1-66009f1"></a> .

    <li class="enumerate" id="x1-66011x5">Be easy to parse and
    generate inside Mongrel2 <span class="pplri7t-">without</span>
    have to parse the entire message to do routing or analysis.

    <li class="enumerate" id="x1-66013x6">Be useful within ZeroMQ
    so that you can do subscriptions and routing.
  </ol><!--l. 434-->

  <p class="noindent">To satisfy these features we use haveo types
  of ZeroMQ sockets (soon to be configurable), a request format
  that Mongrel2 sends and a response format that the handlers send
  back. Most importantly, there is <span class="pplri7t-">nothing
  about the request and response</span> <span class="pplri7t-">that
  must be connected</span>. In most cases they will be connected,
  but you can receive a request from one browser and send a
  response to a totally different one. <!--l. 440-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">5.3.1</span>
  <a id="x1-670005.3.1" name="x1-670005.3.1"></a>Socket Types
  Used</h4><!--l. 442-->

  <p class="noindent">First, the types of ZeroMQ sockets used are a
  <span class="pcrro7t-">ZMQ</span><span class=
  "pcrro7t-">_PUSH</span> socket for messages from Mongrel2 to
  Handlers, which means your Handler's receive socket should
  be a <span class="pcrro7t-">ZMQ</span><span class=
  "pcrro7t-">_PULL</span>. Mongrel2 then uses a <span class=
  "pcrro7t-">ZMQ</span><span class="pcrro7t-">_SUB</span> socket
  for receiving responses, which means your Handlers should send on
  a <span class="pcrro7t-">ZMQ</span><span class=
  "pcrro7t-">_PUB</span> socket. This setup allows multiple
  handlers to connect to a Mongrel2 server, but only one Handler
  will get a message in a round-robin style. The PUB/SUB reply
  sockets, though, will let Handlers send back replies to a cluster
  of Mongrel2 servers, but only the one with the right subscription
  will process the request.<span class="footnote-mark"><a href=
  "book-final7.html#fn2x7"><sup class=
  "textsuperscript">2</sup></a></span><a id="x1-67001f2" name=
  "x1-67001f2"></a> <!--l. 454-->

  <p class="noindent">In the various APIs we've implemented,
  you don't need to care about this. They provide an
  abstraction on top of this, but it does help to know it so that
  you understand why the message format is the way it is. 
  <!--l. 458-->

  <p class="noindent">This leads to rule number 1:

  <div class="quote">
    <!--l. 461-->

    <p class="noindent"><span class="pplri7t-">Rule 1:</span>
    Handlers receive on with PULL and send with PUB sockets.
  </div>

  <h4 class="subsectionHead"><span class="titlemark">5.3.2</span>
  <a id="x1-680005.3.2" name="x1-680005.3.2"></a>UUID
  Addressing</h4><!--l. 466-->

  <p class="noindent">Do you remember all those UUIDs all over the
  place in the configuration files? They may have seemed odd, but
  they identify specific server deployments and processes in a
  cluster. This will let you identify exactly which member of a
  cluster sent a message, so that you can return the right reply.
  This is the first part of our protocol format and it results in
  the next rule 2: <!--l. 472-->

  <p class="noindent">

  <div class="quote">
    <!--l. 473-->

    <p class="noindent"><span class="pplri7t-">Rule 2:</span> Every
    message to and from Mongrel2 has that Mongrel2 instance's
    UUID as the very first thing.
  </div><!--l. 477-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">5.3.3</span>
  <a id="x1-690005.3.3" name="x1-690005.3.3"></a>Numbers Identify
  Listeners</h4><!--l. 479-->

  <p class="noindent">You then need a way to identify a particular
  listener (browser, client, etc.) that your message should target,
  <span class="pplri7t-">and</span> Mongrel2 needs to tell you who
  is sending your handler the request. This means Mongrel2 sends
  you is just one identifier, but you can send Mongrel2 a list of
  them. This leads to rule 3: <!--l. 484-->

  <p class="noindent">

  <div class="quote">
    <!--l. 485-->

    <p class="noindent"><span class="pplri7t-">Rule 3:</span>
    Mongrel2 sends requests with one number right after the
    server's UUID separated by a space. Handlers return a
    <span class="pplri7t-">netstring</span> with a list of numbers
    separated by spaces. The numbers indicate the connected browser
    the message is to/from.
  </div><!--l. 491-->

  <p class="noindent">In case you don't know what a netstring
  is, it is a very simple way to encode a block of data such that
  any language can read the block and know how big it is. A
  netstring is, simply, <span class=
  "obeylines-h verb pcrr7t-">SIZE:DATA,</span>. So, to send
  &ldquo;HI&rdquo;, you would do <span class=
  "obeylines-h verb pcrr7t-">2:HI,</span>, and it is <span class=
  "pplri7t-">incredibly</span> easy to parse in every language,
  even C. It is also a fast format and you can read it even if
  you're a human. <!--l. 498-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">5.3.4</span>
  <a id="x1-700005.3.4" name="x1-700005.3.4"></a>Paths Identify
  Targets</h4><!--l. 500-->

  <p class="noindent">In order to make it possible to route or
  analyze a request in your handlers without having to parse a full
  request, every request has the path that was matched in the
  server as the next piece. That gives us: <!--l. 504-->

  <p class="noindent">

  <div class="quote">
    <!--l. 505-->

    <p class="noindent"><span class="pplri7t-">Rule 4:</span>
    Requests have the path as a single string followed by a space
    and <span class="pplri7t-">no paths may have spaces in
    them</span>.
  </div><!--l. 510-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">5.3.5</span>
  <a id="x1-710005.3.5" name="x1-710005.3.5"></a>Request Headers
  And Body</h4><!--l. 512-->

  <p class="noindent">We only have two more rules to complete the
  message format. <!--l. 514-->

  <p class="noindent">

  <div class="quote">
    <!--l. 515-->

    <p class="noindent"><span class="pplri7t-">Rule 5:</span>
    Mongrel2 sends requests with a <span class=
    "pcrro7t-">netstring</span> that contains a JSON hash (dict) of
    the request headers, and then another <span class=
    "pcrro7t-">netstring</span> with the body of the request.
  </div><!--l. 520-->

  <p class="noindent">Then there's a similar rule for
  responses: <!--l. 522-->

  <p class="noindent">

  <div class="quote">
    <!--l. 523-->

    <p class="noindent"><span class="pplri7t-">Rule 6:</span>
    Handlers return just the body after a space character. It can
    be <span class="pplri7t-">any</span> data that Mongel2 is
    supposed to send to the listeners.
  </div><!--l. 527-->

  <p class="noindent">HTTP headers, image data, HTML pages,
  streaming video&hellip;You can also send as many as you like to
  complete the request and any handler can send it. <!--l. 531-->

  <p class="noindent">

  <h4 class="subsectionHead"><span class="titlemark">5.3.6</span>
  <a id="x1-720005.3.6" name="x1-720005.3.6"></a>Complete Message
  Examples</h4><!--l. 533-->

  <p class="noindent">Now, even though we laid out all of this as a
  series of rules, the actual code to implement these is very
  simple. First here's a simple &ldquo;grammar&rdquo; for how
  a request that gets sent to your handlers is formatted: 
  <!--l. 537-->

  <div class="lstlisting" id="listing-31">
    <span class="label"><a id="x1-72001r1" name=
    "x1-72001r1"></a></span><span class=
    "pcrr7t-">UUID</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">ID</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">PATH</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">SIZE</span><span class="pcrr7t-">:</span><span class=
    "pcrr7t-">HEADERS</span><span class=
    "pcrr7t-">,</span><span class="pcrr7t-">SIZE</span><span class=
    "pcrr7t-">:</span><span class="pcrr7t-">BODY</span><span class=
    "pcrr7t-">,</span>
  </div><!--l. 541-->

  <p class="noindent">That's obviously a much simpler way to
  specify the request than all those rules, but it also
  doesn't tell you why. The above description, while boring
  as hell, tells you why each of these pieces exist. <!--l. 545-->

  <p class="noindent">To parse this in Python we simply do this: 
  <!--l. 547-->

  <p class="noindent"><a id="x1-72002r29" name="x1-72002r29"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 29:</span> <span class=
      "content"><span class="pplri7t-">Parsing Mongrel2 Requests
      In</span> <span class="pplri7t-">Python</span></span>
    </div><!--tex4ht:label?: x1-72002r29 -->
    <!--l. 548-->

    <div class="lstlisting" id="listing-32">
      <span class="label"><a id="x1-72003r1" name=
      "x1-72003r1"></a></span><span class=
      "pcrr7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">json</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72004r2" name=
      "x1-72004r2"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72005r3" name=
      "x1-72005r3"></a></span><span class=
      "pcrr7t-x-x-90">def</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">parse_netstring</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">ns</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72006r4" name=
      "x1-72006r4"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">len</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">rest</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ns</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">split</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">1)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72007r5" name=
      "x1-72007r5"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">len</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">int</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">len</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72008r6" name=
      "x1-72008r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">assert</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">rest</span><span class=
      "pcrr7t-x-x-90">&#91;</span><span class=
      "pcrr7t-x-x-90">len</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">==</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">Netstring</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">did</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">not</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">end</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">in</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72009r7" name=
      "x1-72009r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">return</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">rest</span><span class=
      "pcrr7t-x-x-90">&#91;:</span><span class=
      "pcrr7t-x-x-90">len</span><span class=
      "pcrr7t-x-x-90">&#93;,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">rest</span><span class=
      "pcrr7t-x-x-90">&#91;</span><span class=
      "pcrr7t-x-x-90">len</span><span class=
      "pcrr7t-x-x-90">+1:&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72010r8" name=
      "x1-72010r8"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72011r9" name=
      "x1-72011r9"></a></span><span class=
      "pcrr7t-x-x-90">def</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">parse</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">msg</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72012r10" name=
      "x1-72012r10"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sender</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">conn_id</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">path</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">rest</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">msg</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">split</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">3)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72013r11" name=
      "x1-72013r11"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">rest</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">parse_netstring</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">rest</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72014r12" name=
      "x1-72014r12"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">_</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">parse_netstring</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">rest</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72015r13" name=
      "x1-72015r13"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72016r14" name=
      "x1-72016r14"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">json</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">loads</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72017r15" name=
      "x1-72017r15"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72018r16" name=
      "x1-72018r16"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">return</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">uuid</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">id</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">path</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">body</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 568-->

  <p class="noindent">This is actually all of the code needed to
  parse a request, and is fairly the same in many other languages.
  If you look at the file <span class=
  "pcrb7t-">examples/python/mongrel2/request.py</span>,
  you'll see a more complete example of making a full request
  object. <!--l. 573-->

  <p class="noindent">A response is then just as simple and
  involves crafting a similar setup like this: <!--l. 576-->

  <div class="lstlisting" id="listing-33">
    <span class="label"><a id="x1-72019r1" name=
    "x1-72019r1"></a></span><span class=
    "pcrr7t-">UUID</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">SIZE</span><span class="pcrr7t-">:</span><span class=
    "pcrr7t-">ID</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">ID</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">ID</span><span class="pcrr7t-">,</span><span class=
    "pcrr7t-">&nbsp;</span><span class="pcrr7t-">BODY</span>
  </div><!--l. 580-->

  <p class="noindent">Notice I've got three IDs here, but you
  can do anywhere from 1 up to 128. Generating this is very easy in
  Python: <!--l. 583-->

  <p class="noindent"><a id="x1-72020r30" name="x1-72020r30"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 30:</span> <span class=
      "content"><span class="pplri7t-">Generating</span>
      <span class="pplri7t-">Responses</span></span>
    </div><!--tex4ht:label?: x1-72020r30 -->
    <!--l. 584-->

    <div class="lstlisting" id="listing-34">
      <span class="label"><a id="x1-72021r1" name=
      "x1-72021r1"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72022r2" name=
      "x1-72022r2"></a></span><span class=
      "pcrr7t-x-x-90">def</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">send</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">uuid</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">conn_id</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">msg</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72023r3" name=
      "x1-72023r3"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">header</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"%</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">d</span><span class=
      "pcrr7t-x-x-90">:%</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">,"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">uuid</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">len</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">str</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">conn_id</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">str</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">conn_id</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72024r4" name=
      "x1-72024r4"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">self</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">resp</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">send</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">header</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">+</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">+</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">msg</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72025r5" name=
      "x1-72025r5"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72026r6" name=
      "x1-72026r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72027r7" name=
      "x1-72027r7"></a></span><span class=
      "pcrr7t-x-x-90">def</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">deliver</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">uuid</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">idents</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">data</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-72028r8" name=
      "x1-72028r8"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">self</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">send</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">uuid</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">join</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">idents</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">data</span><span class=
      "pcrr7t-x-x-90">)</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 597-->

  <p class="noindent">That, again, is all there is to it. The
  <span class="pcrro7t-">send</span> method is the one doing the
  real work of crafting the response, and the <span class=
  "pcrro7t-">deliver</span> method is just using <span class=
  "pcrro7t-">send</span> to do all the the target idents joined
  with a space.

  <h4 class="subsectionHead"><span class="titlemark">5.3.7</span>
  <a id="x1-730005.3.7" name="x1-730005.3.7"></a>Python Handler
  API</h4><!--l. 605-->

  <p class="noindent">Instead of building all of this yourself,
  I've created a Python library that wraps all this up and
  makes it easy to use. Each of the other libraries are designed
  around the same idea and should have a similar design. To check
  out how to use the Python API, we'll take a look at each of
  the demos that are available. These are the same demos you ran in
  the previous section to create a sample deployment. <!--l. 612-->

  <p class="noindent">For the Python API, you may want to start by
  looking at two very small files that should be able to understand
  quickly: <span class=
  "pcrb7t-">examples/python/mongrel2/request.py</span> and
  <span class="pcrb7t-">examples/python/mongrel2/handler.py</span>.
  <!--l. 617-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">5.4</span> <a id=
  "x1-740005.4" name="x1-740005.4"></a>Basic Handler Demo</h3>
  <!--l. 619-->

  <p class="noindent">The most basic handler you can write is in
  the <span class="pcrb7t-">examples/http</span><span class=
  "pcrb7t-">_0mq/http.py</span> file and it just the simplest thing
  possible:<span class="footnote-mark"><a href=
  "book-final8.html#fn3x7"><sup class=
  "textsuperscript">3</sup></a></span><a id="x1-74001f3" name=
  "x1-74001f3"></a> <!--l. 623-->

  <p class="noindent"><a id="x1-74002r31" name="x1-74002r31"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 31:</span> <span class=
      "content"><span class="pplri7t-">http.py</span> <span class=
      "pplri7t-">example</span></span>
    </div><!--tex4ht:label?: x1-74002r31 -->
    <!--l. 624-->

    <div class="lstinputlisting">
      <a id="x1-74003" name="x1-74003"></a> <span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74004r1" name=
      "x1-74004r1"></a></span><span class=
      "pcrb7t-x-x-90">from</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">handler</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74005r2" name=
      "x1-74005r2"></a></span><span class=
      "pcrb7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">json</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74006r3" name=
      "x1-74006r3"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74007r4" name=
      "x1-74007r4"></a></span><span class=
      "pcrr7t-x-x-90">sender_id</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">82209006-86</span><span class=
      "pcrr7t-x-x-90">FF</span><span class=
      "pcrr7t-x-x-90">-4982-</span><span class=
      "pcrr7t-x-x-90">B5EA</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">D1E29E55D481</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74008r5" name=
      "x1-74008r5"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74009r6" name=
      "x1-74009r6"></a></span><span class=
      "pcrr7t-x-x-90">conn</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">handler</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">Connection</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">sender_id</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9997</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74010r7" name=
      "x1-74010r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9996</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74011r8" name=
      "x1-74011r8"></a></span><span class=
      "pcrb7t-x-x-90">while</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">True</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74012r9" name=
      "x1-74012r9"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">WAITING</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">FOR</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">REQUEST</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74013r10" name=
      "x1-74013r10"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74014r11" name=
      "x1-74014r11"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">conn</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">recv</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74015r12" name=
      "x1-74015r12"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74016r13" name=
      "x1-74016r13"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">if</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">is_disconnect</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74017r14" name=
      "x1-74017r14"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">DISCONNECT</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74018r15" name=
      "x1-74018r15"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">continue</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74019r16" name=
      "x1-74019r16"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74020r17" name=
      "x1-74020r17"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">if</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">get</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">KILLME</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">None</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74021r18" name=
      "x1-74021r18"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">They</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">want</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">to</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">be</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">killed</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74022r19" name=
      "x1-74022r19"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">response</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74023r20" name=
      "x1-74023r20"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">else</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74024r21" name=
      "x1-74024r21"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">response</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&lt;</span><span class=
      "pcrr7t-x-x-90">pre</span><span class=
      "pcrr7t-x-x-90">&gt;\</span><span class=
      "pcrr7t-x-x-90">nSENDER</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">\</span><span class=
      "pcrr7t-x-x-90">nIDENT</span><span class=
      "pcrr7t-x-x-90">:%</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">\</span><span class=
      "pcrr7t-x-x-90">nPATH</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">\</span><span class=
      "pcrr7t-x-x-90">nHEADERS</span><span class=
      "pcrr7t-x-x-90">:%</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">\</span><span class=
      "pcrr7t-x-x-90">nBODY</span><span class=
      "pcrr7t-x-x-90">:%</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">&lt;/</span><span class=
      "pcrr7t-x-x-90">pre</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74025r22" name=
      "x1-74025r22"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sender</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">conn_id</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">path</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74026r23" name=
      "x1-74026r23"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">json</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">dumps</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74027r24" name=
      "x1-74027r24"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74028r25" name=
      "x1-74028r25"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">response</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74029r26" name=
      "x1-74029r26"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74030r27" name=
      "x1-74030r27"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">conn</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">reply_http</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">response</span><span class=
      "pcrr7t-x-x-90">)</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 627-->

  <p class="noindent">All this code does is print back a simple
  little dump of what it received, and it's not even a valid
  HTML document. Let's walk through everything that's
  going on:

  <ol class="enumerate1">
    <li class="enumerate" id="x1-74034x1">Import the <span class=
    "pcrro7t-">handler</span> module from <span class=
    "pcrro7t-">mongrel2</span> and <span class=
    "pcrro7t-">json</span>. The <span class="pcrro7t-">json</span>
    module is really only used for logging.

    <li class="enumerate" id="x1-74036x2">Establish the UUID for
    our handler, and create a connection. It's not
    <span class="pplri7t-">really</span> a connection but more of a
    &ldquo;virtual circuit&rdquo; that you can just pretend is a
    connection. It's using all ZeroMQ and the protocol we
    just described to create a simple API to use.

    <li class="enumerate" id="x1-74038x3">Go into a while loop
    forever and recv request objects off the connection.

    <li class="enumerate" id="x1-74040x4">One type of special
    message we can get from Mongrel2 is a &ldquo;disconnect&rdquo;
    message, which tells you that one of the listeners you tried to
    talk to was closed. You should either ignore those and read
    another, or update any internal state you may have. They can
    come asynchronously, and for the most part you can ignore them
    unless you need to keep them open as in, say, a chat
    application or streaming.

    <li class="enumerate" id="x1-74042x5">Craft the reply
    you're going to send back, which is just a dump of what
    you received.

    <li class="enumerate" id="x1-74044x6">Send this reply back to
    Mongrel2. Notice the subtle difference where you include the
    <span class="pplri7t-">req</span> object as part of how you
    reply? This is the major difference between this API and more
    traditional request/response APIs in that you need the request
    you are responding to so that it knows where to send things. In
    a normal socket-based server this is just assumed to be the
    socket you're talking about.
  </ol><!--l. 648-->

  <p class="noindent">This is all you need at first to do simple
  HTTP handlers. In reality, the <span class=
  "pcrro7t-">reply</span><span class="pcrro7t-">_http</span> method
  is just syntactic sugar on crafting a decent HTTP response.
  Here's the actual method that is crafting these replies: 
  <!--l. 651-->

  <p class="noindent"><a id="x1-74045r32" name="x1-74045r32"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 32:</span> <span class=
      "content"><span class="pplri7t-">HTTP Response Python</span>
      <span class="pplri7t-">Code</span></span>
    </div><!--tex4ht:label?: x1-74045r32 -->
    <!--l. 652-->

    <div class="lstlisting" id="listing-35">
      <span class="label"><a id="x1-74046r1" name=
      "x1-74046r1"></a></span><span class=
      "pcrr7t-x-x-90">def</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">http_response</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">code</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">status</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74047r2" name=
      "x1-74047r2"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">payload</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">{</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">code</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">code</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">status</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">status</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr7t-x-x-90">}</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74048r3" name=
      "x1-74048r3"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">&#91;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">Content</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Length</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">len</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74049r4" name=
      "x1-74049r4"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">payload</span><span class=
      "pcrr7t-x-x-90">&#91;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">&#93;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"\</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">\</span><span class=
      "pcrr7t-x-x-90">n</span><span class=
      "pcrr7t-x-x-90">".</span><span class=
      "pcrr7t-x-x-90">join</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">k</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">v</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">for</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">k</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">v</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">in</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74050r5" name=
      "x1-74050r5"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">items</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74051r6" name=
      "x1-74051r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-74052r7" name=
      "x1-74052r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">return</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">HTTP_FORMAT</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">payload</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 664-->

  <p class="noindent">Which is then used by <span class=
  "pcrro7t-">Connection.reply</span><span class=
  "pcrro7t-">_http</span> and <span class=
  "pcrro7t-">Connection.deliver</span><span class=
  "pcrro7t-">_http</span> to send an actual HTTP response. That
  means all this is doing is creating the raw bytes you want to go
  to the real browser, and how it's delivered is irrelevant.
  For example, the <span class=
  "pcrro7t-">deliver</span><span class="pcrro7t-">_http</span>
  method means that, yes, you can have one handler send a single
  response to target <span class="pplri7t-">multiple</span>
  browsers at once.

  <h3 class="sectionHead"><span class="titlemark">5.5</span> <a id=
  "x1-750005.5" name="x1-750005.5"></a>Async File Upload Demo</h3>
  <!--l. 675-->

  <p class="noindent">Mongrel2 uses an asynchronous method of doing
  uploads that helps you avoid receiving files you either
  can't accept or shouldn't accept. It does this by
  sending your handler an initial message with just the headers,
  streaming the file to disk, and then a final message so you can
  read the resulting file. If you don't want the upload, then
  you can send a kill message (a 0 length message) and the
  connection closes, and the file never lands. <!--l. 682-->

  <p class="noindent">The upload mechanism works entirely on
  content length, and whether the file is larger than the
  <span class="pcrro7t-">limits.content</span><span class=
  "pcrro7t-">_length</span>. This means if you don't want to
  deal with this for most form uploads, then just set <span class=
  "pcrro7t-">limits.content</span><span class=
  "pcrro7t-">_length</span> high enough and you won't have
  to. <!--l. 687-->

  <p class="noindent">However, if you want to handle file uploads
  or large requests, then you add the setting <span class=
  "pcrro7t-">upload.temp</span><span class="pcrro7t-">_store</span>
  to a <span class="pcrro7t-">mkstemp</span> compatible path like
  <span class="pcrb7t-">/tmp/mongrel2.upload.XXXXXX</span> with the
  XXXXXX chars being replaced with random characters. It
  doesn't have to /tmp either, and can be any store you want,
  network disk, anything. <!--l. 693-->

  <p class="noindent">Here's an example handler in
  <span class="pcrb7t-">examples/http</span><span class=
  "pcrb7t-">_0mq/upload.py</span> that shows you how to do it: 
  <!--l. 696-->

  <p class="noindent"><a id="x1-75001r33" name="x1-75001r33"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 33:</span> <span class=
      "content"><span class="pplri7t-">Async Upload</span>
      <span class="pplri7t-">Example</span></span>
    </div><!--tex4ht:label?: x1-75001r33 -->
    <!--l. 697-->

    <div class="lstinputlisting">
      <a id="x1-75002" name="x1-75002"></a> <span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75003r1" name=
      "x1-75003r1"></a></span><span class=
      "pcrb7t-x-x-90">from</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">handler</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75004r2" name=
      "x1-75004r2"></a></span><span class=
      "pcrb7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">json</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75005r3" name=
      "x1-75005r3"></a></span><span class=
      "pcrb7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">hashlib</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75006r4" name=
      "x1-75006r4"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75007r5" name=
      "x1-75007r5"></a></span><span class=
      "pcrr7t-x-x-90">sender_id</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">82209006-86</span><span class=
      "pcrr7t-x-x-90">FF</span><span class=
      "pcrr7t-x-x-90">-4982-</span><span class=
      "pcrr7t-x-x-90">B5EA</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">D1E29E55D481</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75008r6" name=
      "x1-75008r6"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75009r7" name=
      "x1-75009r7"></a></span><span class=
      "pcrr7t-x-x-90">conn</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">handler</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">Connection</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">sender_id</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9997</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75010r8" name=
      "x1-75010r8"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9996</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75011r9" name=
      "x1-75011r9"></a></span><span class=
      "pcrb7t-x-x-90">while</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">True</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75012r10" name=
      "x1-75012r10"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">WAITING</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">FOR</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">REQUEST</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75013r11" name=
      "x1-75013r11"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75014r12" name=
      "x1-75014r12"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">conn</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">recv</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75015r13" name=
      "x1-75015r13"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75016r14" name=
      "x1-75016r14"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">if</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">is_disconnect</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75017r15" name=
      "x1-75017r15"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">DISCONNECT</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75018r16" name=
      "x1-75018r16"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">continue</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75019r17" name=
      "x1-75019r17"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75020r18" name=
      "x1-75020r18"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">elif</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">get</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">X</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Mongrel2</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Upload</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Done</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">None</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75021r19" name=
      "x1-75021r19"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">expected</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">get</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">X</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Mongrel2</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Upload</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Start</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">BAD</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75022r20" name=
      "x1-75022r20"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">upload</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">get</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">X</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Mongrel2</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Upload</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Done</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">None</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75023r21" name=
      "x1-75023r21"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75024r22" name=
      "x1-75024r22"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">if</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">expected</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">!=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">upload</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75025r23" name=
      "x1-75025r23"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">GOT</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">THE</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">WRONG</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">TARGET</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">FILE</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">expected</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">upload</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75026r24" name=
      "x1-75026r24"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">continue</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75027r25" name=
      "x1-75027r25"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75028r26" name=
      "x1-75028r26"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">open</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">upload</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">read</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75029r27" name=
      "x1-75029r27"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">UPLOAD</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">DONE</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">BODY</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">IS</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">d</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">long</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">content</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">length</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">is</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75030r28" name=
      "x1-75030r28"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">len</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">&#91;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">Content</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Length</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">&#93;)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75031r29" name=
      "x1-75031r29"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75032r30" name=
      "x1-75032r30"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">response</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">UPLOAD</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">GOOD</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">hashlib</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">md5</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">hexdigest</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75033r31" name=
      "x1-75033r31"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75034r32" name=
      "x1-75034r32"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">elif</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">get</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">X</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Mongrel2</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Upload</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Start</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">None</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75035r33" name=
      "x1-75035r33"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">UPLOAD</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">starting</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">don</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">t</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">reply</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">yet</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75036r34" name=
      "x1-75036r34"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">Will</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">read</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">file</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">from</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">s</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">get</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">X</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Mongrel2</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Upload</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">Start</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">None</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75037r35" name=
      "x1-75037r35"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">continue</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75038r36" name=
      "x1-75038r36"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75039r37" name=
      "x1-75039r37"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">else</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75040r38" name=
      "x1-75040r38"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">response</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&lt;</span><span class=
      "pcrr7t-x-x-90">pre</span><span class=
      "pcrr7t-x-x-90">&gt;\</span><span class=
      "pcrr7t-x-x-90">nSENDER</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">\</span><span class=
      "pcrr7t-x-x-90">nIDENT</span><span class=
      "pcrr7t-x-x-90">:%</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">\</span><span class=
      "pcrr7t-x-x-90">nPATH</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">\</span><span class=
      "pcrr7t-x-x-90">nHEADERS</span><span class=
      "pcrr7t-x-x-90">:%</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">\</span><span class=
      "pcrr7t-x-x-90">nBODY</span><span class=
      "pcrr7t-x-x-90">:%</span><span class=
      "pcrr7t-x-x-90">r</span><span class=
      "pcrr7t-x-x-90">&lt;/</span><span class=
      "pcrr7t-x-x-90">pre</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">%</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75041r39" name=
      "x1-75041r39"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">sender</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">conn_id</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">path</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75042r40" name=
      "x1-75042r40"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">json</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">dumps</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75043r41" name=
      "x1-75043r41"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75044r42" name=
      "x1-75044r42"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">response</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75045r43" name=
      "x1-75045r43"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-75046r44" name=
      "x1-75046r44"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">conn</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">reply_http</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">response</span><span class=
      "pcrr7t-x-x-90">)</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 700-->

  <p class="noindent">You can test this with something like
  <span class="obeylines-h verb"><span class=
  "pcrr7t-">curl</span><span class=
  "pcrr7t-">&nbsp;-T</span><span class=
  "pcrr7t-">&nbsp;tests/config.sqlite</span><span class=
  "pcrr7t-">&nbsp;http://localhost:6767/handlertest</span></span>
  to upload a big file. <!--l. 703-->

  <p class="noindent">What's happening is the following
  process:

  <ol class="enumerate1">
    <li class="enumerate" id="x1-75050x1">Mongrel2 receives a
    request from a browser (or curl in this case) that is greater
    than <span class="pcrro7t-">limits.content</span><span class=
    "pcrro7t-">_length</span> in size. It actually doesn't
    read all of it yet, only about 2k.

    <li class="enumerate" id="x1-75052x2">Mongrel2 looks up the
    <span class="pcrro7t-">upload.temp</span><span class=
    "pcrro7t-">_store</span> setting and makes a temp file there to
    write the contents. If you don't have this setting then
    it aborts and returns an error to the browser.

    <li class="enumerate" id="x1-75054x3">Mongrel2 sees that the
    request is for a Handler, so it crafts an initial request
    message. This request message has all the original headers,
    plus a <span class="pcrro7t-">X-Mongrel2-Upload-Start</span>
    header with the path of the expected tmpfile you will read
    later.

    <li class="enumerate" id="x1-75056x4">Your handler receives
    this message, which has no actual content, but the original
    content length, all the headers, and this new header to
    indicate an upload is starting.

    <li class="enumerate" id="x1-75058x5">At this point, your
    handler can decide to kill the connection by simply responding
    with a kill message, or even with a valid HTTP error reponse
    then a kill message.

    <li class="enumerate" id="x1-75060x6">Otherwise your handler
    does nothing, and Mongrel2 is already streaming the file into
    the designated tmpfile for this upload.

    <li class="enumerate" id="x1-75062x7">When the upload is
    finally saved to the file, it <span class=
    "pplri7t-">adds</span> a new header of <span class=
    "pcrro7t-">X-Mongrel2-Upload-Done</span> set to the same file
    as the first header. Remember that <span class=
    "pplri7t-">both</span> headers are in this final request.

    <li class="enumerate" id="x1-75064x8">Your handler then gets
    this final request message that has both the <span class=
    "pcrro7t-">X-Mongrel2-Upload-Start</span> and <span class=
    "pcrro7t-">X-Mongrel2-Upload-Done</span> headers, which you can
    then use to read the upload contents. You should also make sure
    the headers match to prevent someone forging completed uploads.
  </ol><!--l. 716-->

  <p class="noindent"><a id="x1-75065r12" name="x1-75065r12"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Note 12:</span> <span class=
      "content"><span class="pplri7t-">Watch The chroot</span>
      <span class="pplri7t-">Too</span></span>
    </div><!--tex4ht:label?: x1-75065r12 -->

    <div class="quote">
      <!--l. 717-->

      <p class="indent">Remember, when you run Mongrel2 it will
      store the file relative to its <span class=
      "pcrro7t-">chroot</span> setting. In testing you probably
      aren't running Mongrel2 as root so it works fine. You
      just then have to make sure that your handler know to look
      for the file in the same place. So if you have <span class=
      "pcrb7t-">/var/www/mongrel2.org</span> for your <span class=
      "pcrro7t-">chroot</span> and <span class=
      "pcrb7t-">/uploads/file.XXXXXX</span> then the actual file
      will be in <span class=
      "pcrb7t-">/var/www/mongrel2.org/uploads/file.XXXXXX</span>.
      The good thing is you can read the config database in your
      handlers and find out all this information as well.
    </div>
  </div>
  <hr class="endfloat">

  <h3 class="sectionHead"><span class="titlemark">5.6</span> <a id=
  "x1-760005.6" name="x1-760005.6"></a>MP3 Streaming Demo</h3>
  <!--l. 726-->

  <p class="noindent">The next example is a very simple and, well,
  kind of poorly implemented MP3 streaming demo that uses the ICY
  protocol. ICY is a really lame protocol that was obviously
  designed before HTTP was totally baked and probably by people who
  don't really get HTTP. It works in an odd way of having
  meta-data sent at specific sized intervals so the client can
  display an update to the meta-data. <!--l. 733-->

  <p class="noindent">The mp3streamer demo creates a streaming
  system by having a thread that receives requests for connections,
  and then another thread that sends the current data to all
  currently connected clients. Rather than go through all the code,
  you can take a look at the main file and see how simple it is
  once you get the streaming thread right: <!--l. 740-->

  <p class="noindent"><a id="x1-76001r34" name="x1-76001r34"></a>
  <hr class="float">

  <div class="float">
    <div class="caption">
      <span class="id">Source 34:</span> <span class=
      "content"><span class="pplri7t-">Base mp3stream</span>
      <span class="pplri7t-">Code</span></span>
    </div><!--tex4ht:label?: x1-76001r34 -->
    <!--l. 741-->

    <div class="lstinputlisting">
      <a id="x1-76002" name="x1-76002"></a> <span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76003r1" name=
      "x1-76003r1"></a></span><span class=
      "pcrb7t-x-x-90">from</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mp3stream</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ConnectState</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Streamer</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76004r2" name=
      "x1-76004r2"></a></span><span class=
      "pcrb7t-x-x-90">from</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">mongrel2</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">handler</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76005r3" name=
      "x1-76005r3"></a></span><span class=
      "pcrb7t-x-x-90">import</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">glob</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76006r4" name=
      "x1-76006r4"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76007r5" name=
      "x1-76007r5"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76008r6" name=
      "x1-76008r6"></a></span><span class=
      "pcrr7t-x-x-90">sender_id</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">9703</span><span class=
      "pcrr7t-x-x-90">b4dd</span><span class=
      "pcrr7t-x-x-90">-227</span><span class=
      "pcrr7t-x-x-90">a</span><span class=
      "pcrr7t-x-x-90">-45</span><span class=
      "pcrr7t-x-x-90">c4</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">b7a1</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">ef62d97962b2</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76009r7" name=
      "x1-76009r7"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76010r8" name=
      "x1-76010r8"></a></span><span class=
      "pcrr7t-x-x-90">CONN</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">handler</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">Connection</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">sender_id</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9995</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76011r9" name=
      "x1-76011r9"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">tcp</span><span class=
      "pcrr7t-x-x-90">://127.0.0.1:9994</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76012r10" name=
      "x1-76012r10"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76013r11" name=
      "x1-76013r11"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76014r12" name=
      "x1-76014r12"></a></span><span class=
      "pcrr7t-x-x-90">STREAM_NAME</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">Mongrel2</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">Radio</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76015r13" name=
      "x1-76015r13"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76016r14" name=
      "x1-76016r14"></a></span><span class=
      "pcrr7t-x-x-90">MP3_FILES</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">glob</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">glob</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">&#8902;.</span><span class=
      "pcrr7t-x-x-90">mp3</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76017r15" name=
      "x1-76017r15"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76018r16" name=
      "x1-76018r16"></a></span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">PLAYING</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">MP3_FILES</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76019r17" name=
      "x1-76019r17"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76020r18" name=
      "x1-76020r18"></a></span><span class=
      "pcrr7t-x-x-90">CHUNK_SIZE</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">8</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&#8902;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">1024</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76021r19" name=
      "x1-76021r19"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76022r20" name=
      "x1-76022r20"></a></span><span class=
      "pcrr7t-x-x-90">STATE</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">ConnectState</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76023r21" name=
      "x1-76023r21"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76024r22" name=
      "x1-76024r22"></a></span><span class=
      "pcrr7t-x-x-90">STREAMER</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">Streamer</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">MP3_FILES</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">STATE</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">CONN</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">CHUNK_SIZE</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">sender_id</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76025r23" name=
      "x1-76025r23"></a></span><span class=
      "pcrr7t-x-x-90">STREAMER</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">start</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76026r24" name=
      "x1-76026r24"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76027r25" name=
      "x1-76027r25"></a></span><span class=
      "pcrr7t-x-x-90">HEADERS</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">{</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">icy</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">metaint</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">CHUNK_SIZE</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76028r26" name=
      "x1-76028r26"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">icy</span><span class=
      "pcrr7t-x-x-90">-</span><span class=
      "pcrr7t-x-x-90">name</span><span class=
      "pcrr8c-x-x-90">'</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">STREAM_NAME</span><span class=
      "pcrr7t-x-x-90">}</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76029r27" name=
      "x1-76029r27"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76030r28" name=
      "x1-76030r28"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76031r29" name=
      "x1-76031r29"></a></span><span class=
      "pcrb7t-x-x-90">while</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">True</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76032r30" name=
      "x1-76032r30"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">CONN</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">recv</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76033r31" name=
      "x1-76033r31"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76034r32" name=
      "x1-76034r32"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">if</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">is_disconnect</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76035r33" name=
      "x1-76035r33"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">DISCONNECT</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">conn_id</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76036r34" name=
      "x1-76036r34"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">STATE</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">remove</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76037r35" name=
      "x1-76037r35"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">else</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76038r36" name=
      "x1-76038r36"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">REQUEST</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">body</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76039r37" name=
      "x1-76039r37"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76040r38" name=
      "x1-76040r38"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">if</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">STATE</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">count</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&gt;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">20:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76041r39" name=
      "x1-76041r39"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">print</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">TOO</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">MANY</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">STATE</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">count</span><span class=
      "pcrr7t-x-x-90">()</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76042r40" name=
      "x1-76042r40"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">CONN</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">reply_http</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">Too</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">Many</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">Connected</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">Try</span><span class=
      "pcrr7t-x-x-90">&#9251;</span><span class=
      "pcrr7t-x-x-90">Later</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76043r41" name=
      "x1-76043r41"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrb7t-x-x-90">else</span><span class=
      "pcrr7t-x-x-90">:</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76044r42" name=
      "x1-76044r42"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">STATE</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">add</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">)</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><br>
      <span class="label"><a id="x1-76045r43" name=
      "x1-76045r43"></a></span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">CONN</span><span class=
      "pcrr7t-x-x-90">.</span><span class=
      "pcrr7t-x-x-90">reply_http</span><span class=
      "pcrr7t-x-x-90">(</span><span class=
      "pcrr7t-x-x-90">req</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">"</span><span class=
      "pcrr7t-x-x-90">,</span><span class=
      "pcrr7t-x-x-90">&nbsp;</span><span class=
      "pcrr7t-x-x-90">headers</span><span class=
      "pcrr7t-x-x-90">=</span><span class=
      "pcrr7t-x-x-90">HEADERS</span><span class=
      "pcrr7t-x-x-90">)</span>
    </div>
  </div>
  <hr class="endfloat">
  <!--l. 744-->

  <p class="noindent">Walking through this example is fairly easy,
  assuming you just trust that the streaming thread stuff works:

  <ol class="enumerate1">
    <li class="enumerate" id="x1-76050x1">Starts off just like the
    handler test.

    <li class="enumerate" id="x1-76052x2">We figure out what .mp3
    files are in the current directory.

    <li class="enumerate" id="x1-76054x3">Establish a data chunk
    size of 5k for the ICY protocol and make a ConnectState and
    Streamer from that. These are the streaming thread things found
    in <span class="pcrb7t-">mp3stream.py</span> in the same
    directory.

    <li class="enumerate" id="x1-76056x4">We then loop forever,
    accepting requests.

    <li class="enumerate" id="x1-76058x5">Unlike the handler, we
    want to remove disconnected clients, so we take them out of the
    STATE when we are notified.

    <li class="enumerate" id="x1-76060x6">If we have too many
    connected clients, we reply with a failure.

    <li class="enumerate" id="x1-76062x7">Otherwise, we add them to
    the STATE and then send the initial ICY protocol header to get
    things going.
  </ol><!--l. 763-->

  <p class="noindent">That is the base of it, and if you point
  mplayer at it (which is the only player that works, really) you
  should hear it play: <!--l. 766-->

  <div class="lstlisting" id="listing-36">
    <span class="label"><a id="x1-76063r1" name=
    "x1-76063r1"></a></span><span class=
    "pcrr7t-">&gt;</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">mplayer</span><span class=
    "pcrr7t-">&nbsp;</span><span class=
    "pcrr7t-">http</span><span class=
    "pcrr7t-">://</span><span class=
    "pcrr7t-">localhost</span><span class=
    "pcrr7t-">:6767/</span><span class="pcrr7t-">mp3stream</span>
  </div><!--l. 770-->

  <p class="noindent">That is, assuming you put some mp3 files into
  the directory and started the handler again. <!--l. 773-->

  <p class="noindent">For more on how the actual state and the
  protocol works, go look at mp3stream.py. Explaining it is far
  outside the scope of this manual, but the key points to realize
  are that this is one thread that's targetting randomly
  connected clients with a single message to the Mongrel2 server
  and streaming it.

  <h3 class="sectionHead"><span class="titlemark">5.7</span> <a id=
  "x1-770005.7" name="x1-770005.7"></a>Chat Demo</h3><!--l. 782-->

  <p class="noindent">The chat demo is the most involved
  demonstration, and I'm kind of getting tired of leading you
  by the hand, so you go read the code. Here's where to look:

  <dl class="description">
    <dt class="description"><span class="pplb7t-">JavaScript</span>

    <dd class="description">Look at <span class=
    "pcrb7t-">examples/chat/static/&#8902;.js</span> for the
    goodies. The key is to see how <span class=
    "pcrb7t-">chat.js</span> works with the JSSocket stuff, and
    then look at how I did <span class="pcrb7t-">app.js</span>
    using <span class="pcrb7t-">fsm.js</span>.

    <dt class="description"><span class="pplb7t-">Python</span>

    <dd class="description">Look at the <span class=
    "pcrb7t-">examples/chat/chat.py</span> file to see how the chat
    states are maintained and how messages are sent around.

    <dt class="description"><span class="pplb7t-">config</span>

    <dd class="description">The configuration you created in the
    last chapter actually works with the demo, and if you've
    been following along you should have tested it.
  </dl><!--l. 797-->

  <p class="noindent">Hopefully, you can figure it out from the
  code, but if not, let me know. <!--l. 800-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">5.8</span> <a id=
  "x1-780005.8" name="x1-780005.8"></a>Other Language APIs</h3>
  <!--l. 802-->

  <p class="noindent">As mentioned before, there are currently APIs
  for Ruby, C++, and PHP in addition to the Python code:

  <dl class="description">
    <dt class="description"><span class="pplb7t-">Python</span>

    <dd class="description">When you installed the <span class=
    "pcrro7t-">m2sh</span> gear, you also got a <span class=
    "pcrro7t-">mongrel2</span> Python library.

    <dt class="description"><span class="pplb7t-">Ruby</span>

    <dd class="description">Probably the most extensively supported
    language, with good Rack support, by <a href=
    "http://github.com/perplexes/m2r">perplexes on github</a>.

    <dt class="description"><span class="pplb7t-">C++</span>

    <dd class="description">C++ support by <a href=
    "http://github.com/akrennmair/mongrel2-cpp">akrennmair on
    github</a>.

    <dt class="description"><span class="pplb7t-">PHP</span>

    <dd class="description">PHP support by <a href=
    "http://github.com/winks/m2php">winks on github</a>.
  </dl><!--l. 814-->

  <p class="noindent">If you want to implement another language, it
  should be fairly trivial. Just base your design on the Python API
  so that it is consistent, but, please, don't be a slave to
  the Python design if it doesn't fit the chosen language;
  creating a direct translation of the Python is fine at first, but
  try to make it idiomatic after that so people who use that
  language feel at home and it's easy for them. <!--l. 822-->

  <p class="noindent">

  <h3 class="sectionHead"><span class="titlemark">5.9</span> <a id=
  "x1-790005.9" name="x1-790005.9"></a>Writing Your Own m2sh</h3>
  <!--l. 824-->

  <p class="noindent">The very last thing I will cover in the
  section on hacking Mongrel2 is how to write your own <span class=
  "pcrro7t-">m2sh</span> script in your favorite language.
  Obviously, if you're doing this you should probably have a
  good reason<span class="footnote-mark"><a href=
  "book-final9.html#fn4x7"><sup class=
  "textsuperscript">4</sup></a></span><a id="x1-79001f4" name=
  "x1-79001f4"></a> . What writing your own, or understanding what
  <span class="pcrro7t-">m2sh</span> is doing will do for you,
  though, is help you when you start to think about automating
  Mongrel2 for your deployments. <!--l. 832-->

  <p class="noindent">Hopefully, I may have motivated you to
  automate, automate, automate. This is why we write software. If I
  wanted to do stuff manually I'd go play guitars or juggle.
  I write software because I want a computer to do things for me,
  and nothing needs this more than managing your systems. 
  <!--l. 837-->

  <p class="noindent">This is why Mongrel2 is designed the way it
  is, using the MVC model. It lets <span class=
  "pplri7t-">you</span> create your own View like m2sh, web
  interfaces, automation scripts, and anything else you need to
  make it easier to manage more. <!--l. 841-->

  <p class="noindent">If you want to write your own <span class=
  "pcrro7t-">m2sh</span> then first go have a look at the Python
  code in <span class="pcrb7t-">examples/python/config</span>. This
  is where each command lives, where the argument parsing is and,
  most importantly, the ORM model that works the raw SQLite
  database. <!--l. 846-->

  <p class="noindent">The next thing to do is to make your tool
  craft databases and compare the results to what m2sh does for a
  similar configuration. I recommend you make a database
  that's &ldquo;correct&rdquo; with m2sh, and then dump it
  via <span class="pcrro7t-">sqlite3</span>. After that, use your
  tool to make your own database, dump it, and then use
  <span class="pcrro7t-">diff</span> to compare your results to
  mine. <!--l. 852-->

  <p class="noindent">Finally, you'll need to look at two
  base schema files: <span class=
  "pcrb7t-">src/config/config.sql</span> and <span class=
  "pcrb7t-">src/config/mimetypes.sql</span>, where the database
  schema is created and the large list of mimetypes that Mongrel2
  knows is stored.<span class="footnote-mark"><a href=
  "book-final10.html#fn5x7"><sup class=
  "textsuperscript">5</sup></a></span><a id="x1-79002f5" name=
  "x1-79002f5"></a> Your tool should be able to use this SQL to
  make its database, or at least know what it does. <!--l. 859-->

  <p class="noindent">If you do something cool with all of this,
  let us know.

  <h2 class="chapterHead"><span class=
  "titlemark">Chapter&nbsp;6</span><br>
  <a id="x1-800006" name="x1-800006"></a>Contributing</h2>
  <!--l. 3-->

  <p class="noindent">You have gone through a complete description
  of all the features that Mongrel2 has right now, but <span class=
  "pplri7t-">not</span> all the features it <span class=
  "pplri7t-">will</span> have. I tend to write small software that
  does exactly what it needs to do, and Mongrel2 is no different.
  What you see here are the majority of the things you need to do
  right now, and we'll be slowly adding things people need. 
  <!--l. 9-->

  <p class="noindent">Right now, what you have in your hands is
  something you can use, but it needs help. There is not SSL
  support yet. We're just using plain old poll to get things
  working. There's no dynamic modules or filters yet (if we
  ever have them), and we haven't really deployed it in
  anything important. <!--l. 14-->

  <p class="noindent">That means you can contribute. If you want to
  help with Mongrel2, just go to the <a href=
  "http://mongrel2.org">Mongrel2</a> site and do whatever you can.
  Submit bug reports, help with docs, offer patches, join the
  mailing list, whatever. <!--l. 18-->

  <p class="noindent">The reason I am mostly begging people who are
  interested in Mongrel2 for help is that I'm on a mission.
  I've been through 3 or 4 major technology cycles that got
  us nowhere but forced me and many other programmers to learn
  whole new languages with dubious benefits. I remember C++ wiping
  out C with no real benefit. I remember Java wiping out C++,
  again, with no real benefit. I remember Ruby wiping out Java, and
  again, with no real benefit. In the end, the only thing we got
  from each &ldquo;language revolution&rdquo; was yet another Ponzi
  Scheme we all had to pretend to believe in if we wanted to get a
  job. <!--l. 27-->

  <p class="noindent">My goal with Mongrel2 is to lessen this
  suffering. A professional engineer should not have to follow fads
  like a fashion designer. You should be able to use the tool that
  works best for the environment, and all languages should be
  treated equally in the eyes of core technologies like web servers
  and email servers. Businesses should also be able to hire
  programmers, not by what language they know, but by how good they
  are and how well they fit. Companies should be able to pivot off
  dead or poorly-suited technologies and onto better ones without
  major upheaval. <!--l. 35-->

  <p class="noindent">I don't know if Mongrel2 will do this,
  but I do know it has a chance to, at least, start the trend of
  language agnosticism in our industry. If you want to help, then
  please, come contribute. <!--l. 39-->

  <p class="noindent">Thanks, <!--l. 41-->

  <p class="noindent">Zed

