<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Unwinding the Stack &#187; Programming</title>
	<atom:link href="http://thestaticvoid.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://thestaticvoid.com</link>
	<description>Explorations in Computing</description>
	<lastBuildDate>Wed, 09 May 2012 21:22:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>My Homemade LOM</title>
		<link>http://thestaticvoid.com/post/2012/05/09/my-homemade-lom/</link>
		<comments>http://thestaticvoid.com/post/2012/05/09/my-homemade-lom/#comments</comments>
		<pubDate>Wed, 09 May 2012 21:17:42 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[hardware]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=798</guid>
		<description><![CDATA[In one of the final classes of my CS master&#8217;s program, Embedded Computing, we were required to complete a semester project of our choosing involving embedded systems. Like in previous semester projects, I wanted to do something that I would actually be able to use after the class ended. This time around I chose to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://thestaticvoid.com/wordpress/wp-content/uploads/2012/05/lom.jpg"><img src="http://thestaticvoid.com/wordpress/wp-content/uploads/2012/05/lom-300x199.jpg" alt="" title="My homemade LOM installed in an Ultra 24" width="300" height="199" class="alignright size-medium wp-image-809" /></a>In one of the final classes of my CS master&#8217;s program, Embedded Computing, we were required to complete a semester project of our choosing involving embedded systems.  Like in <a href="http://thestaticvoid.com/post/2011/06/09/wireless-802-1x-support-in-solaris/">previous semester projects</a>, I wanted to do something that I would actually be able to use after the class ended.</p>
<p>This time around I chose to build a <a href="http://en.wikipedia.org/wiki/Out-of-band_management">lights-out manager</a> for my Sun Ultra 24 server (which this blog is hosted on).  With a LOM I can control the system&#8217;s power and access its serial console so I will be able to perform OS updates remotely, among other things.</p>
<p>Since I already owned one and I didn&#8217;t want to spend a lot of money, I chose to develop the project on top of the <a href="http://arduino.cc/en/Main/arduinoBoardUno">Arduino</a> platform.  I like the size of the Arduino, and the availability of different shields to minimize soldering.  It&#8217;s also able to be powered by USB, which is perfect because the Ultra 24 has an internal USB port that always supplies power.</p>
<p>To make things a little more challenging for myself (because the Arduino is pretty easy on its own), I chose to implement a hardware UART to communicate with the Ultra 24&#8242;s serial port.  Specifically, I chose to use the <a href="http://www.maxim-ic.com/datasheet/index.mvp/id/2052">Maxim MAX3110E</a> SPI UART and RS-232 transceiver.  Great little chip.</p>
<p>For communication with the outside world, I bought an <a href="http://www.freetronics.com/products/ethernet-shield-with-poe">Ethernet shield</a> from Freetronics.  It&#8217;s compatible with the official Arduino Ethernet shield, but includes a fix to allow the network module to work with other SPI devices (such as my UART) on the same bus.  I started to implement the network UI using Telnet, but after realizing I would have to translate the serial console data from VT100 to <a href="http://www.ietf.org/rfc/rfc854.txt">NVT</a>, I switched to <a href="http://www.ietf.org/rfc/rfc1282.txt">Rlogin</a>, which is like Telnet, but assumes like-to-like terminal types.</p>
<p>Lastly, for controling the system&#8217;s power, I figured out how to tap into the Ultra 24&#8242;s power LED and switch.  Using the LED, I can check whether the system is on or off, and using the switch circuit and a transistor, I can power the system on and off.  I managed to do this without affecting the operation of the front panel buttons/LEDs.</p>
<p>I&#8217;ll spare you all of the implementation details (if you&#8217;re interested, you can read <a href="https://github.com/MrStaticVoid/school/raw/master/CSCI6907/project/final-report/final-report.pdf">my report</a>).  Suffice it to say, the thing works as well as I could have imagined.  Here is a screenshot of me using the serial console on my workstation:</p>
<p><a href="http://thestaticvoid.com/wordpress/wp-content/uploads/2012/05/session.png"><img src="http://thestaticvoid.com/wordpress/wp-content/uploads/2012/05/session.png" alt="" title="LOM Session" width="652" height="1050" class="aligncenter size-full wp-image-804" /></a></p>
<p>From my research, the serial and power motherboard headers are the same on most modern Intel systems, so this LOM should work on more than just an Ultra 24.  If you want to build one of your own, my code is available on <a href="https://github.com/MrStaticVoid/school/tree/master/CSCI6907/project/sketch">GitHub</a> and the hardware schematic is in the report I linked to above.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2012/05/09/my-homemade-lom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Nitrogen as a Library Under Yaws</title>
		<link>http://thestaticvoid.com/post/2011/02/17/using-nitrogen-as-a-library-under-yaws/</link>
		<comments>http://thestaticvoid.com/post/2011/02/17/using-nitrogen-as-a-library-under-yaws/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 20:58:23 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[nitrogen]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[yaws]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=477</guid>
		<description><![CDATA[Motivation I&#8217;ve been working on a project off and on for the past year which uses the Spring Framework extensively. I love Spring for how easy it makes web development, from wiring up various persistence and validation libraries, to dependency injection, and brainless security and model-view-controller functionality. However, as the project has grown, I&#8217;ve become [...]]]></description>
			<content:encoded><![CDATA[<h4>Motivation</h4>
<p>I&#8217;ve been working on a project off and on for the past year which uses the <a href="http://www.springsource.org/">Spring Framework</a> extensively.  I love Spring for how easy it makes web development, from wiring up various persistence and validation libraries, to dependency injection, and brainless security and model-view-controller functionality.  However, as the project has grown, I&#8217;ve become more and more frustrated with one aspect of Spring and Java web development in general: performance and resource usage.  It&#8217;s so bad, I&#8217;ve pretty much stopped working on it altogether.  Between Eclipse and Tomcat, you&#8217;ve already spent over 2 GB of memory, and every time you make a source code change, Tomcat has to reload the application which takes up to 30 seconds on my system, if it doesn&#8217;t crash first.  This doesn&#8217;t suit my development style of making and testing lots of small, incremental changes.</p>
<p>So rather than buy a whole new computer, I&#8217;ve started to look for a new lightweight web framework to convert the project to.  I really like Erlang and have wanted to write something big in it for a while, so when I found the <a href="http://nitrogenproject.com/">Nitrogen Web Framework</a>, I thought this might be my opportunity to do so.  Erlang is designed for performance and fault-tolerance and has a great standard library in <a href="http://www.erlang.org/doc/">OTP</a>, including a distributed database, <a href="http://www.erlang.org/doc/man/mnesia.html">mnesia</a>, which should eliminate my need for an object-relational mapper (it stores Erlang terms directly) and enable me to make my application highly available in the future without much fuss.  Nitrogen has the added benefit of simplifying some of the fancy things I wanted to do with AJAX but found too difficult with Spring MVC.</p>
<p>The thing I don&#8217;t like about Nitrogen is that it is designed to deliver a complete, stand-alone application with a built-in web server of your choosing and a copy of the entire Erlang runtime.  This seems to be The Erlang/OTP Way of doing things, but it seems very foreign to me.  I already have Erlang installed system-wide and a web server, Yaws, that I have a lot of <a href="http://thestaticvoid.com/post/2009/08/04/replacing-apache-with-yaws/">time invested in</a>.  I&#8217;d rather use Nitrogen as a library in my application under Yaws just like I was using Spring as a library in my application under Tomcat.</p>
<h4>Procedures</h4>
<p>I start my new project with <a href="https://bitbucket.org/basho/rebar/wiki/Home">Rebar</a>:</p>
<pre class="terminal">
$ <kbd>mkdir test &#038;&#038; cd test</kbd>
$ <kbd>wget https://bitbucket.org/basho/rebar/downloads/rebar &#038;&#038; chmod +x rebar</kbd>
$ <kbd>./rebar create-app appid=test</kbd>
==> test (create-app)
Writing src/test.app.src
Writing src/test_app.erl
Writing src/test_sup.erl
$ <kbd>mkdir static include templates</kbd>  <span class="comment"># These directories will be used later</span>
</pre>
<p>Now I define my project&#8217;s dependencies in <tt>rebar.config</tt> in the same directory:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #109ab8;">&#123;</span>deps<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>nitrogen_core<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;2.1.*&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>git<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;git://github.com/nitrogen/nitrogen_core.git&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;HEAD&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>nprocreg<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;0.2.*&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>git<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;git://github.com/nitrogen/nprocreg.git&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;HEAD&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>simple_bridge<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;1.2.*&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>git<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;git://github.com/nitrogen/simple_bridge.git&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;HEAD&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>sync<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;0.1.*&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>git<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;git://github.com/rklophaus/sync.git&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;HEAD&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><br />
<span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></div></div>
<p>These dependencies are taken from Nitrogen&#8217;s <a href="https://github.com/nitrogen/nitrogen/blob/master/rebar.config">rebar.config</a>.  Next I write a Makefile to simplify common tasks:</p>
<div class="codecolorer-container make default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="make codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">default<span style="color: #004400;">:</span> compile static<span style="color: #004400;">/</span>nitrogen<br />
<br />
get<span style="color: #004400;">-</span>deps<span style="color: #004400;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">./</span>rebar get<span style="color: #004400;">-</span>deps<br />
<br />
<span style="color: #666622; font-weight: bold;">include</span><span style="color: #004400;">/</span>basedir<span style="color: #004400;">.</span>hrl<span style="color: #004400;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; echo <span style="color: #CC2200;">'-define(BASEDIR, &quot;$(PWD)&quot;).'</span> <span style="color: #004400;">&gt;</span> <span style="color: #666622; font-weight: bold;">include</span><span style="color: #004400;">/</span>basedir<span style="color: #004400;">.</span>hrl<br />
<br />
static<span style="color: #004400;">/</span>nitrogen<span style="color: #004400;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ln <span style="color: #004400;">-</span>sf <span style="color: #004400;">../</span>deps<span style="color: #004400;">/</span>nitrogen_core<span style="color: #004400;">/</span>www static<span style="color: #004400;">/</span>nitrogen<br />
<br />
compile<span style="color: #004400;">:</span> <span style="color: #666622; font-weight: bold;">include</span><span style="color: #004400;">/</span>basedir<span style="color: #004400;">.</span>hrl get<span style="color: #004400;">-</span>deps<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">./</span>rebar compile<br />
<br />
clean<span style="color: #004400;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">-</span>rm <span style="color: #004400;">-</span>f static<span style="color: #004400;">/</span>nitrogen <span style="color: #666622; font-weight: bold;">include</span><span style="color: #004400;">/</span>basedir<span style="color: #004400;">.</span>hrl<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">./</span>rebar delete<span style="color: #004400;">-</span>deps<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">./</span>rebar clean<br />
<br />
distclean<span style="color: #004400;">:</span> clean<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #004400;">-</span>rm <span style="color: #004400;">-</span>rf deps ebin</div></div>
<p>I expect I&#8217;ll be tweaking this Makefile some more in the future, but it demonstrates the absolute minimum to compile the application.  When I run <tt>make</tt>, four things happen the first time:</p>
<ol>
<li><tt>BASEDIR</tt> is defined as the current directory in <tt>include/basedir.hrl</tt>.  We&#8217;ll use this later.</li>
<li>All of the Nitrogen dependencies are pulled from Git to the <tt>deps</tt> directory.</li>
<li>All of the code is compiled.</li>
<li>The static content from Nitrogen (mostly Javascript files) is symlinked into our <tt>static</tt> content directory.</li>
</ol>
<p>Next I prepare the code for running under Yaws.  First I create the Nitrogen appmod in <tt>src/test_yaws.erl</tt>:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>test_yaws<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #ff3c00;">export</span> <span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>out<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">out</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; <span style="color: #45b3e6;">RequestBridge</span> <span style="color: #014ea4;">=</span> simple_bridge:<span style="color: #ff3c00;">make_request</span><span style="color: #109ab8;">&#40;</span>yaws_request_bridge<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Arg</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; <span style="color: #45b3e6;">ResponseBridge</span> <span style="color: #014ea4;">=</span> simple_bridge:<span style="color: #ff3c00;">make_response</span><span style="color: #109ab8;">&#40;</span>yaws_response_bridge<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Arg</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; nitrogen:<span style="color: #ff3c00;">init_request</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">RequestBridge</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">ResponseBridge</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; nitrogen:<span style="color: #ff3c00;">run</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></div></div>
<p>This is taken from <a href="https://github.com/nitrogen/nitrogen/blob/master/rel/overlay/yaws/site/src/test_yaws.erl">Nitrogen repository</a>.  I also modify the <code class="codecolorer erlang default"><span class="erlang">init<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span></span></code> function in <tt>src/test_sup.erl</tt> to start the <tt>nprocreg</tt> application, similar to how it is done in <a href="https://github.com/nitrogen/nitrogen/blob/master/rel/overlay/yaws/site/src/nitrogen_sup.erl">Nitrogen proper</a>:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff3c00;">init</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; <span style="color: #ff4e18;">application</span>:<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span>nprocreg<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span> <span style="color: #109ab8;">&#123;</span>one_for_one<span style="color: #6bb810;">,</span> <span style="color: #ff9600;">5</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">10</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span> <span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></div></div>
<p>Lastly, I add a function to <tt>src/test_app.erl</tt> which can be used by Yaws to start the application:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>start<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; <span style="color: #ff4e18;">application</span>:<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span>test<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></div></div>
<p>One other thing that I do before loading the application up in Yaws is create a sample page, <tt>src/index.erl</tt>.  This is downloaded from <a href="https://github.com/nitrogen/nitrogen/blob/master/rel/overlay/common/site/src/index.erl">Nitrogen</a>:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #014ea4;">-</span><span style="color: #ff3c00;">module</span> <span style="color: #109ab8;">&#40;</span>index<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">compile</span><span style="color: #109ab8;">&#40;</span>export_all<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;nitrogen_core/include/wf.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;basedir.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">main</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> #template <span style="color: #109ab8;">&#123;</span> file<span style="color: #014ea4;">=</span>?<span style="color: #6941fd;">BASEDIR</span> <span style="color: #014ea4;">++</span> <span style="color: #ff7800;">&quot;/templates/bare.html&quot;</span> <span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">title</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff7800;">&quot;Welcome to Nitrogen&quot;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">body</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; #container_12 <span style="color: #109ab8;">&#123;</span> body<span style="color: #014ea4;">=</span><span style="color: #109ab8;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #grid_8 <span style="color: #109ab8;">&#123;</span> alpha<span style="color: #014ea4;">=</span>true<span style="color: #6bb810;">,</span> prefix<span style="color: #014ea4;">=</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> suffix<span style="color: #014ea4;">=</span><span style="color: #ff9600;">2</span><span style="color: #6bb810;">,</span> omega<span style="color: #014ea4;">=</span>true<span style="color: #6bb810;">,</span> body<span style="color: #014ea4;">=</span><span style="color: #ff3c00;">inner_body</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #109ab8;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">inner_body</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #h1 <span style="color: #109ab8;">&#123;</span> text<span style="color: #014ea4;">=</span><span style="color: #ff7800;">&quot;Welcome to Nitrogen&quot;</span> <span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #<span style="color: #d400ed;">p</span><span style="color: #109ab8;">&#123;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7800;">&quot;<br />
If you can see this page, then your Nitrogen server is up and<br />
running. Click the button below to test postbacks.<br />
&quot;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #<span style="color: #d400ed;">p</span><span style="color: #109ab8;">&#123;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #button <span style="color: #109ab8;">&#123;</span> id<span style="color: #014ea4;">=</span>button<span style="color: #6bb810;">,</span> text<span style="color: #014ea4;">=</span><span style="color: #ff7800;">&quot;Click me!&quot;</span><span style="color: #6bb810;">,</span> postback<span style="color: #014ea4;">=</span>click <span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; #<span style="color: #d400ed;">p</span><span style="color: #109ab8;">&#123;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7800;">&quot;<br />
Run &lt;b&gt;./bin/dev help&lt;/b&gt; to see some useful developer commands.<br />
&quot;</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">event</span><span style="color: #109ab8;">&#40;</span>click<span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; <span style="color: #006600;">wf</span>:<span style="color: #ff3c00;">replace</span><span style="color: #109ab8;">&#40;</span>button<span style="color: #6bb810;">,</span> #panel <span style="color: #109ab8;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; body<span style="color: #014ea4;">=</span><span style="color: #ff7800;">&quot;You clicked the button!&quot;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; actions<span style="color: #014ea4;">=</span>#effect <span style="color: #109ab8;">&#123;</span> effect<span style="color: #014ea4;">=</span>highlight <span style="color: #109ab8;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></div></div>
<p>I make sure to include <tt>basedir.hrl</tt> (generated by the Makefile, remember?) and modify the template path to start with <code class="codecolorer erlang default"><span class="erlang">?<span style="color: #6941fd;">BASEDIR</span></span></code>.  Since where Yaws is running is out of our control, we must reference files by absolute pathnames.  Speaking of templates, I downloaded mine from the <a href="https://github.com/nitrogen/nitrogen/blob/master/rel/overlay/common/site/templates/bare.html">Nitrogen repository</a>.  Obviously, it can be modified however you want or you could create one from scratch.</p>
<p>Before we continue, I recompile everything by typing <tt>make</tt>.</p>
<p>Now the fun begins: wiring it all up in Yaws.  I use <a href="http://pkg.thestaticvoid.com/en/search.shtml?token=yaws&#038;action=Search">my package</a> for OpenSolaris which puts the configuration file in <tt>/etc/yaws/yaws.conf</tt>.  I add the following to it:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ebin_dir = /docs/test/deps/nitrogen_core/ebin<br />
ebin_dir = /docs/test/deps/nprocreg/ebin<br />
ebin_dir = /docs/test/deps/simple_bridge/ebin<br />
ebin_dir = /docs/test/deps/sync/ebin<br />
ebin_dir = /docs/test/ebin<br />
<br />
runmod = test_app<br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> test.thestaticvoid.com<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; port = 80<br />
&nbsp; &nbsp; listen = 0.0.0.0<br />
&nbsp; &nbsp; docroot = /docs/test/static<br />
&nbsp; &nbsp; appmods = <span style="color: #009900;">&lt;/, test_yaws<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/server<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>Obviously, your paths will probably be different.  The point is to tell Yaws where all of the compiled code is, tell it to start your application (where the business logic will be contained), and tell it to use the Nitrogen appmod.  Restart Yaws and it should all be working!</p>
<p>Now for some cool stuff.  If you run the <tt>svc:/network/http:yaws</tt> service from my package, or you start Yaws like <tt>yaws --run_erl svc</tt>, you can run <tt>yaws --to_erl svc</tt> (easiest to do with root privileges) and get access to Yaws&#8217;s Erlang console.  From here you can hot-reload code.  For example, modify the title in <tt>index.erl</tt> and recompile by running <tt>make</tt>.  In the Erlang console, you can run <code class="codecolorer erlang default"><span class="erlang"><span style="color: #ff3c00;">l</span><span style="color: #109ab8;">&#40;</span>index<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></span></code> and it will pick up your changes.  But there is something even cooler.  From the Erlang console, type <code class="codecolorer erlang default"><span class="erlang">syn<span style="color: #ff4e18;">c</span>:<span style="color: #ff3c00;">go</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></span></code> and now whenever you make a change to a loaded module&#8217;s source code, it will automatically be recompiled and loaded, almost instantly!  It looks something like:</p>
<pre class="terminal">
# <kbd>yaws --to_erl svc</kbd>
Attaching to /var//run/yaws/pipe/svc/erlang.pipe.1 (^D to exit)

1> <kbd>sync:go().</kbd>
Starting Sync (Automatic Code Reloader)
ok
2>
=INFO REPORT==== 17-Feb-2011::15:03:10 ===
/docs/test/src/index.erl:0: Recompiled. (Reason: Source modified.)

=INFO REPORT==== 17-Feb-2011::15:04:20 ===
/docs/test/src/index.erl:11: Error: syntax error before: body

=INFO REPORT==== 17-Feb-2011::15:04:26 ===
/docs/test/src/index.erl:0: Fixed!

2> <kbd>sync:stop().</kbd>

=INFO REPORT==== 17-Feb-2011::15:07:17 ===
    application: sync
    exited: stopped
    type: temporary
ok
</pre>
<p>One gotcha that may or may not apply to you, is that Yaws should have permission to write to your application&#8217;s <tt>ebin</tt> directory if you want to save the automatically compiled code.  In my case, Yaws runs as a different user than I develop as, a practice that I would highly recommend.  So I use a ZFS ACL to allow the web server user read and write access:</p>
<pre class="terminal">
$ <kbd>/usr/bin/chmod -R A+user:webservd:rw:f:allow /docs/test/ebin</kbd>
$ <kbd>/usr/bin/ls -dv /docs/test/ebin</kbd>
drwxr-xr-x+  2 jlee     staff          8 Feb 17 15:04 /docs/test/ebin
     0:user:webservd:read_data/write_data:file_inherit:allow
     1:owner@::deny
     2:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     3:group@:add_file/write_data/add_subdirectory/append_data:deny
     4:group@:list_directory/read_data/execute:allow
     5:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     6:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow
</pre>
<p>ACLs are pretty scary to some people, but I love &#8216;em <img src='http://thestaticvoid.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4>Other Thoughts</h4>
<p>You would not be able to run multiple Nitrogen projects on separate virtual hosts using this scheme.  Nitrogen maps request paths to module names (for example, requesting &#8220;/admin/login&#8221; would load a module <tt>admin_login</tt>) and module names must be unique in Erlang.  I think it would be possible to work around this using a Yaws <a href="http://thestaticvoid.com/post/2009/08/04/replacing-apache-with-yaws/#trac-rewrite">rewrite module</a>, though I haven&#8217;t tested it.  I imagine if one virtual host maps &#8220;/admin/login&#8221; to &#8220;/foo/admin/login&#8221; and another maps it to &#8220;/bar/admin/login&#8221;, then Nitrogen would search for <tt>foo_admin_login</tt> and <tt>bar_admin_login</tt>, respectively, eliminating the conflicting namespace problem.</p>
<p>Now that I&#8217;ve gone through all the trouble of setting up Nitrogen the way I like, I should start converting my application over.  Hopefully I&#8217;ll like it.  It would be a shame to have done all this work for naught.  I&#8217;m sure there will be posts to follow.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2011/02/17/using-nitrogen-as-a-library-under-yaws/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Replacing Apache with Yaws</title>
		<link>http://thestaticvoid.com/post/2009/08/04/replacing-apache-with-yaws/</link>
		<comments>http://thestaticvoid.com/post/2009/08/04/replacing-apache-with-yaws/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 02:35:25 +0000</pubDate>
		<dc:creator>James Lee</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[cgi]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[trac]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[yaws]]></category>

		<guid isPermaLink="false">http://thestaticvoid.com/?p=139</guid>
		<description><![CDATA[After some time running with the Apache worker model, I noticed it was not much better on memory than prefork. It would spawn new threads as load increased, but didn&#8217;t give up the resources when load decreased. I know it does this for performance, but I am very tight on memory. And I know Apache [...]]]></description>
			<content:encoded><![CDATA[<p>After some time running with the Apache <a href="http://thestaticvoid.com/post/2009/07/27/reducing-memory-footprint-of-apache-services/">worker</a> model, I noticed it was not much better on memory than prefork.  It would spawn new threads as load increased, but didn&#8217;t give up the resources when load decreased.  I know it does this for performance, but I am very tight on memory.  And I know Apache is very tunable, so I could probably change that behavior, but tuning is boring.  Playing with new stuff is fun!  This was the perfect opportunity for me to look at lightweight web servers.</p>
<p>I toyed around with <a href="http://www.lighttpd.net/">lighttpd</a> and read the documentation for <a href="http://nginx.net/">nginx</a>.  Both seem to do what I need them to do, but I was more interested in the equally fast and light <a href="http://yaws.hyber.org/">Yaws</a>.  I&#8217;ve been really into <a href="http://en.wikipedia.org/wiki/Erlang_(programming_language)">Erlang</a> lately (more on that in another post), so this was a great opportunity to see how a real Erlang application works.</p>
<h3>Installation</h3>
<p>Naturally, Yaws isn&#8217;t included in OpenSolaris yet, but Erlang is!  So it was fairly easy to whip together a <a href="https://github.com/MrStaticVoid/specs/blob/master/yaws.spec">spec file</a> and <a href="https://github.com/MrStaticVoid/specs/blob/master/ext-sources/http-yaws.xml">SMF manifest</a> for the program.  Then it was as easy as:</p>
<pre class="terminal">
$ <kbd>pkgtool build-only --download --interactive yaws.spec</kbd>
$ <kbd>pfexec pkg install yaws</kbd>
</pre>
<p>I&#8217;ve set the configuration to go to <tt>/etc/yaws/yaws.conf</tt> and the service can be started with <tt>svcadm enable yaws</tt>.  When I&#8217;m completely satisfied with the package, I&#8217;ll upload it to <a href="http://jucr.opensolaris.org/">SourceJuicer</a>.</p>
<h3>Configuration</h3>
<p>I run two virtual hosts: thestaticvoid.com and iriverter.thestaticvoid.com.  Those two domains also have &#8220;.org&#8221; counterparts which I want to redirect to the &#8220;.com&#8221; domain.  The <tt>yaws.conf</tt> syntax to handle this case is very simple:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">pick_first_virthost_on_nomatch = true<br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> localhost<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; port = 80<br />
&nbsp; &nbsp; &nbsp; &nbsp; listen = 0.0.0.0<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;redirect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / = thestaticvoid.com<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/redirect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/server<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> thestaticvoid.com<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; port = 80<br />
&nbsp; &nbsp; &nbsp; &nbsp; listen = 0.0.0.0<br />
&nbsp; &nbsp; &nbsp; &nbsp; docroot = /docs/thestaticvoid.com<br />
&nbsp; &nbsp; &nbsp; &nbsp; dir_listings = true<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/server<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> iriverter.thestaticvoid.com<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; port = 80<br />
&nbsp; &nbsp; &nbsp; &nbsp; listen = 0.0.0.0<br />
&nbsp; &nbsp; &nbsp; &nbsp; docroot = /docs/iriverter.thestaticvoid.com<br />
&nbsp; &nbsp; &nbsp; &nbsp; dir_listings = true<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/server<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> iriverter.thestaticvoid.org<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; port = 80<br />
&nbsp; &nbsp; &nbsp; &nbsp; listen = 0.0.0.0<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;redirect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / = iriverter.thestaticvoid.com<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/redirect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/server<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>Should be pretty self-explanatory, but the nice thing is the <tt>pick_first_virthost_on_nomatch</tt> directive combined with the localhost block so that if anyone gets to this site by any other address, they&#8217;ll be redirected to the canonical thestaticvoid.com.  I did actually run into a bug with the redirection putting extra slashes in the URL, but squashed that bug pretty quickly with a bit of help from the Yaws mailing list.  That whole problem is summarized in <a href="http://thread.gmane.org/gmane.comp.web.server.yaws.general/2188">this thread</a>.</p>
<h4>PHP</h4>
<p>Yaws handles PHP execution as a special case.  All you have to do is add a couple lines to the configuration above:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">php_exe_path = /usr/php/bin/php-cgi<br />
<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;server</span> thestaticvoid.com<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ...<br />
&nbsp; &nbsp; &nbsp; &nbsp; allowed_scripts = php<br />
&nbsp; &nbsp; &nbsp; &nbsp; ...<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/server<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>Reload the server (<tt>svcadm refresh yaws</tt>) and PHP, well, won&#8217;t work just yet.  This actually took me an hour or two to figure out.  OpenSolaris&#8217; PHP is compiled with the <tt>--enable-force-cgi-redirect</tt> option which means PHP will refuse to execute unless it was invoked by an Apache <tt>Action</tt> directive.  Fortunately, you can disable this security measure by setting <tt>cgi.force_redirect = 0</tt> in your <tt>/etc/php/5.2/php.ini</tt>.</p>
<h4>Trac</h4>
<p>Trac needs a little work to get running in Yaws.  It&#8217;s requires an environmental variable, <tt>TRAC_ENV</tt>, set to tell it where to find the project database.  The easiest way to do that is to copy <tt>/usr/share/trac/cgi-bin/trac.cgi</tt> to the document root, modify it to set the environmental variable, and enable CGI scripts in Yaws by setting <tt>allowed_scripts = cgi</tt>.</p>
<p>But I decided to set up an appmod, so that <tt>trac.cgi</tt> could be left where it was, unmodified.  Appmods are Erlang modules which get run by Yaws whenever the configured URL is requested.  Here&#8217;s the one I wrote for Trac:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>trac<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>out<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">APPMOD</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/trac&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">TRAC_ENV</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/trac/iriverter&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">SCRIPT</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/usr/share/trac/cgi-bin/trac.cgi&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;yaws/include/yaws_api.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">out</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Pathinfo</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>pathinfo<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Env</span> <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #ff7800;">&quot;SCRIPT_NAME&quot;</span><span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">APPMOD</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #ff7800;">&quot;TRAC_ENV&quot;</span><span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">TRAC_ENV</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; yaws_cg<span style="color: #ff4e18;">i</span>:<span style="color: #ff3c00;">call_cgi</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #6bb810;">,</span> undefined<span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">SCRIPT</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pathinfo</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Env</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></div></div>
<p>All appmods must define the out/1 function which takes an <tt>arg</tt> record which contains information about the current request.  At the end of the function, the Yaws API is used to execute the CGI script with the extra environmental variables.  This is compiled (<tt>erlc -o /var/yaws/ebin -I/usr/lib trac.erl</tt>) and enabled in the Yaws configuration by adding <tt>appmods = &lt;/trac, trac&gt;</tt> to a <tt>server</tt> section.  Then whenever someone requests <tt>/trac/foo/bar</tt>, Trac runs properly!</p>
<p><a name="trac-rewrite"></a></p>
<p>I also set up URL rewriting so that instead of requesting something like <tt>http://i.tsv.c/trac/wiki</tt>, all you see is <tt>http://i.tsv.c/wiki</tt>.  This involves another Erlang module, a rewrite module.  It looks like:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>rewrite_trac<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>arg_rewrite<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;yaws/include/yaws_api.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">arg_rewrite</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Req</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>req<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">abs</span>_path<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Req</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">http_request</span><span style="color: #6bb810;">.</span>path<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">try</span> yaws_ap<span style="color: #ff4e18;">i</span>:<span style="color: #ff3c00;">url_decode_q_split</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">DecPath</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Query</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">case</span> <span style="color: #45b3e6;">DecPath</span> <span style="color: #014ea4;">==</span> <span style="color: #ff7800;">&quot;/&quot;</span> <span style="color: #186895;">orelse</span> <span style="color: #014ea4;">not</span> <span style="color: #ff4e18;">filelib</span>:<span style="color: #ff3c00;">is_file</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>docroot <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">DecPath</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; true <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #109ab8;">&#123;</span>req <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Req</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">http_request</span><span style="color: #109ab8;">&#123;</span>path <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">abs</span>_path<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/trac&quot;</span> <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; false <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">catch</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #fa6fff;">exit</span>:_ <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></div></div>
<p>This module runs as soon as a request comes into the server and allows you to modify many variables before the request is handled.  This is a simple one which says: if the request is &#8220;/&#8221; or the requested file doesn&#8217;t exist, append the request to the Trac appmod, otherwise pass it through unaltered.  It&#8217;s enabled in the Yaws server by adding <tt>	arg_rewrite_mod = rewrite_trac</tt> to <tt>yaws.conf</tt>.  The Trac appmod must also be modified to make sure <tt>SCRIPT_NAME</tt> is now </tt>/</tt> so the application generates links without containing <tt>/trac</tt>.</p>
<h4>WordPress</h4>
<p>WordPress works perfectly once PHP is enabled in Yaws.  WordPress permalinks, however, do not.  A little background:  WordPress normally relies on Apache's mod_rewrite to execute <tt>index.php</tt> when it gets an request like <tt>/post/2009/07/27/suexec-on-opensolaris/</tt>.  mod_rewrite sets up the environmental variables such that WordPress is able to detect how it was called and can process the page accordingly.</p>
<p>Without mod_rewrite, the best it can do is rely on requests like <tt>/index.php/post/2009/07/27/suexec-on-opensolaris/</tt> and use the <tt>PATH_INFO</tt> variable, which is the text after <tt>index.php</tt>.  I think that looks ugly, having <tt>index.php</tt> in every URL.  You would think that simply rewriting the URL, just as was done with Trac, would solve the problem, but WordPress is too smart, and always sends you to a canonical URL which it thinks must include <tt>index.php</tt>.</p>
<p>After more experimentation than I care to explain, I discovered that if I set the <tt>REQUEST_URI</tt> variable to the original request (the one not including <tt>index.php</tt>), WordPress was happy.  This was a tricky exercise in trying to set an environmental variable from the rewrite module.  But, as we saw with the Trac example, environmental variables can be set from appmods.  And I found that data can be passed from the rewrite module to the appmod through the <tt>arg</tt> record!  Here's my solution:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>rewrite_blog<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>arg_rewrite<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;yaws/include/yaws_api.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">arg_rewrite</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Req</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>req<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">abs</span>_path<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Req</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">http_request</span><span style="color: #6bb810;">.</span>path<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">try</span> yaws_ap<span style="color: #ff4e18;">i</span>:<span style="color: #ff3c00;">url_decode_q_split</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">DecPath</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Query</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">case</span> <span style="color: #45b3e6;">DecPath</span> <span style="color: #014ea4;">==</span> <span style="color: #ff7800;">&quot;/&quot;</span> <span style="color: #186895;">orelse</span> <span style="color: #014ea4;">not</span> <span style="color: #ff4e18;">filelib</span>:<span style="color: #ff3c00;">is_file</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>docroot <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">DecPath</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; true <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">case</span> <span style="color: #ff4e18;">string</span>:<span style="color: #ff3c00;">str</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/wsvn&quot;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #014ea4;">==</span> <span style="color: #ff9600;">1</span> <span style="color: #186895;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; true <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewPath</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_RepCount</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">regexp</span>:<span style="color: #ff3c00;">sub</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;^/wsvn(<span style="color: #000099; font-weight: bold;">\.</span>php)?&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/wsvn.php&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #109ab8;">&#123;</span>req <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Req</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">http_request</span><span style="color: #109ab8;">&#123;</span>path <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">abs</span>_path<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewPath</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; false <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #109ab8;">&#123;</span>opaque <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #ff7800;">&quot;REQUEST_URI&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Req</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">http_request</span><span style="color: #109ab8;">&#123;</span>path <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#123;</span><span style="color: #fa6fff;">abs</span>_path<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/blog&quot;</span> <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">end</span><span style="color: #6bb810;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; false <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">catch</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #fa6fff;">exit</span>:_ <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Arg</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></div></div>
<p>Nevermind the extra <a href="http://thestaticvoid.com/wsvn/">WebSVN</a> rewriting code.  Notice I set the <tt>opaque</tt> component of the <tt>arg</tt>.  Then in the appmod:</p>
<div class="codecolorer-container erlang default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="erlang codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>blog<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>out<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">SCRIPT</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;/docs/thestaticvoid.com/wordpress/index.php&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;yaws/include/yaws.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;yaws/include/yaws_api.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span><br />
<br />
<span style="color: #ff3c00;">out</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Pathinfo</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>pathinfo<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #45b3e6;">Env</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Arg</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>opaque<span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">GC</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Groups</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> yaws_ap<span style="color: #ff4e18;">i</span>:<span style="color: #fa6fff;">get</span><span style="color: #ff3c00;">conf</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; yaws_cg<span style="color: #ff4e18;">i</span>:<span style="color: #ff3c00;">call_cgi</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Arg</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">GC</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">gconf</span><span style="color: #6bb810;">.</span>phpexe<span style="color: #6bb810;">,</span> ?<span style="color: #6941fd;">SCRIPT</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Pathinfo</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Env</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></div></div>
<p>I pull the data from the <tt>arg</tt> record and pass it to the <tt>call_cgi/5</tt> function.  Also of note here is the special way to invoke the PHP CGI.  The location of the <tt>php-cgi</tt> executable is pulled from the Yaws configuration and passed as the second argument to <tt>call_cgi/5</tt> so Yaws knows what to do with the files.  You can surely imagine this as a way to execute things other than PHP which do not have a <tt>#!</tt> at the top.  Or emulating suEXEC with a custom wrapper <img src='http://thestaticvoid.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Overall, this probably seems like a lot of work to get things working that are trivial in other servers, but I'm finding that the appmods are really powerful, and the Yaws code itself is very easy to understand and modify.  Plus you get the legendary performance and fault-tolerance of Erlang.</p>
]]></content:encoded>
			<wfw:commentRss>http://thestaticvoid.com/post/2009/08/04/replacing-apache-with-yaws/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

