<?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>Racker Hacker &#187; mod_rewrite</title>
	<atom:link href="http://rackerhacker.com/tag/mod_rewrite/feed/" rel="self" type="application/rss+xml" />
	<link>http://rackerhacker.com</link>
	<description>Words of wisdom from a server administrator</description>
	<lastBuildDate>Tue, 07 Feb 2012 14:07:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Create a local PyPi repository using only mod_rewrite</title>
		<link>http://rackerhacker.com/2012/01/31/create-a-local-pypi-repository-using-only-mod_rewrite/</link>
		<comments>http://rackerhacker.com/2012/01/31/create-a-local-pypi-repository-using-only-mod_rewrite/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 04:02:49 +0000</pubDate>
		<dc:creator>Major Hayden</dc:creator>
				<category><![CDATA[Blog Posts]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://rackerhacker.com/?p=2861</guid>
		<description><![CDATA[Regular users of Python's package tools like pip or easy_install are probably familiar with the PyPi repository. It's a one-stop-shop to learn more about available Python packages and get them installed on your server. However, certain folks may find the need to host a local PyPi repository for their own packages. You may need it [...]<p><a href="http://rackerhacker.com/2012/01/31/create-a-local-pypi-repository-using-only-mod_rewrite/">Create a local PyPi repository using only mod_rewrite</a> is a post from: Major Hayden's <a href="http://rackerhacker.com">Racker Hacker</a> blog. 
<p>Thanks for following the blog via the RSS feed. Please don't copy my posts or quote portions of them without attribution.</p></p>
]]></description>
			<content:encoded><![CDATA[<p>Regular users of Python's package tools like <a href="http://pypi.python.org/pypi/pip">pip</a> or <a href="http://pypi.python.org/pypi/setuptools">easy_install</a> are probably familiar with the <a href="http://pypi.python.org/pypi">PyPi</a> repository.  It's a one-stop-shop to learn more about available Python packages and get them installed on your server.</p>
<p>However, certain folks may find the need to host a local PyPi repository for their own packages.  You may need it to store Python code which you don't plan to release publicly or you may need to add proprietary patches to upstream Python packages.  Regardless of the reason to have it, a local PyPi repository is relatively easy to configure.</p>
<p>You'll need to start with a base directory for your PyPi repository.  For this example, I chose <code>/var/pypi</code>.  The directory structure should look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">/var/pypi/simple/[package_name]/[package_tarball]</pre></div></div>

<p>For a package like <code>pip</code>, you'd make a structure like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">/var/pypi/simple/pip/pip-1.0.2.tar.gz</pre></div></div>

<p>Once you have at least one package stored locally, it's time to configure apache.  Here's a snippet from the virtual host I configured:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">DocumentRoot /var/pypi/
ServerName pypi.example.com
&nbsp;
Options +Indexes
&nbsp;
RewriteEngine On
RewriteRule ^/robots.txt - [L]
RewriteRule ^/icons/.* - [L]
RewriteRule ^/index\..* - [L]
&nbsp;
RewriteCond /var/pypi/$1 !-f
RewriteCond /var/pypi/$1 !-d
RewriteRule ^/(.*)/?$ http://pypi.python.org/$1 [R,L]</pre></div></div>

<p>The last set of rewrite directives check to see if the request refers to an existing file or directory under your document root.  If it does, your server will reply with a directory listing or with the actual file to download.  If the directory or file doesn't exist, apache will send the client a redirection to the main PyPi site.</p>
<p>Reload your apache configuration to bring in your new changes.  Let's try to download the <code>pip</code> tarball from our local server in the example I mentioned above:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">$ curl -I http://pypi.example.com/simple/pip/
HTTP/1.1 200 OK
&nbsp;
$ curl -I http://pypi.example.com/simple/pip/pip-1.0.2.tar.gz
HTTP/1.1 200 OK</pre></div></div>

<p>I've obviously snipped a bit of the response above, but you can see that apache is responding with 200's since it has the directories and files that I was trying to retrieve via curl.  Let's try to get something we don't have locally, like <code>kombu</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">$ curl -I http://pypi.example.com/simple/kombu/
HTTP/1.1 302 Found
Location: http://pypi.python.org/simple/kombu/</pre></div></div>

<p>Our local PyPi repository doesn't have <code>kombu</code> so it will refer our Python tools over to the official PyPi repository to get the listing of available package versions for <code>kombu</code>.</p>
<p>Now we need to tell <code>pip</code> to use our local repository.  Edit <code>~/.pip/pip.conf</code> and add:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">[global]
index-url = http://pypi.example.com/simple/</pre></div></div>

<p>If you'd rather use <code>easy_install</code>, edit <code>~/.pydistutils.cfg</code> and add:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">[easy_install]
index_url = http://pypi.example.com/simple/</pre></div></div>

<p>Once your tools are configured, try installing a package you have locally and try to install one that you know you won't have locally.  You can add <code>-v</code> to <code>pip install</code> to watch it retrieve different URL's to get the packages it needs.  If you spot any peculiar behavior or unexpected redirections, double-check your mod_rewrite rules in your apache configuration and check the spelling of your directories under your document root.</p>
<p><a href="http://rackerhacker.com/2012/01/31/create-a-local-pypi-repository-using-only-mod_rewrite/">Create a local PyPi repository using only mod_rewrite</a> is a post from: Major Hayden's <a href="http://rackerhacker.com">Racker Hacker</a> blog. 
<p>Thanks for following the blog via the RSS feed. Please don't copy my posts or quote portions of them without attribution.</p></p>
]]></content:encoded>
			<wfw:commentRss>http://rackerhacker.com/2012/01/31/create-a-local-pypi-repository-using-only-mod_rewrite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Throwing thoughtful &quot;403 Forbidden&quot; responses with apache</title>
		<link>http://rackerhacker.com/2010/11/17/throwing-thoughtful-403-forbidden-responses-with-apache/</link>
		<comments>http://rackerhacker.com/2010/11/17/throwing-thoughtful-403-forbidden-responses-with-apache/#comments</comments>
		<pubDate>Wed, 17 Nov 2010 13:47:19 +0000</pubDate>
		<dc:creator>Major Hayden</dc:creator>
				<category><![CDATA[Blog Posts]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://rackerhacker.com/?p=1936</guid>
		<description><![CDATA[If you offer a web service that users query via scripts or other applications, you'll probably find that some people will begin to abuse the service. My icanhazip.com site is no exception. While many of the users have reasonable usage patterns, there are some users that query the site more than once per second from [...]<p><a href="http://rackerhacker.com/2010/11/17/throwing-thoughtful-403-forbidden-responses-with-apache/">Throwing thoughtful "403 Forbidden" responses with apache</a> is a post from: Major Hayden's <a href="http://rackerhacker.com">Racker Hacker</a> blog. 
<p>Thanks for following the blog via the RSS feed. Please don't copy my posts or quote portions of them without attribution.</p></p>
]]></description>
			<content:encoded><![CDATA[<p>If you offer a web service that users query via scripts or other applications, you'll probably find that some people will begin to abuse the service.  My <a href="http://icanhazip.com/">icanhazip.com</a> site is no exception.</p>
<p>While many of the users have reasonable usage patterns, there are some users that query the site more than once per second from the same IP address.  If you haven't used the site before, all it does is return your public IP address in plain text.  Unless your IP changes rapidly, you may not need to query the site more than a few times an hour.</p>
<p>I added the following to my icanhazip.com virtual host definition to get the message across to those users that abuse the service:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">ErrorDocument</span> <span style="color: #ff0000;">403</span> <span style="color: #7f007f;">&quot;No can haz IP. Stop abusing this service. <span style="color: #000099; font-weight: bold;">\</span>
    Contact major at mhtx dot net for details.&quot;</span>
<span style="color: #00007f;">RewriteEngine</span> <span style="color: #0000ff;">On</span>
<span style="color: #00007f;">RewriteCond</span> %{REMOTE_ADDR} ^12.23.34.45$ [OR]
<span style="color: #00007f;">RewriteCond</span> %{REMOTE_ADDR} ^98.87.76.65$
<span style="color: #00007f;">RewriteRule</span> .* nocanhaz [F]</pre></div></div>

<p>The users that are caught on the business end of these 403 responses will see something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">$ curl -i icanhazip.com
HTTP/1.1 403 Forbidden
Date: Wed, 17 Nov 2010 13:42:55 GMT
Server: Apache
Content-Length: 84
Connection: close
Content-Type: text/html; charset=iso-8859-1
&nbsp;
No can haz IP. Stop abusing this service. Contact major at mhtx dot net for details.</pre></div></div>

<p><a href="http://rackerhacker.com/2010/11/17/throwing-thoughtful-403-forbidden-responses-with-apache/">Throwing thoughtful "403 Forbidden" responses with apache</a> is a post from: Major Hayden's <a href="http://rackerhacker.com">Racker Hacker</a> blog. 
<p>Thanks for following the blog via the RSS feed. Please don't copy my posts or quote portions of them without attribution.</p></p>
]]></content:encoded>
			<wfw:commentRss>http://rackerhacker.com/2010/11/17/throwing-thoughtful-403-forbidden-responses-with-apache/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Apache 2.2: internal dummy connection</title>
		<link>http://rackerhacker.com/2008/09/23/apache-22-internal-dummy-connection/</link>
		<comments>http://rackerhacker.com/2008/09/23/apache-22-internal-dummy-connection/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 01:42:21 +0000</pubDate>
		<dc:creator>Major Hayden</dc:creator>
				<category><![CDATA[Blog Posts]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://rackerhacker.com/?p=465</guid>
		<description><![CDATA[After working with some RHEL 5 servers fairly regularly, I noticed a reduction in Apache 2.2 performance when many connections were made to the server. There were messages like these streaming into the access_log as well: 127.0.0.1 - - [21/Aug/2008:12:00:10 -0400] "GET / HTTP/1.0" 200 2269 "-" "Apache/2.2.3 (Red Hat) (internal dummy connection)" 127.0.0.1 - [...]<p><a href="http://rackerhacker.com/2008/09/23/apache-22-internal-dummy-connection/">Apache 2.2: internal dummy connection</a> is a post from: Major Hayden's <a href="http://rackerhacker.com">Racker Hacker</a> blog. 
<p>Thanks for following the blog via the RSS feed. Please don't copy my posts or quote portions of them without attribution.</p></p>
]]></description>
			<content:encoded><![CDATA[<p>After working with some RHEL 5 servers fairly regularly, I noticed a reduction in Apache 2.2 performance when many connections were made to the server.  There were messages like these streaming into the access_log as well:</p>
<p><code>127.0.0.1 - - [21/Aug/2008:12:00:10 -0400] "GET / HTTP/1.0" 200 2269 "-" "Apache/2.2.3 (Red Hat) (internal dummy connection)"<br />
127.0.0.1 - - [21/Aug/2008:12:00:11 -0400] "GET / HTTP/1.0" 200 2269 "-" "Apache/2.2.3 (Red Hat) (internal dummy connection)"<br />
127.0.0.1 - - [21/Aug/2008:12:00:13 -0400] "GET / HTTP/1.0" 200 2269 "-" "Apache/2.2.3 (Red Hat) (internal dummy connection)"<br />
127.0.0.1 - - [21/Aug/2008:12:00:14 -0400] "GET / HTTP/1.0" 200 2269 "-" "Apache/2.2.3 (Red Hat) (internal dummy connection)"<br />
127.0.0.1 - - [21/Aug/2008:12:00:15 -0400] "GET / HTTP/1.0" 200 2269 "-" "Apache/2.2.3 (Red Hat) (internal dummy connection)"</code></p>
<p>On servers with ipv6 enabled, you might see a line like this one:</p>
<p><code>::1 - - [21/Aug/2008:12:00:15 -0400] "GET / HTTP/1.0" 200 2269 "-" "Apache/2.2.3 (Red Hat) (internal dummy connection)"</code></p>
<p>I began to wonder why Apache was making these connections back onto itself and initiating a <code>GET /</code>.  Apache's <a href="http://wiki.apache.org/httpd/InternalDummyConnection">documentation</a> had the following:</p>
<blockquote><p>When the Apache HTTP Server manages its child processes, it needs a way to wake up processes that are listening for new connections. To do this, it sends a simple HTTP request back to itself. This request will appear in the access_log file with the remote address set to the loop-back interface (typically 127.0.0.1 or ::1 if IPv6 is configured). If you log the User-Agent string (as in the combined log format), you will see the server signature followed by "(internal dummy connection)" on non-SSL servers. During certain periods you may see up to one such request for each httpd child process.</p>
<p>These requests are perfectly normal and you do not, in general, need to worry about them. They can simply be ignored.</p></blockquote>
<p>Sure, I could easily ignore the requests, but the requests were increasing the load on my server more than I liked.  Apache's documentation suggested omitting the lines from the logs by adding the following to the Apache configuration:</p>
<p><code>SetEnvIf Remote_Addr "127\.0\.0\.1" loopback</code></p>
<p>And then adding <code>env=!loopback</code> to your <code>CustomLog</code> lines ensures that the data won't show up in your access logs.  However, you'll still end up with <code>Directory index forbidden by Options directive: /var/www/html/</code> filling up your error_logs.  A quick search revealed a <a href="http://www.inventivelabs.com.au/weblog/post/apache-s-internal-dummy-connection">handy mod_rewrite</a> rule to get rid of these requests as quickly as possible with the lowest effort required from Apache:</p>
<p><code>RewriteCond %{HTTP_USER_AGENT} ^.*internal\ dummy\ connection.*$ [NC]<br />
RewriteRule .* - [F,L]</code></p>
<p>At this point, the requests to the localhost should receive a 403 immediately.  Since you can't keep Apache from sending all of these requests to itself, the best you can do is respond to them in a manner that requires the lowest possible resources.</p>
<p><a href="http://rackerhacker.com/2008/09/23/apache-22-internal-dummy-connection/">Apache 2.2: internal dummy connection</a> is a post from: Major Hayden's <a href="http://rackerhacker.com">Racker Hacker</a> blog. 
<p>Thanks for following the blog via the RSS feed. Please don't copy my posts or quote portions of them without attribution.</p></p>
]]></content:encoded>
			<wfw:commentRss>http://rackerhacker.com/2008/09/23/apache-22-internal-dummy-connection/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Enabling Ruby on Rails support for a domain in Plesk</title>
		<link>http://rackerhacker.com/2008/08/11/enabling-ruby-on-rails-support-for-a-domain-in-plesk/</link>
		<comments>http://rackerhacker.com/2008/08/11/enabling-ruby-on-rails-support-for-a-domain-in-plesk/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 01:16:18 +0000</pubDate>
		<dc:creator>Major Hayden</dc:creator>
				<category><![CDATA[Blog Posts]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[plesk]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://rackerhacker.com/?p=389</guid>
		<description><![CDATA[If you have Plesk 8.1 or later, you have support available for Ruby on Rails. Unfortunately, clicking the FastCGI checkbox in Plesk won't get you all of the support you need (and expect). The folks over at Parallels created a relatively simple process to get Ruby on Rails working properly on your site: Go to [...]<p><a href="http://rackerhacker.com/2008/08/11/enabling-ruby-on-rails-support-for-a-domain-in-plesk/">Enabling Ruby on Rails support for a domain in Plesk</a> is a post from: Major Hayden's <a href="http://rackerhacker.com">Racker Hacker</a> blog. 
<p>Thanks for following the blog via the RSS feed. Please don't copy my posts or quote portions of them without attribution.</p></p>
]]></description>
			<content:encoded><![CDATA[<p>If you have Plesk 8.1 or later, you have support available for Ruby on Rails.  Unfortunately, clicking the FastCGI checkbox in Plesk won't get you all of the support you need (and expect).  The folks over at Parallels created a <a href="http://kb.parallels.com/en/5489">relatively simple process</a> to get Ruby on Rails working properly on your site:</p>
<p>Go to your domain that you want to adjust, and click <b>Setup</b>.  Make sure the <b>CGI</b> and <b>FastCGI</b> options are enabled.  Pick a name for your application and make the directory for your application in the <b>httpdocs</b> directory.  Upload your files to that directory.</p>
<p>Once you've done that, create an <b>.htaccess</b> file in the <b>httpdocs</b> directory with the following text inside:</p>
<p><code>RewriteEngine On<br />
RewriteRule ^$ /public/index.html [L]<br />
RewriteCond % !^/railsapp/public<br />
RewriteRule ^(.*)$ /public/$1 [L]<br />
RewriteCond % !-f<br />
RewriteRule ^(.*)$ public/dispatch.fcgi/$1 [QSA,L]</code></p>
<p>Remove the <b>.htaccess</b> file within the <b>public</b> directory of your application and add a file called <b>dispatch.fcgi</b> to that directory which contains:</p>
<p><code>#!/usr/bin/ruby</code></p>
<p>You should be able to access your application at http://domain.com/railsapp/.</p>
<p><a href="http://rackerhacker.com/2008/08/11/enabling-ruby-on-rails-support-for-a-domain-in-plesk/">Enabling Ruby on Rails support for a domain in Plesk</a> is a post from: Major Hayden's <a href="http://rackerhacker.com">Racker Hacker</a> blog. 
<p>Thanks for following the blog via the RSS feed. Please don't copy my posts or quote portions of them without attribution.</p></p>
]]></content:encoded>
			<wfw:commentRss>http://rackerhacker.com/2008/08/11/enabling-ruby-on-rails-support-for-a-domain-in-plesk/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

