mod rewrite not reading the rule from htaccess file - .htaccess

I am using WAMP (apache 2.2.9 and PHP 5.4.17). I have few simple mod rewrite rules that are working on production server (CentOS) but on my windows machine one rule is being ignored. I spent 3 days on finding solution but none worked.
Here is mod rewrite rules
Options -Indexes FollowSymLinks MultiViews
RewriteEngine on
RewriteBase /mysite/
RewriteRule ^reviews/([a-zA-Z0-9_-]+)/([0-9]+)/(.*).html$ page-review.php?t=$1&m=$2&s=$3 [L] #This is being ignored by Apache
RewriteRule ^reviews/?$ reviews.php [L]
RewriteRule ^reviews/([a-zA-Z0-9_-]+)-reviews/?$ reviews.php?r=$1 [L]
RewriteRule ^file/([a-zA-Z0-9_-]+)/s([0-9]+)-([a-zA-Z0-9_-]+)/f([0-9]+)-(.*).html$ file.php?c=$1&s=$2&st=$3&&m=$4&t=$5 [L]
The first rewrite rule is being ignored by Apache. Surprisingly, when I remove all contents from htaccess it still reads my rules. I have turned on mod rewrite log and here is the log detail
log for http://localhost/mysite/reviews/product/11/samsung.html
127.0.0.1 - - [23/Aug/2013:14:37:34 +0100] [localhost/sid#453140][rid#1821000/subreq] (1) [perdir /mydir/] pass through /mydir/reviews.php
127.0.0.1 - - [23/Aug/2013:14:37:34 +0100] [localhost/sid#453140][rid#17cc4f0/initial] (1) [perdir /mydir/] pass through /mydir/reviews.php
127.0.0.1 - - [23/Aug/2013:14:37:34 +0100] [localhost/sid#453140][rid#17d0500/initial] (1) [perdir /mydir/] pass through /mydir/reviews.php
127.0.0.1 - - [23/Aug/2013:14:37:34 +0100] [localhost/sid#453140][rid#1835050/initial] (1) [perdir /mydir/] pass through /mydir/reviews.php
As you can see above, instead of rewriting above request to page-review.php it reads reviews.php file
Here is another request which works fine
log for http://localhost/mysite/file/downloads/software/f5983-docs.html
127.0.0.1 - - [23/Aug/2013:14:39:42 +0100] [localhost/sid#453140][rid#47f4188/initial] (2) [perdir /mydir/] rewrite 'file/downloads/software/f5983-docs.html' -> 'file.php?c=downloads&s=45&st=software&&m=5983&t=docs'
127.0.0.1 - - [23/Aug/2013:14:39:42 +0100] [localhost/sid#453140][rid#47f4188/initial] (2) [perdir /mydir/] trying to replace prefix /mydir/ with /mysite/
127.0.0.1 - - [23/Aug/2013:14:39:42 +0100] [localhost/sid#453140][rid#47f4188/initial] (1) [perdir /mydir/] internal redirect with /mysite/file.php [INTERNAL REDIRECT]
127.0.0.1 - - [23/Aug/2013:14:39:42 +0100] [localhost/sid#453140][rid#47ed3e0/initial/redir#1] (1) [perdir /mydir/] pass through /mydir/file.php

Rules mostly look alright. Try this slightly modified code:
Options -Indexes +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /mysite/
RewriteRule ^reviews/(\w+)/([0-9]+)/([^.]+)\.html$ page-review.php?t=$1&m=$2&s=$3 [L,QSA,NC]
RewriteRule ^reviews/?$ reviews.php [L,NC]
RewriteRule ^reviews/(\w+)-reviews/?$ reviews.php?r=$1 [L,QSA,NC]
RewriteRule ^file/(\w+)/s([0-9]+)-(\w+)/f([0-9]+)-([^.]+)\.html$ file.php?c=$1&s=$2&st=$3&&m=$4&t=$5 [L,QSA,NC]
Btw regex in your last rule won't match file/downloads/software/f5983-docs.html

Related

Symfony 4 + AWS Cloudfront as PageCache + AWS ELB results in endless redirects on frontpage

I am having the following setup:
Domain -> Cloudfront -> ELB -> #instances
This fails ONLY (!) on the index page, all sub pages are working fine!
If I remove the Cloudfront in the chain, everything works.
So the server error says "Too many redirects". I am using currently (for testing) the following .htaccess content ("official" example):
# Use the front controller as index file. It serves as a fallback solution when
# every other rewrite/redirect fails (e.g. in an aliased environment without
# mod_rewrite). Additionally, this reduces the matching process for the
# start page (path "/") because otherwise Apache will apply the rewriting rules
# to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl).
DirectoryIndex index.php
# By default, Apache does not evaluate symbolic links if you did not enable this
# feature in your server configuration. Uncomment the following line if you
# install assets as symlinks or if you experience problems related to symlinks
# when compiling LESS/Sass/CoffeScript assets.
# Options FollowSymlinks
# Disabling MultiViews prevents unwanted negotiation, e.g. "/index" should not resolve
# to the front controller "/index.php" but be rewritten to "/index.php/index".
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
# Determine the RewriteBase automatically and set it as environment variable.
# If you are using Apache aliases to do mass virtual hosting or installed the
# project in a subdirectory, the base path will be prepended to allow proper
# resolution of the index.php file and to redirect to the correct URI. It will
# work in environments without path prefix as well, providing a safe, one-size
# fits all solution. But as you do not need it in this case, you can comment
# the following 2 lines to eliminate the overhead.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
# Sets the HTTP_AUTHORIZATION header removed by Apache
RewriteCond %{HTTP:Authorization} .
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect to URI without front controller to prevent duplicate content
# (with and without `/index.php`). Only do this redirect on the initial
# rewrite by Apache and not on subsequent cycles. Otherwise we would get an
# endless redirect loop (request -> rewrite to front controller ->
# redirect -> request -> ...).
# So in case you get a "too many redirects" error or you always get redirected
# to the start page because your Apache does not expose the REDIRECT_STATUS
# environment variable, you have 2 choices:
# - disable this feature by commenting the following 2 lines or
# - use Apache >= 2.3.9 and replace all L flags by END flags and remove the
# following RewriteCond (best solution)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]
# If the requested filename exists, simply serve it.
# We only want to let Apache serve files and not directories.
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Rewrite all other queries to the front controller.
RewriteRule ^ %{ENV:BASE}/index.php [L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
# When mod_rewrite is not available, we instruct a temporary redirect of
# the start page to the front controller explicitly so that the website
# and the generated links can still be used.
RedirectMatch 307 ^/$ /index.php/
# RedirectTemp cannot be used instead
</IfModule>
</IfModule>
I enabled trace logging for htaccess mod rewrite with the following output if I open the index page with cloudfront.domain.com
[rewrite:trace2] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff233f70/initial] [perdir /var/www/html/web/] trying to replace context docroot /var/www/html/web with context prefixerror_log
[rewrite:trace1] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff233f70/initial] [perdir /var/www/html/web/] internal redirect with /index.php [INTERNAL REDIRECT]error_log
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] strip per-dir prefix: /var/www/html/web/index.php -> index.php
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] applying pattern '^(.*)' to uri 'index.php'
[rewrite:trace4] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] RewriteCond: input='/index.php::index.php' pattern='^(/.+)/(.*)::\\\\2$' => not-matched
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] strip per-dir prefix: /var/www/html/web/index.php -> index.phperror_log
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] applying pattern '^' to uri 'index.php'
[rewrite:trace4] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] RewriteCond: input='' pattern='.' => not-matched
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] strip per-dir prefix: /var/www/html/web/index.php -> index.php
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] applying pattern '^index\\\\.php(?:/(.*)|$)' to uri 'index.php'
[rewrite:trace4] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] RewriteCond: input='200' pattern='^$' => not-matched
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] strip per-dir prefix: /var/www/html/web/index.php -> index.php
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] applying pattern '^' to uri 'index.php'
[rewrite:trace4] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] RewriteCond: input='/var/www/html/web/index.php' pattern='-f' => matched
[rewrite:trace1] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] pass through /var/www/html/web/index.php
The comments in the .htaccess files say that you should comment the lines if the error with "too many redirects" occurs. But this is not working for me. Cause the problem only occurs with cloudfront in front of the webserver.
Also this setup was working fine with Symfony 3.4!
Any .htaccess server gurus out there who can tell me what is possibly causing the problem?
I fixed it by myself.
The problem seems to be that Cloudfront is adding a slash to the REQUEST_URI, which leads to a duplicate / on the index page and a redirect to itself and so on.
So my hotfix was to put that at the beginning of the index.php file to remove // from the REQUEST_URI:
$_SERVER['REQUEST_URI'] = '/' . ltrim(#$_SERVER['REQUEST_URI'], '/');

.htaccess remove square brackets from URLs

I had many URLs with square brackets. Then I changed these URLs and removed all square brackets from them, but I still get soft 404 errors, because old URLs are indexed in the web. The URLs are vary, I can redirect each URLs manually, but It will be better if I'll use some universal rule in .htaccess, which removes all square brackets from the URLs.
http://www.example.com/page-[first]
http://www.example.com/page-[second]
etc.. will replaced with:
http://www.example.com/page-first
http://www.example.com/page-second
Can I do it with .htaccess?
Thank you
Try this:
RewriteEngine On
RewriteBase /
RewriteRule ^(.*)\[(.*)$ $1$2 [N,R=301]
RewriteRule ^(.*)\](.*)$ $1$2 [N,R=301]
If your .htacess is in a sub folder, change RewriteBase / with:
RewriteBase /sub-folder-name
Here's my access_log - which shows the redirections:
::1 - - [04/Jun/2016:12:29:23 +0800] "GET /test/hello-[world].html HTTP/1.1" 301 246
::1 - - [04/Jun/2016:12:29:23 +0800] "GET /test/hello-world.html HTTP/1.1" 200 3
::1 - - [04/Jun/2016:12:37:45 +0800] "GET /test/hello-%5bworld%5d.html HTTP/1.1" 301 246
::1 - - [04/Jun/2016:12:37:45 +0800] "GET /test/hello-world.html HTTP/1.1" 304 -
You can do this redirection using a single rule :
RewriteEngine on
RewriteCond %{THE_REQUEST} /page-(?:%5B|\[)(.*?)(?:%5D|\]) [NC]
RewriteRule ^ /%1 [R,L]

mod_rewrite: how to stop it after the first match?

I have a PHP application that uses GET variables to determine language, that is:
http://example.com/?lang=en
And I'm writing a mod_rewrite rule so that people can access it using SEO friendly URLs:
http://example.com/en/
My .htaccess looks like this so far:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^[a-z]{2} /test.php?lang=$0 [L]
(The test.php thing is just a test, not the name of my real app).
But when I access:
http://example.com/fr/blabla
What I get in my rewrite_log is the following:
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (3) [perdir /var/www/html/example/] add path info postfix: /var/www/html/example/fr -> /var/www/html/example/fr/blabla
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (3) [perdir /var/www/html/example/] strip per-dir prefix: /var/www/html/example/fr/blabla -> fr/blabla
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (3) [perdir /var/www/html/example/] applying pattern '^[a-z]{2}' to uri 'fr/blabla'
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (2) [perdir /var/www/html/example/] rewrite 'fr/blabla' -> '/test.php?lang=fr'
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (3) split uri=/test.php?lang=fr -> uri=/test.php, args=lang=fr
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (1) [perdir /var/www/html/example/] internal redirect with /test.php [INTERNAL REDIRECT]
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b92310/initial/redir#1] (3) [perdir /var/www/html/example/] strip per-dir prefix: /var/www/html/example/test.php -> test.php
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b92310/initial/redir#1] (3) [perdir /var/www/html/example/] applying pattern '^[a-z]{2}' to uri 'test.php'
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b92310/initial/redir#1] (1) [perdir /var/www/html/example/] pass through /var/www/html/example/test.php
What I don't understand is why, after the first match (4th line in the log), mod_rewrite keeps matching and redirecting again and again. I found several people posting similar questions here, and as a result of their answers, I tried adding the RewriteCond rule, but mod_rewrite seems to ignore it (yes, test.php does exist in my filesystem). What's going on?
EDIT: forgot to mention. The server I'm testing this on is an Apache 2.2.3.
EDIT: nevermind. It was a typo in my test.php, which was preventing it from being executed correctly (can you add here one of those "eyeroll" or "embarrassed" emojis?)
To stop after first rewrite you can use:
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^[a-z]{2} test.php?lang=$0 [L,QSA]
%{ENV:REDIRECT_STATUS} is internal variable that is set to 200 after first rewrite by Apache.
However RewriteCond %{REQUEST_FILENAME} !-f should stop rewrite loop after first rewrite if test.php is a valid file.

Mediawiki Rewrite to external site

I am moving my site from Mediawiki to Wordpress and would like to redirect this page:
http://wecheck.org/wiki/Aaron_Swartz
to this page:
http://newslines.org/wiki/category/computer-people/aaron-swartz/
Currently in .htaccess I have
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{QUERY_STRING} ^title=Aaron_Swartz$
RewriteRule ^/w/index\.php$ http://newslines.org/wiki/category/computer-people/aaron-swartz/? [L,R=301]
RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/w/index.php [L]
RewriteRule ^/?$ %{DOCUMENT_ROOT}/w/index.php [L]
The second part makes the pretty URLs for mediawiki. I have tried many, many variations but I can't get it to work at all. Any help most appreciated.
UPDATE: Log file using the solution given. What is the .phtml?
[24/Jan/2013:22:01:00 +0000] init rewrite engine with requested uri /wiki/Aaron_Swartz
[24/Jan/2013:22:01:00 +0000] (1) pass through /wiki/Aaron_Swartz
[24/Jan/2013:22:01:00 +0000] (1) [perdir /var/www/] pass through /var/www/w/wiki.phtml
[24/Jan/2013:22:01:00 +0000] (3) [perdir /var/www/] add path info postfix: /var/www/w/wiki.phtml -> /var/www/w/wiki.phtml/Aaron_Swartz
[24/Jan/2013:22:01:00 +0000] (3) [perdir /var/www/] strip per-dir prefix: /var/www/w/wiki.phtml/Aaron_Swartz -> w/wiki.phtml/Aaron_Swartz
[24/Jan/2013:22:01:00 +0000] (3) [perdir /var/www/] applying pattern '^wiki/Aaron_Swartz$' to uri 'w/wiki.phtml/Aaron_Swartz'
[24/Jan/2013:22:01:00 +0000] (3) [perdir /var/www/] add path info postfix: /var/www/w/wiki.phtml -> /var/www/w/wiki.phtml/Aaron_Swartz
[24/Jan/2013:22:01:00 +0000] (3) [perdir /var/www/] strip per-dir prefix: /var/www/w/wiki.phtml/Aaron_Swartz -> w/wiki.phtml/Aaron_Swartz
[24/Jan/2013:22:01:00 +0000] (3) [perdir /var/www/] applying pattern '^w/index\.php$' to uri 'w/wiki.phtml/Aaron_Swartz'
[24/Jan/2013:22:01:00 +0000] (1) [perdir /var/www/] pass through /var/www/w/wiki.phtml
Remember that Apache directives like RewriteRule are applied before MediaWiki even sees the request. Thus, your current rule should work for http://wecheck.org/w/index.php?title=Aaron_Swartz, but not for http://wecheck.org/wiki/Aaron_Swartz.
Actually, though, the rule won't work because your regexp begins with a /, but in .htaccess context the leading slash (or whatever you've set RewriteBase to) is removed before the rewrite rules are applied.
Thus, fixing those two problems, what you need is something like this:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
# match the short URL of the page:
RewriteRule ^wiki/Aaron_Swartz$ http://newslines.org/wiki/category/computer-people/aaron-swartz/ [R=301,L]
# optional: also match the long version of the URL:
RewriteCond %{QUERY_STRING} ^title=Aaron_Swartz$
RewriteRule ^w/index\.php$ http://newslines.org/wiki/category/computer-people/aaron-swartz/ [R=301,L]
Edit: Based on your log file, it looks like you have a wiki.phtml file in your webserver root, to which Apache is automatically resolving any URL paths beginning with /wiki/.
One workaround would be to move your rewrite rules to the main Apache config where they'll run before any such mapping is done; another, more straightforward way would be to just change the first rewrite rule above to:
# match the short URL of the page:
RewriteRule ^wiki\.phtml/Aaron_Swartz$ http://newslines.org/wiki/category/computer-people/aaron-swartz/ [R=301,L]
or even:
# match the short URL of the page:
RewriteRule ^wiki(\.phtml)?/Aaron_Swartz$ http://newslines.org/wiki/category/computer-people/aaron-swartz/ [R=301,L]

Redirect to specific pages depending upon the url routing using htaccess file

I have the urls like
http://localhost/mis
http://localhost/mis/newsletter.php
http://localhost/mis/cms.php?mainid=65
http://localhost/mis/news.php?mainid=93
Well I am using these urls for school section.
Now for the A-level section I have the following urls
http://localhost/mis/index.php?mode=0
http://localhost/mis/newsletter.php?mode=0
http://localhost/mis/cms.php?mainid=65&mode=0
http://localhost/mis/news.php?mainid=93&mode=0
I want the above urls to be routed like
http://localhost/mis/a-level
http://localhost/mis/a-level/newsletter.php
http://localhost/mis/a-level/cms.php?mainid=65
http://localhost/mis/a-level/news.php?mainid=93
Please help me out with these url routing via .htaccess file.
EDIT: The htaccess file is under mis folder
FILE STRUCTURE:
root>>
mis>>
.htaccess
newsletter.php
cms.php
news.php
Try these in the .htaccess file inside the /mis folder.
# turning rewrite on
RewriteEngine On
# this will redirect: mis/a-level
RewriteRule ^a-level$ index.php?mode=0 [L]
# this will redirect all the rest
RewriteRule ^a-level/(.+)$ $1?mode=0 [QSA,L]
I think the lines like http://localhost/mis/cms.php?mainid=65&mode=0 are just copy-paste errors and you ment: http://localhost/mis/cms.php?mainid=65&mode=0
I have tested these rules. If they don't work on your system there must be some configuration issue. Are there other rewrite rules in your file? I not, try enabling rewrite logging to get some more information. This must be enabled in httpd.conf (they are not allowed in .htaccess).
RewriteLog D:\bence\wamp\logs\rewrite.log
RewriteLogLevel 3
My rewrite log for the url http://proba.test/mis/a-level/news.php?some=thing&other=33
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#f67a88/initial] (3) [perdir D:/bence/www/proba.test/mis/] add path info postfix: D:/bence/www/proba.test/mis/a-level -> D:/bence/www/proba.test/mis/a-level/news.php
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#f67a88/initial] (3) [perdir D:/bence/www/proba.test/mis/] strip per-dir prefix: D:/bence/www/proba.test/mis/a-level/news.php -> a-level/news.php
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#f67a88/initial] (3) [perdir D:/bence/www/proba.test/mis/] applying pattern '^a-level$' to uri 'a-level/news.php'
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#f67a88/initial] (3) [perdir D:/bence/www/proba.test/mis/] add path info postfix: D:/bence/www/proba.test/mis/a-level -> D:/bence/www/proba.test/mis/a-level/news.php
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#f67a88/initial] (3) [perdir D:/bence/www/proba.test/mis/] strip per-dir prefix: D:/bence/www/proba.test/mis/a-level/news.php -> a-level/news.php
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#f67a88/initial] (3) [perdir D:/bence/www/proba.test/mis/] applying pattern '^a-level/(.+)$' to uri 'a-level/news.php'
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#f67a88/initial] (2) [perdir D:/bence/www/proba.test/mis/] rewrite 'a-level/news.php' -> 'news.php?mode=0'
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#f67a88/initial] (3) split uri=news.php?mode=0 -> uri=news.php, args=mode=0&some=thing&other=33
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#f67a88/initial] (3) [perdir D:/bence/www/proba.test/mis/] add per-dir prefix: news.php -> D:/bence/www/proba.test/mis/news.php
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#f67a88/initial] (2) [perdir D:/bence/www/proba.test/mis/] strip document_root prefix: D:/bence/www/proba.test/mis/news.php -> /mis/news.php
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#f67a88/initial] (1) [perdir D:/bence/www/proba.test/mis/] internal redirect with /mis/news.php [INTERNAL REDIRECT]
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#253ab08/initial/redir#1] (3) [perdir D:/bence/www/proba.test/mis/] strip per-dir prefix: D:/bence/www/proba.test/mis/news.php -> news.php
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#253ab08/initial/redir#1] (3) [perdir D:/bence/www/proba.test/mis/] applying pattern '^a-level$' to uri 'news.php'
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#253ab08/initial/redir#1] (3) [perdir D:/bence/www/proba.test/mis/] strip per-dir prefix: D:/bence/www/proba.test/mis/news.php -> news.php
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#253ab08/initial/redir#1] (3) [perdir D:/bence/www/proba.test/mis/] applying pattern '^a-level/(.+)$' to uri 'news.php'
127.0.0.1 - - [11/Mar/2011:11:36:03 +0100] [proba.test/sid#713440][rid#253ab08/initial/redir#1] (1) [perdir D:/bence/www/proba.test/mis/] pass through D:/bence/www/proba.test/mis/news.php
And the log for: http://proba.test/mis/a-level
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#25f6338/initial] (3) [perdir D:/bence/www/proba.test/mis/] strip per-dir prefix: D:/bence/www/proba.test/mis/a-level -> a-level
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#25f6338/initial] (3) [perdir D:/bence/www/proba.test/mis/] applying pattern '^a-level$' to uri 'a-level'
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#25f6338/initial] (2) [perdir D:/bence/www/proba.test/mis/] rewrite 'a-level' -> 'index.php?mode=0'
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#25f6338/initial] (3) split uri=index.php?mode=0 -> uri=index.php, args=mode=0
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#25f6338/initial] (3) [perdir D:/bence/www/proba.test/mis/] add per-dir prefix: index.php -> D:/bence/www/proba.test/mis/index.php
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#25f6338/initial] (2) [perdir D:/bence/www/proba.test/mis/] strip document_root prefix: D:/bence/www/proba.test/mis/index.php -> /mis/index.php
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#25f6338/initial] (1) [perdir D:/bence/www/proba.test/mis/] internal redirect with /mis/index.php [INTERNAL REDIRECT]
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#260c1d0/initial/redir#1] (3) [perdir D:/bence/www/proba.test/mis/] strip per-dir prefix: D:/bence/www/proba.test/mis/index.php -> index.php
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#260c1d0/initial/redir#1] (3) [perdir D:/bence/www/proba.test/mis/] applying pattern '^a-level$' to uri 'index.php'
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#260c1d0/initial/redir#1] (3) [perdir D:/bence/www/proba.test/mis/] strip per-dir prefix: D:/bence/www/proba.test/mis/index.php -> index.php
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#260c1d0/initial/redir#1] (3) [perdir D:/bence/www/proba.test/mis/] applying pattern '^a-level/(.+)$' to uri 'index.php'
127.0.0.1 - - [11/Mar/2011:11:39:29 +0100] [proba.test/sid#713440][rid#260c1d0/initial/redir#1] (1) [perdir D:/bence/www/proba.test/mis/] pass through D:/bence/www/proba.test/mis/index.php
RewriteEngine On
RewriteRule ^a-level$ a-level/
RewriteRule a-level/(.*)$ $1?mode=0 [QSA]
The first rule acts as support for the second one, since the second one needs the trailing slash. You could also add [R=301,L] to the first rule to redirect the user to the version with the slash. (For real, actual folders, Apache will do just that, automatically. Since this is not a "real" folder you'd have to do it yourself.)
The second rule will simply strip the a-level part of the URL. The secret sauce, however, that makes this dish so low-calorie, is the QSA part. QSA stands for query string append. It will simply jams any existing query string to the end of the URL.
This has the added benefit that you make no assumptions about the contents of the QS. If you'd ever need to add another query variable, apart from mainid, you don't need to modify the rule.
Edit: Or, like this, if the htaccess file is in the web root.
RewriteRule ^mis/a-level$ mis/a-level/
RewriteRule mis/a-level/(.*)$ /mis/$1?mode=0 [QSA]
RewriteEngine On
RewriteCond %{query_string} mode=0
RewriteRule mis/(.+?\.php)$ mis/a-level/$1 [QSA,L]
Got it...
RewriteCond %{QUERY_STRING} ^(.*)mode(.*)$
RewriteRule mis/(.*) /mis/a-level/$1?%1 [R]
Architecture for reference:
/root/
.htaccess
/mis/
/a-level/
newsletter.php
cms.php
news.php
localhost/mis/newsletter.php?mainid=65&mode=0
now redirects to
localhost/mis/a-level/cms.php?mainid=65 - - (MODE BE GONE) :-)
No php required for param/value stripping. Pretty neat trick, if you can keep your Cond/Rules and RegEx under control. (note: an almost identical Cond/Rule may need to go directly ahead of this solution to catch the index.php file)
You can actually change the param/values as well:
RewriteRule mis/(.*) /mis/a-level/$1?blue=9 [R]
Had some help http://wiki.apache.org/httpd/RewriteQueryString
I think you are looking at this the wrong way - your main problem is translating what the PHP code needs into something that is descriptive for the URL, rather than try and accomplish this via mod_rewrite, I suggest you reconsider your approach.
Using mode=0 is meaningless within the code, and is not obvious to anyone reading the code as to what it does. I suggest changing the code to accept mode=a-level instead. this will make your mod_rewrite rule far easier, and also make your code much easier to read.
Haven't tested it on a live server, but http://www.regextester.com/ shows these output what you need
Options +FollowSymLinks
RewriteEngine on
RewriteRule a-level/(.*)\.php\?mainid=(.*)$ /mis/$1.php?mainid=$2&mode=0
RewriteRule a-level/(.*)\.php$ /mis/$1.php?mode=0
RewriteRule a-level$ /mis/index.php?mode=0

Resources