<?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>BLARGH!! for the people &#187; apache</title>
	<atom:link href="http://blargh.tommymontgomery.com/category/apache/feed/" rel="self" type="application/rss+xml" />
	<link>http://blargh.tommymontgomery.com</link>
	<description>It&#039;s time to bring forth the rhythm and the rhyme</description>
	<lastBuildDate>Fri, 09 Jul 2010 04:03:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Subversion, Apache, nginx and &#8220;Entity Too Large&#8221;</title>
		<link>http://blargh.tommymontgomery.com/2010/05/subversion-apache-nginx-and-entity-too-large/</link>
		<comments>http://blargh.tommymontgomery.com/2010/05/subversion-apache-nginx-and-entity-too-large/#comments</comments>
		<pubDate>Wed, 05 May 2010 04:00:48 +0000</pubDate>
		<dc:creator>tmont</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://blargh.tommymontgomery.com/?p=502</guid>
		<description><![CDATA[tl;dr: add client_max_body_size 10m; to your nginx vhost.
This one took me a while to track down. My brother uses my subversion repository, and he was trying to commit a 1MB flash file. The TortoiseSVN error he got back was: 

This was a bit perplexing. I figured it was some sort of mod_dav setting I had [...]]]></description>
			<content:encoded><![CDATA[<p><strong>tl;dr: add <kbd>client_max_body_size 10m;</kbd> to your nginx vhost.</strong></p>
<p>This one took me a while to track down. <a href="http://bob.tmont.com/">My brother</a> uses my subversion repository, and he was trying to commit a 1MB flash file. The TortoiseSVN error he got back was: </p>
<p><img src="http://blargh.tommymontgomery.com/wp-content/uploads/2010/05/CommitError.png" alt="" title="CommitError" width="659" height="301" class="aligncenter size-full wp-image-503" /></p>
<p>This was a bit perplexing. I figured it was some sort of <kbd>mod_dav</kbd> setting I had never encountered, so I turned to Google. Google spouted a bunch of stuff about where to put your SSL directives in your Apache configuration, some stuff about Apache not handling the <kbd>Content-Length</kbd> header correctly, some promising mailing list threads about using the <kbd>LimitXMLRequestBody</kbd> <kbd>mod_dav</kbd> directive, and a bunch of stuff about some idiots trying to commit 4GB files to a subversion server running on Windows.</p>
<p>None of these were my problem.</p>
<p>It turns out I needed to add another keyword to my search. After I searched for <em>svn apache <strong>nginx</strong> &#8220;entity too large&#8221;</em>, the <a href="http://digita.la/2009/2/12/nginx-subversion-and-413-s">first hit</a> took me home. Like everyone else who is awesome, I&#8217;m using nginx as a proxy to Apache running <kbd>mod_dav</kbd>. nginx&#8217;s configuration was getting hit first, and Apache and Subversion had nothing to do with anything.</p>
<p>It turns out the default maximum request body size for nginx is 1MB, exactly the size my brother was trying commit to the repository. Adding this one line in my virtual host solved it all:</p>
<pre class="brush: plain; highlight: [5];">
server {
    listen 80;
    server_name svn.tommymontgomery.com;

    client_max_body_size 10m;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://svn.tommymontgomery.com:8080;
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blargh.tommymontgomery.com/2010/05/subversion-apache-nginx-and-entity-too-large/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Conditional gzipping with Apache</title>
		<link>http://blargh.tommymontgomery.com/2009/08/conditional-gzipping-with-apache/</link>
		<comments>http://blargh.tommymontgomery.com/2009/08/conditional-gzipping-with-apache/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 21:41:53 +0000</pubDate>
		<dc:creator>tmont</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://blargh.tommymontgomery.com/?p=123</guid>
		<description><![CDATA[I&#8217;ve never really experimented with some of the more low-level website optimizations (server side stuff, like gzipping, caching and the like), mostly because I&#8217;ve never really had to. I&#8217;m not a server admin, and my sites don&#8217;t generate enough traffic for me to really care about such minor issues. But then I released two little [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve never really experimented with some of the more low-level website optimizations (server side stuff, like gzipping, caching and the like), mostly because I&#8217;ve never really had to. I&#8217;m not a server admin, and my sites don&#8217;t generate enough traffic for me to really care about such minor issues. But then I released two <a href="http://acronymulator.com/">little</a> <a href="http://linkurious.com/">utilities</a> wherein users could just include a piece of JavaScript from my own server. You know, they would so something like this:</p>
<pre class="brush: xml;">
&lt;script type=&quot;text/javascript&quot; src=&quot;http://linkurious.com/js&quot;&gt;&lt;/script&gt;
</pre>
<p>where the <kbd>src</kbd> attribute was pointing to an external server; namely, <strong>my</strong> server. If enough people start using these utilities (extremely unlikely, although they are pretty awesome) it could be a strain on my server.</p>
<p>So I decided to offer a plain text version and a gzipped version. But I didn&#8217;t want to store two versions of the scripts in separate places on my server just to satisfy that need. The reasons had nothing to do with disk space or anything tangible; I just didn&#8217;t &#8220;feel right&#8221; doing something so hackish. Damn this ego of mine!</p>
<p>Anyway, once I figured out how to use <a href="http://httpd.apache.org/docs/2.2/mod/mod_deflate.html"><kbd>mod_deflate</kbd></a>:</p>
<pre class="brush: plain;">
#DER!
SetOutputFilter DEFLATE
</pre>
<p>I realized that that would make <strong>everything</strong> gzipped! OH NOES!! But then I noticed you could filter the&#8230; er&#8230; filter by mimetype, like so:</p>
<pre class="brush: plain;">
#only text/html will be gzipped
AddOutputFilterByType DEFLATE text/html
</pre>
<p>But that still didn&#8217;t help me. I needed <em>conditional</em> gzipping, like if the query string said <kbd>?gz</kbd> it would know to serve the document gzipped; otherwise, it would just serve it with no compression. But how to accomplish this? Apache&#8217;s docs were no help. Luckily I&#8217;m fairly proficient at <a href="http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html"><kbd>mod_rewrite</kbd></a>, and I&#8217;m decently intelligent. Let&#8217;s see if I can figure it out (<strong>SPOILER</strong>: I figured it out; this 1st person past-tense non-omniscient narrative is just a literary technique).</p>
<p>Here were my requirements:</p>
<ol>
<li>A request to <tt>http://acronymulator.com/1</tt> would serve the JavaScript document with no compression</li>
<li>A request to <tt>http://acronymulator.com/1/gz</tt> would serve the JavaScript document with gzip compression</li>
<li>Only one physical copy of the document exists on the server</li>
</ol>
<p>Let&#8217;s get to work!</p>
<p>First, let&#8217;s do the rewrite rules:</p>
<pre class="brush: plain;">
RewriteEngine On
RewriteRule ^/([1-9]\d*)(?:/gz)? /acronymulates/$1.js
</pre>
<p>The first line turns on the rewrite engine. The second line matches anything from the root that is made up of numbers, at least one number long where the first number is not a zero, with an optional <tt>/gz</tt> on the end. The rule finishes by internally redirecting those to the acronymulates directory, and serves up the JavaScript file whose name is the number with <tt>.js</tt> at the end. Simple enough, right? Sure.</p>
<p>Hopefully, you&#8217;ve deduced that <tt>/gz</tt> indicates that we want gzip compression; if it&#8217;s omitted, we don&#8217;t want gzip compression. Notice that it&#8217;s redirecting to the real JavaScript file whether the <tt>/gz</tt> is tacked on the end or not.</p>
<p>Now we need to do the deflate stuff. How we do it? Well, the most obvious solution is something like this:</p>
<pre class="brush: plain;">
&lt;Directory /path/to/acronymulates&gt;
    SetOutputFilter DEFLATE
&lt;/Directory&gt;
</pre>
<p>This makes sense because the only thing in the acronymulates directory is the JavaScript files that we want to compress. See?</p>
<div id="attachment_137" class="wp-caption aligncenter" style="width: 608px"><img src="http://blargh.tommymontgomery.com/wp-content/uploads/2009/08/dynamic_gzipping_acronymulates.png" alt="The files inside the acronymulates directory" title="dynamic_gzipping_acronymulates" width="598" height="117" class="size-full wp-image-137" /><p class="wp-caption-text">The files inside the acronymulates directory</p></div>
<p>However, this will force gzip compression no matter what, and we want it be <strong>conditional</strong>: only when the <tt>/gz</tt> is part of the URL. What do we do?</p>
<p><strong>Location to the rescue!</strong></p>
<p>The <a href="http://httpd.apache.org/docs/2.2/mod/core.html#location">Location</a> directive accomplishes this for us. more specifically, the LocationMatch directive accomplishes this for us. The difference between Directory and Location is that Directory matches a physical directory on the filesystem, whereas Location just matches a virtual directory (i.e. the path of the URL: /1/gz, in our case). Now it&#8217;s fairly obvious what the solution should be:</p>
<pre class="brush: plain;">
&lt;LocationMatch /[1-9]\d*/gz&gt;
    SetOutputFilter DEFLATE
&lt;/LocationMatch&gt;
</pre>
<p>And there&#8217;s your dynamic gzipping using Apache. Note that these are real life examples (IRL ZOMG). Let&#8217;s prove it with Firebug&#8217;s help.</p>
<p>Without compression (<a href="http://acronymulator.com/1">http://acronymulator.com/1</a>:</p>
<div id="attachment_142" class="wp-caption aligncenter" style="width: 467px"><img src="http://blargh.tommymontgomery.com/wp-content/uploads/2009/08/dynamic_gzipping_11.png" alt="Dynamic gzipping: without compression" title="dynamic_gzipping_1" width="457" height="246" class="size-full wp-image-142" /><p class="wp-caption-text">Dynamic gzipping: without compression</p></div>
<p>Without compression (<a href="http://acronymulator.com/1/gz">http://acronymulator.com/1/gz</a>:</p>
<div id="attachment_143" class="wp-caption aligncenter" style="width: 467px"><img src="http://blargh.tommymontgomery.com/wp-content/uploads/2009/08/dynamic_gzipping_1_gz1.png" alt="Dynamic gzipping: with compression" title="dynamic_gzipping_1_gz" width="457" height="303" class="size-full wp-image-143" /><p class="wp-caption-text">Dynamic gzipping: with compression</p></div>
<p>And here&#8217;s proof that both URLs serve the same content:<br />
<div id="attachment_138" class="wp-caption aligncenter" style="width: 526px"><img src="http://blargh.tommymontgomery.com/wp-content/uploads/2009/08/dynamic_gzipping_md5sum.png" alt="Proof that both URLs serve the same content" title="dynamic_gzipping_md5sum" width="516" height="90" class="size-full wp-image-138" /><p class="wp-caption-text">Proof that both URLs serve the same content</p></div></p>
]]></content:encoded>
			<wfw:commentRss>http://blargh.tommymontgomery.com/2009/08/conditional-gzipping-with-apache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
