Thursday, April 9, 2015

URL rewriting not working in Apache 2.4.7 + Ubuntu 14.04

Have been struggling for the last two hours to get the URL rewriting working on my Apache 2.4.7 + Ubuntu 14.04 installation. Went through all the checklists and guidelines provided on the subject.. most common ones being enabling MultiView and AllowOverride all. Nothing worked.

Finally, figured out that I needed to add the following mime type to /etc/apache2/mods-enabled/mime.conf

AddType application/x-httpd-php .php

Second big learning was getting an insight into the URL matching logs. The old mechanism of enabling RewriteLog has been removed in 2.4 onwards. To see the logs, you will have to add the following in /etc/apache2/sites-enabled/000-default.conf on the /var/www module.

LogLevel alert rewrite:trace3

Once the above is done, you can tail and grep the error log on 'rewrite' to see the logs. Here is a step log of how Apache seems to be working through my rewrite rule. The following is my rewrite intention 

localhost/api/Chapter/3?priority=3  => localhost/api_gateway.php?path=Chapter/3&priority=3

  • [perdir /var/www/] strip per-dir prefix: /var/www/api/Chapter/3 -> api/Chapter/3
  • [perdir /var/www/] applying pattern '^api/(.*)$' to uri 'api/Chapter/3'
  • [perdir /var/www/] rewrite 'api/Chapter/3' -> 'api_gateway.php?path=Chapter/3'
  • split uri=api_gateway.php?path=Chapter/3 -> uri=api_gateway.php, args=path=Chapter/3&priority=3
  • [perdir /var/www/] add per-dir prefix: api_gateway.php -> /var/www/api_gateway.php
  • [perdir /var/www/] strip document_root prefix: /var/www/api_gateway.php -> /api_gateway.php
  • [perdir /var/www/] internal redirect with /api_gateway.php [INTERNAL REDIRECT]
  • [perdir /var/www/] strip per-dir prefix: /var/www/api_gateway.php -> api_gateway.php
  • [perdir /var/www/] applying pattern '^api/(.*)$' to uri 'api_gateway.php'
  • [perdir /var/www/] pass through /var/www/api_gateway.php
  • [perdir /var/www/] add path info postfix: /var/www/api -> /var/www/api/Chapter/3
  • [perdir /var/www/] strip per-dir prefix: /var/www/api/Chapter/3 -> api/Chapter/3
  • [perdir /var/www/] applying pattern '^api/(.*)$' to uri 'api/Chapter/3'
  • [perdir /var/www/] rewrite 'api/Chapter/3' -> 'api_gateway.php?path=Chapter/3'
  • split uri=api_gateway.php?path=Chapter/3 -> uri=api_gateway.php, args=path=Chapter/3&priority=3
  • [perdir /var/www/] add per-dir prefix: api_gateway.php -> /var/www/api_gateway.php

As you can see, my rewrite rule turns out to be:

RewriteRule ^api/(.*)$ api_gateway.php?path=$1 [QSA,NC,L]

Here, QSA is Query String Append which takes care of appending priority=3 to the target query. NC stands for Case Insensitive and L implies if this rule matches don't try any other rule.

Oh btw, if you are on the path of debugging your rewrite rule by switching the trace on - you are heading for scroll blindness. Use the following command to filter out just the part of log relevant to mod_rewrite.

$ tail -f /var/log/apache2/error.log | grep 'mod_rewrite' | awk '{for(i=1;i<=15;i++){$i=""}; print $0}'

 

No comments: