<?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>Tudor Barbu&#039;s professional blog &#187; apache</title>
	<atom:link href="http://blog.motane.lu/tag/apache/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.motane.lu</link>
	<description>Ramblings about software development</description>
	<lastBuildDate>Thu, 02 Feb 2012 17:38:27 +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>Redirect GET requests to improve SEO rating</title>
		<link>http://blog.motane.lu/2012/01/01/redirect-get-requests-to-improve-seo-rating/</link>
		<comments>http://blog.motane.lu/2012/01/01/redirect-get-requests-to-improve-seo-rating/#comments</comments>
		<pubDate>Sun, 01 Jan 2012 12:37:34 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[seo]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1662</guid>
		<description><![CDATA[SEO, SEO, SEO. Everything today is about SEO. If your site doesn&#8217;t rank high in Google or other search engines, well, it doesn&#8217;t really matter how good it is as nobody will ever get to it. And URLs are very important in the SEO process. I&#8217;m not going to talk about friendly-urls as there are [...]]]></description>
			<content:encoded><![CDATA[<p>SEO, SEO, SEO. Everything today is about SEO. If your site doesn&#8217;t rank high in Google or other search engines, well, it doesn&#8217;t really matter how good it is as nobody will ever get to it. And URLs are very important in the SEO process. I&#8217;m not going to talk about <a href="http://en.wikipedia.org/wiki/Rewrite_engine" title="Friendly URLs in Wikipedia" rel="outgoing">friendly-urls</a> as there are thousands of articles out there on the subject, but on a slightly different problem. </p>
<p>Take a look at the two friendly URLs below:</p>
<blockquote><p>
www.example.com/controller/action<br />
www.example.com/controller/action/
</p></blockquote>
<p>For Google&#8217;s crawler, these are two different URLs. Links to one of them don&#8217;t improve the link popularity of the other. And you&#8217;ll also get a lot of &#8220;duplicate title tags&#8221; in Google&#8217;s webmaster tools. Which is not good for business. Literally!!!</p>
<p>The obvious solution is to just redirect all URLs that don&#8217;t end with a / caracter with a HTTP 301 Permanent Redirect. Easily done via .htaccess:</p>
<pre class="brush: plain; title: ; notranslate">
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [L,R=301]
</pre>
<p>But as soon as I did it, an <a href="http://blog.motane.lu/2011/01/25/forward-post-data/" title="Forward POST data">old nemesis</a> of mine came back to haunt me. The server discards the POST data when redirecting and half the site stopped working. #FAIL</p>
<p>After thinking on a suitable solution to redirect all the POST data without bothering the user with security alerts and against all specifications, it hit me: I don&#8217;t have to. Web crawlers don&#8217;t post data so I just need to redirect the GET requests. Easily done by adding just one more line to the .htaccess file:</p>
<pre class="brush: plain; title: ; notranslate">
RewriteCond %{REQUEST_METHOD} ^(GET)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [L,R=301]
</pre>
<p>Voila! The solution is up and running on <a href="http://www.storebeez.com" title="StoreBeez">StoreBeez</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2012/01/01/redirect-get-requests-to-improve-seo-rating/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework and web hosting services</title>
		<link>http://blog.motane.lu/2009/11/24/zend-framework-and-web-hosting-services/</link>
		<comments>http://blog.motane.lu/2009/11/24/zend-framework-and-web-hosting-services/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 19:47:29 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1106</guid>
		<description><![CDATA[Let&#8217;s face it. We can&#8217;t all buy or rent our own servers. It&#8217;s not cost effective. So we turn to hosting companies &#8211; always the popular choice. But when you&#8217;re using an shared hosting service, you can&#8217;t make changes in the server&#8217;s configuration file. You usually get a writeable directory in a location like &#8230;and [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s face it. We can&#8217;t all buy or rent our own servers. It&#8217;s not cost effective. So we turn to hosting companies &#8211; always the popular choice. But when you&#8217;re using an shared hosting service, you can&#8217;t make changes in the server&#8217;s configuration file. You usually get a writeable directory in a location like</p>
<pre class="brush: plain; title: ; notranslate">
/home/{your-username}/public_html/
</pre>
<p>&#8230;and a <a href="http://www.cpanel.net/" title="Cpanel Inc. homepage" class="outgoing">Cpanel account</a> to manage your share of the server, emails, databases and so on. And&#8230;that&#8217;s about it. You can&#8217;t point your webroot to the public directory as taught in Zend Framework&#8217;s manual, all your library files will be exposed to the public and so on. What to do then? The answer is simple: <strong><em>.htaccess</em></strong> and <strong>mod_rewrite</strong>. Usually, hosting companies install <strong><em>mod_rewrite</em></strong> and set <strong><em>AllowOverride</em></strong> to true, so this solution will work in the vast majority of cases.</p>
<p>Upload via FTP or SSH your content into your <strong><em>public_html</em></strong>, <strong><em>wwwroot</em></strong> or <strong><em>www</em></strong> directory (the webroot directory, whatever its name may be). Then add 4 htaccess files, one directly in the web root, one in the public directory and one in all other folders. It should look something like this (without the numbers, of course).</p>
<blockquote>
<pre>
public_html/
     /public
       .htaccess (2)
     /application
        .htaccess (3)
     /library
        .htaccess (3)
    .htaccess (1)
</pre>
</blockquote>
<p>Now, the first htaccess file &#8211; #1 &#8211; should contain the following:</p>
<pre class="brush: plain; title: ; notranslate">
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</pre>
<p>&#8230;this will redirect the traffic from this folder to the public/ sub-folder. The second .htaccess &#8211; the one in the public folder &#8211; should be the .htaccess file shipped with Zend Framework. It usually looks like this:</p>
<pre class="brush: plain; title: ; notranslate">
SetEnv APPLICATION_ENV production 

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
</pre>
<p>And the .htaccess files located in all other directories &#8211; #3 &#8211; should simply forbid access to their respective folders, like such:</p>
<pre class="brush: plain; title: ; notranslate">
deny from all
</pre>
<p>Worked for me <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2009/11/24/zend-framework-and-web-hosting-services/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Web svn administration on Debian</title>
		<link>http://blog.motane.lu/2009/10/30/web-svn-administration-on-debian/</link>
		<comments>http://blog.motane.lu/2009/10/30/web-svn-administration-on-debian/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 08:01:45 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[source control]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1050</guid>
		<description><![CDATA[When I work alone on some projects, I usually use git for versioning. I have a github account and I throw there my code, for safe keeping, since GitHub&#8217;s datacenter is much more reliable than anything I could ever improvise at home. And it&#8217;s quite cheap also. But at work I&#8217;ve always used SVN and [...]]]></description>
			<content:encoded><![CDATA[<p>When I work alone on some projects, I usually use <a href="http://git-scm.com/" title="Git - Fast Version Control System" class="outgoing">git</a> for versioning. I have a <a href="http://github.com/motanelu" title="">github account</a> and I throw there my code, for safe keeping, since GitHub&#8217;s datacenter is much more reliable than anything I could ever improvise at home. And it&#8217;s quite cheap also. </p>
<p>But at work I&#8217;ve always used SVN and I also wanted to use it at my current workplace. So I had to install it. Since we&#8217;re using Debian and all the components are in the repositories, things went pretty smooth:</p>
<pre class="brush: plain; title: ; notranslate">
sudo apt-get install subversion libapache2-svn
sudo a2enmod dav
sudo a2enmod dav-svn
</pre>
<p>And basically that&#8217;s it. It works. But since I&#8217;m lazy, I wanted a simple way to create repositories, manage the users&#8217; rights and so on. That &#8220;svn admin create&#8221; stuff just doesn&#8217;t cut it for me. Thus I looked over the web in search of a suitable web interface for SVN. And I&#8217;ve found one developed by some French guys, called <a href="http://www.usvn.info/" title="User friendly SVN" class="outgoing">User Friendly SVN</a>. It&#8217;s built on Zend Framework, it&#8217;s simple, very simple for that matter &#8211; just the essentials &#8211; but it gets the job done. It really easy to use and easy to install. If you want a SVN management tool, give it a try. </p>
<p>Now I&#8217;m looking for a way to tie &#8211; as simple as possible &#8211; the system user accounts with SVN&#8217;s user account. Use password to rule them all <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2009/10/30/web-svn-administration-on-debian/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Caching problems with mod_expires</title>
		<link>http://blog.motane.lu/2009/09/21/caching-problems-with-mod_expires/</link>
		<comments>http://blog.motane.lu/2009/09/21/caching-problems-with-mod_expires/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 21:16:59 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[system administration]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1026</guid>
		<description><![CDATA[Sometimes, when you&#8217;re dealing with large images, flash movies or large javascript files, it&#8217;s generally a good idea to force them in the client&#8217;s cache. A very simple way to achieve this is by using Apache&#8217;s mod_expires. For instance, if you add the following example, taken from the manual, to your .htaccess file &#8211; assuming [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.motane.lu/wp-content/uploads/2009/09/apache.jpg" alt="apache" title="apache" width="200" height="150" class="alignleft size-full wp-image-1036" />Sometimes, when you&#8217;re dealing with large images, flash movies or large javascript files, it&#8217;s generally a good idea to force them in the client&#8217;s cache. </p>
<p>A very simple way to achieve this is by using Apache&#8217;s <strong><em>mod_expires</em></strong>. For instance, if you add the following example, taken from the manual, to your <strong><em>.htaccess</em></strong> file &#8211; assuming of course that mod_expires is properly installed and configured &#8211;  it will tell the browser to cache all the files for a month.</p>
<pre class="brush: plain; title: ; notranslate">
ExpiresDefault &quot;access plus 4 weeks&quot;
</pre>
<p>So, every time the client returns in the following month to the site, the browser won&#8217;t download all the static content again, but load it locally from the cache, thus minimising the loading time. Of course, there are some issues that usually appear after updates. Particularly after updates of the cached files <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>For instance, you add a new Javascript functionality to the site or make some changes in the <em>css</em> or <em>swf</em> files and the user doesn&#8217;t hit at CTRL+F5 to fully refresh the page and clear its cache, then he will see the old version of the site. Of course, one can take the short road to LamerVille and post a message on the site, asking the user to refresh the page. But that&#8217;s a little too lame to be taken into consideration, especially when dealing with respectable sites.</p>
<p>But there&#8217;s another way, much more elegant. First of all, place all the static, cache-able files in a separate folder. The browser will cache all the files based on their URL. If you want the browser to reload all the static data on every new request, you need to change the URLs on every new request. </p>
<p>Let&#8217;s say, the site resides at <strong><em>www.example.com</em></strong> and that all the static information will be served from <strong><em>www.example.com/static/</em></strong>. Now, a good idea is to make the links look like this:</p>
<blockquote>
<p>http://www.example.com/static/(release-number)/css/style.css</p>
<p>http://www.example.com/static/(release-number)/js/cool-ajax-app.js</p>
</blockquote>
<p>Where <em>release-number</em> is a number that increments with every new release. This way, the URLs will be different after each release thus forcing the browsers to fetch the new files. You don&#8217;t need to go through lots of files and increment the release number by hand, you can just use the following python script:</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/python
&quot;&quot;&quot;
Read more about what this script actually does on 

http://blog.motane.lu/2009/09/21/caching-problems-with-mod_expires/

Usage:
	python increment_release.py start_directory static_prefix

Author:
	Tudor Barbu http://blog.motane.lu
&quot;&quot;&quot;
import sys, os, re

REGEX = ''
CACHED_DIR = ''

def main():
    global REGEX, CACHED_DIR 

    if sys.argv is not None:
        length = len( sys.argv )
        if length &lt; 3:
            print 'Read the comments in the source code'
            exit()
    start_folder = sys.argv[1]
    CACHED_DIR = sys.argv[2]

    REGEX = re.compile( '=(\'|&quot;)' + re.escape( CACHED_DIR ) + '\/((\d+)\/|)([^\'|&quot;]+)(\'|&quot;)' )

    parse_files( start_folder )

def parse_files( dir ):
    basedir = dir
    subdirectories = []
    for item in os.listdir( dir ):
        if os.path.isfile( os.path.join( basedir, item ) ):
            perform_replace( os.path.join( basedir, item ) )
        else:
            subdirectories.append( os.path.join( basedir, item ) )
    for subdir in subdirectories:
        parse_files( subdir )

def perform_replace( file ):
    global REGEX
    f = open( file, 'r' )
    contents = f.read()
    f.close()
    if REGEX.search( contents ):
        f = open( file, 'w' )
        f.write( REGEX.sub( handle_match, contents ) )
        f.close()

def handle_match( matches ):
    global CACHED_DIR
    if matches.group(3) is not None:
        revision_number = int( matches.group(3) ) + 1
    else:
        revision_number = 1
    return '=%s%s/%s/%s%s' % ( matches.group(1), CACHED_DIR, revision_number, matches.group(4), matches.group(5) )

if __name__ == '__main__':
    main()
</pre>
<p>&#8230;and, of course, there&#8217;s no need to create lots of directories either. A simple .htaccess rewrite rule will do. Just redirect all the URLs like <strong><em>/static/(number)/css/style.css</em></strong> to point to <strong><em>/static/css/style.css</em></strong>, by adding these 2 lines in the /static/.htaccess file:</p>
<pre class="brush: plain; title: ; notranslate">
RewriteEngine On
RewriteRule ^\/static\/(\d+)\/(.*)$ $2 [NC,L]
</pre>
<p>This should solve all your caching related problems. If you want to look savvy, you can use the version number of the head revision from subversion of whatever versioning system you might be using instead of a simple incremental number. </p>
<p>Yes, I know that the script is a little bit buggy but it works for me. If you have an improved version, post a comment below. Credits will be given. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2009/09/21/caching-problems-with-mod_expires/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>ALERT &#8211; configured POST variable limit exceeded</title>
		<link>http://blog.motane.lu/2009/09/15/alert-configured-post-variable-limit-exceeded/</link>
		<comments>http://blog.motane.lu/2009/09/15/alert-configured-post-variable-limit-exceeded/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 17:03:22 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=990</guid>
		<description><![CDATA[ALERT &#8211; configured POST variable limit exceeded&#8230;this error kept poping in my server&#8217;s logs all morning, and &#8211; what a strange coincidence &#8211; an application stopped working in that exact time frame Well, upon investigation, this exception is thrown by suhosin when a client application sends too many variables to the server. In my case, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>ALERT &#8211; configured POST variable limit exceeded</strong>&#8230;this error kept poping in my server&#8217;s logs all morning, and &#8211; what a strange coincidence &#8211; an application stopped working in that exact time frame <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>Well, upon investigation, this exception is thrown by <a href="http://www.hardened-php.net/suhosin/" title="Hardened-PHP Project" class="outgoing">suhosin</a> when a client application sends too many variables to the server. In my case, via HTTP POST. </p>
<p>The solution is simple, just increase the maximum number of allowed variables in php.ini. If you don&#8217;t have a suhosin section, just create one. Like such:</p>
<pre class="brush: plain; title: ; notranslate">
[suhosin]
suhosin.request.max_vars = 1000
suhosin.post.max_vars = 1000
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2009/09/15/alert-configured-post-variable-limit-exceeded/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Apache catch-all subdomains configuration</title>
		<link>http://blog.motane.lu/2009/09/14/apache-catch-all-subdomains-configuration/</link>
		<comments>http://blog.motane.lu/2009/09/14/apache-catch-all-subdomains-configuration/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 20:00:13 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[system administration]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=994</guid>
		<description><![CDATA[Since my job description is &#8220;Jack of all trades&#8221; today I had to configure some virtual hosts on our Apache web server. One of them had to have a catch-all rule for subdomains. I&#8217;m not a particularly good system administrator and I don&#8217;t want to become one. Programming is my thing. But, in order to [...]]]></description>
			<content:encoded><![CDATA[<p>Since my job description is &#8220;Jack of all trades&#8221; today I had to configure some virtual hosts on our Apache web server. One of them had to have a catch-all rule for subdomains. </p>
<p>I&#8217;m not a particularly good system administrator and I don&#8217;t want to become one. Programming is my thing. But, in order to put bread on the table, we sometimes have to do things we don&#8217;t like that much. For me, today was one of those days. And, after spending about two hours browsing Apache&#8217;s gargantuan documentation, I&#8217;ve finally figure it out and decided to share it with the world, in hope that will save somebody else&#8217;s time.</p>
<p>With a disclaimer that this might not be the best solution out there and I&#8217;m sure that are better, more elegant way to achieve this. But it works! </p>
<p>First of all, the main vhost looks something like this:</p>
<pre class="brush: plain; title: ; notranslate">
&lt;VirtualHost *&gt;
    ServerName www.my-site.com
    ServerAdmin webmaster@my-site.com

    DocumentRoot /var/www/my-site
    &lt;Directory /var/www/hosted/my-site&gt;
         Options FollowSymLinks
         AllowOverride All
         Order allow,deny
         Allow from all
    &lt;/Directory&gt;
   #bla bla bla
&lt;/VirtualHost&gt;
</pre>
<p>Apache queues all the virtual hosts and on each request it iterates through this queue in searching for a suitable virtual host definition. The first one that matches the request&#8217;s parameters is used, so the above definition must be first in the <em>/etc/apache2/sites-available/my-site.com</em>. This definition will serve the &#8220;www&#8221; sub-domain and all other sub-domains will be redirected here.</p>
<p>After the &#8220;main&#8221; virtual host, just add a definition for another virtual host, like such:</p>
<pre class="brush: plain; title: ; notranslate">
&lt;VirtualHost *&gt;
    ServerName my-site.com
    ServerAlias *.my-site.com
    RedirectMatch permanent (.+)$ http://www.my-site.ro$1
&lt;/VirtualHost&gt;
</pre>
<p>This way, all URLs that look like </p>
<blockquote><p>http://any-subdomain.my-site.com/whatever-file.php</p></blockquote>
<p> or </p>
<blockquote><p>http://my-site.com/whatever-file.php</p></blockquote>
<p>will be redirected to </p>
<blockquote><p>http://www.my-site.com/whatever-file.php</p></blockquote>
<p>Aside from correcting some spelling mistakes, like <em>ww.my-site.com</em> this will boost link popularity, because the crawlers usually consider <em>www.my-site.com</em> and <em>my-site.com</em> as two different sites (and, in fact, they are, but anyway), so incoming links to one will not be taken into consideration when computing the link popularity index of the other one. But, with a 301 permanent redirection, the crawler will consider both URLs to be the same site.</p>
<p>Another good idea is to also buy the &#8220;non-dash&#8221; spelling form of the domain &#8211; aka mysite.com &#8211; and redirect it to the original address. Like such:</p>
<pre class="brush: plain; title: ; notranslate">
&lt;VirtualHost *&gt;
    ServerName mysite.com
    ServerAlias *.mysite.com
    RedirectMatch permanent (.+)$ http://www.my-site.ro$1
&lt;/VirtualHost&gt;
</pre>
<p>Got the job done for me. And remember: Linux is like a wigwam: no windows, no doors, Apache inside <img src='http://blog.motane.lu/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2009/09/14/apache-catch-all-subdomains-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

