Issue with URL rewriting and parameter GET - apache

I have some problem to build my url rewrite. On my local server, working with nginx, everything is going well. But as soon as I try to make it working for apache with htacces, I kind of get crazy.
My urls are looking like this:
http://example.com/controller/action/param1/value1/param2/value2
Following is the htaccess working for the previous case:
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_URI} !^/(images|css|js)/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?$1 [L]
</IfModule>
But in some case I have some extra parameter, for example for Facebook authentication:
http://example.com/controller/action?hauth.start=Facebook&hauth.time=1382665465
This case is not working with the previous htaccess. Nothing is going in the GET variables. How could I fix this?

Use QSA (Query String Append) flag in your rule
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_URI} !^/(images|css|js)/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
</IfModule>
QSA flag makes sure to preserve an existing query string while adding new query parameters.

Related

Why are these mod_rewrite rules not working?

I have an .htaccess file that looks like the following:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+?)/(\d+?)/?$ index.php?cmd=$1&num=$2 [L]
RewriteRule ^(.+?)/?$ index.php?cmd=$1 [L]
</IfModule>
Basically, I'm trying to write an API that can handle requests like get_all/ or get/123/.
The problem is, when I try to go to either of the above URLs, the cmd parameter is always set to index.php and the num parameter is not set at all.
If I comment out either of the RewriteRule lines, then requests work for the remaining, uncommented out RewriteRule, but I need to be able to handle both cases.
I am aware of the looping that occurs with mod_rewrite, but in this case, I have no clue how to stop it. I can't even understand why the above rules are causing cmd to be set to index.php.
Can anyone please explain what is happening here and how to fix it?
Thank you.
Rules are behaving because RewriteCond is only applied to very next RewriteRule. Due to this your last RewriteRule is running without conditions and hence running twice by mod_rewrite loop.
Use this code to fix it:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+?)/(\d+?)/?$ index.php?cmd=$1&num=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+?)/?$ index.php?cmd=$1 [L]
</IfModule>
If you want to avoid repetition of Rewriteond then use:
<IfModule mod_rewrite.c>
RewriteEngine On
# skips files and directories from rewrite rules
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^(.+?)/(\d+?)/?$ index.php?cmd=$1&num=$2 [L]
RewriteRule ^(.+?)/?$ index.php?cmd=$1 [L]
</IfModule>

.htaccess Rewrite sub directory

I am trying to change my .htaccess so that when i go to http://example.com/foo it re-rewrites it to my_folder, currently if i go to http://example.com/ it re-writes to my_folder.
i have tried adding RewriteCond %{REQUEST_URI} /foo$ and RewriteCond %{REQUEST_FILENAME} /foo to the condition list but i cant seem to get it to work.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /my_folder/$1 [L]
</IfModule>
Try adding this rule:
RewriteRule ^/?foo/(.*)$ /my_folder/$1 [L]

mod_rewrite not working for query string redirect

Currently I have one rewrite rule for pretty urls, which is working fine. I tried adding in a second, and it's giving me problems:
# redirect /?p=xyz to /xyz
RewriteCond %{QUERY_STRING} ^p=(.*)$
RewriteRule ^(.*)$ /index.php/%1 [L]
# Removes index.php from ExpressionEngine URLs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
The second one is working fine, but the first one is giving me internal server error. Basically I want anything in ?p=* to go to /index.php/*
[Edit] Just to clarify, I need http://domain.com/?p=test to be equivalent to http://domain.com/test/
domain.com/test to domain.com/?p=test
Try this instead:
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} !p= [NC]
RewriteRule ^([^/]+)/? /?p=$1 [L,NC]
OPTION:
In case it is the opposite:
domain.com/?p=test to domain.com/test/index.php
Try this:
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} p=([^/]+) [NC]
RewriteRule .* /%1/index.php? [L,NC]
Remove index.php in case it is not needed, like this:
RewriteRule .* /%1/? [L,NC]

htaccess rewrite rule for backend/frontend app

I have a yii app that has separate back end and front end. I am trying to make friendly url.
I have tried some online tools but could not get it correct
So I want this url
http://mydomain.lc/abs/admin/some/crazy/urls (for example
some/crazy/urls can be admin/index)
will be rewritten to:
http://mydomain.lc/abs/backend.php/some/crazy/urls (because this
url works directly)
And I have also front end site but they are both in the same project so they share .httacess.
the rule for .htaccess for front end is:
this url:
http://mydomain.lc/abs/some/crazy/urls (some can not be admin
here, so we can differentiate btw fron and back end)
should be
http://mydomain.lc/abs/index.php/some/crazy/urls
I have:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^abs/admin/?(.*?)$ abs/backend.php?url=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(?!abs/admin\/)(.*?)$ abs/index.php?url=$1 [QSA,L]
</IfModule>
the above script is not working.
Root is under abs folder and .htaccess in the root
You do not have to change anything except RewriteBase / to RewriteBase /abs
RewriteEngine On
RewriteBase /abs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^admin/?(.*?)$ backend.php?url=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(?!admin\/)(.*?)$ index.php?url=$1 [QSA,L]
I guess the problem is with the RewriteBase.
You may try this in the .htaccess file in /abs directory:
Update according to last OP comment: this one is correct: backend.php/some/crazy/urls
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /abs
# Backend admin
RewriteCond %{REQUEST_URI} !backend\.php [NC]
RewriteRule ^admin(.*) /backend.php/$1 [QSA,L,NC]
# Frontend
RewriteCond %{REQUEST_URI} !index\.php [NC]
RewriteCond %{REQUEST_URI} !admin [NC]
RewriteRule ^(.*) /index.php/$1 [QSA,L,NC]

wordpress: mod_rewrite first "folder" name as a get parameter

I set the wordpress permalink-structure to just use the articlename and got a .htaccess that looks like this
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
works fine.
but I want to distinguish between different locations (i.e. berlin, hamburg or muenchen) in my various template files. so I thought I'd add the location to the URL like this:
http://myurl.com/berlin/articlename
and now I need to rewrite this to
http://myurl.com/articlename?location=berlin
but
http://myurl.com/articlename
or
http://myurl.com/category/articlename
should still work. just look for predefined locations (berlin|hamburg|muenchen).
how do I need to adjust the RewriteRule above to accomplish this?
So basically if what you're asking for is that http://myurl.com/(word1)/(word2)/ (i.e. only matches exactly two words, no less no more) gets internally rewritten on the server side to http://myurl.com/(word2)?location=(word1) then here it is:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule /([^/]+)/([^/]+)/$ /$2?location=$1 [QSA,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
i fixed this with the following additions to the .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} !location
RewriteRule ^(muenchen|berlin)/$ /index.php?location=$1 [NC,QSA,P]
RewriteCond %{QUERY_STRING} !location
RewriteRule ^(muenchen|berlin)/(.*)$ /$2?location=$1 [NC,QSA,P]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>