Correct .htaccess RewriteCond? - .htaccess

I have spent hours looking for a solution, but .htaccess rules seem way over my head. I have this rule:
RewriteRule ^(.*)$ wikka.php?wakka=$1 [QSA,L]
and I need it to be applied only if there is anything beyond the domain name, ie. www.example.com/xyz but NOT with just www.example.com because then I only need to display a simple index.php instead {no address translation}.
How do I do that?

RewriteRule ^(.*)$ wikka.php?wakka=$1 [QSA,L]
You just need to change the * (0 or more) in the RewriteRule pattern to + (1 or more). For example:
RewriteRule (.+) wikka.php?wakka=$1 [QSA,L]
I also removed the anchors ^ and $, since they are not necessary here. You are grabbing everything anyway, so saying you are grabbing everything from the start to the end is just not necessary.
Also, unless you require the query string from the original request I would remove the QSA flag. By itself this rule will result in a repeated query string of the form ?wakka=wikka.php&wakka=xyz - where xyz is the intial request. This still "works" if reading the URL params with PHP as wakka=xyz will override the earlier parameter.

Related

Mod rewrite to redirect except on a certain page

Trying to write a rewrite rule in my htaccess so that any request to /en/shop/index.html or /fr/shop/index.html stays on the server, but if the user goes to any other page it redirects to a different server. Here's what I've got so far and it doesn't work.
RewriteRule ^(.*)/shop/(.*) [L]
RewriteRule ^(.*)$ http://www.newwebsite.com/$1 [R=301]
Add a dash to tell the first RewriteRule that you want the matches to be passed through unchanged:
RewriteRule ^.*/shop(/.*)?$ - [L]
I also removed the first set of parentheses since you're not using the results of the match so there's no need to store the matched patterns. I assumed you might need to match /shop without a trailing slash so that's why the (/.*)? section is there.

htaccess redirect with php variables ...

I'm using this format in my htaccess to redirect several pages/links:
RewriteEngine On
RewriteRule special.php http://www.mysite.com [R=301]
...
...
RewriteRule http://www.mysite.com/special.php?t=master http://www.mysite.com/index.php?q=former [R=301, L]
I noticed, first, that only the top line is catching anything, and in fact the others, like the bottom line, did nothing until I put in that top line. Any ideas why?
Second, mysite.com/special.php?t=grave is redirected, by the above top line, to mysite.com/?t=grave , thus retaining the variables in the URL. I don't want this, I simply want it to go to mysite.com with no variables. How do I do this?
Thanks,
Derek
First, your first rule catches any URI with special.php in it, even if it is followed by a bunch of characters. To limit it to only and exactly special.php, and to make sure the query string is discarded, change it to
RewriteRule ^special.php$ http://www.mysite.com/? [L, R=301]
Secondly, rewrite rules only match the part after http://www.mysite.com/ (note the last slash) and before the query string (the part after the question mark). So if you change the format of those rules to
RewriteCond %{QUERY_STRING} t=master
RewriteRule ^special.php$ index.php?q=former [R=301, L]
you should be good to go.

mod_rewrite doesn't actually... re-write the URL

Basically, I've been trying to make some friendly URL's via .htaccess using mod_rewrite - and I've managed to get it to work... but only with basic stuff like:
RewriteEngine On
RewriteBase /
RewriteRule ^profile.php http://www.google.co.uk [L]
So mod_rewrite works, and I can re-direct to other sites, other files/directories in my server, etc. - but it seems to not work when I use this:
RewriteEngine On
RewriteBase /
RewriteRule ^profile.php?user=$1 ^profile/user/([^/]*)/$ [L]
Any help on this would be great, as I pretty much suck at mod_rewrite, but it's something I need to learn.
Cheers!
Change your [L] to [R,L] to force an actual HTTP redirect. Otherwise it just does the rewriting internally (when possible), which only affects the mapping from the URI to the filesystem. (See the description of the [R] flag at http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteflags.)
Wrong.
## rewriting from to
RewriteRule ^profile.php?user=$1 ^profile/user/([^/]*)/$ [L]
Should be
## rewriting from to
RewriteRule ^profile/user/([^/]+)$ profile.php?user=$1 [L]
Your configuration currently is this:
RewriteEngine On
RewriteBase /
RewriteRule ^profile.php?user=$1 ^profile/user/([^/]*)/$ [L]
In the RewriteRule you swapped the from and to parameters.
Assuming that on your server there is a directory structure like this:
/var/www/htdocs/profile/user/albert
/var/www/htdocs/profile/user/bob
Then you can use the following rule:
RewriteCond ${QUERY_STRING} ^user=(\w+)$
RewriteRule ^profile\.php$ profile/user/%1 [L]
There are some points that you got wrong here:
The request to "/profile.php?user=bob" first gets split into the Request URI and the Query String. Only the Request URI will be used by mod_rewrite. Therefore you have to handle the query string separately.
I restricted the user name to only [A-Za-z0-9_]. If I had allowed all characters, an attacker could easily call /profile.php?user=../../config.php, which would be rewritten to profile/user/../../config.php, and you probably don't want to share that file with the world.
The arguments to the RewriteRule directive are completely different regarding their syntax.
The first argument (the from part) is a regular expression, which usually starts with a caret ^ and ends with a dollar $.
The second argument (the to part) is the replacement, which is almost only a simple string, with only some special features. This string usually doesn't start with a caret, but looks rather like a pathname.

.htaccess mod-rewrite conditional statements and sending GET request?

Not necessarily a problem, just something that I am not yet knowledgeable enough to do. I have an .htaccess file that I am using for url rewriting. This is what I have now.
ErrorDocument 404 /inc/error_documents/404.php
ErrorDocument 503 /inc/error_documents/503.php
# For security reasons, Option followsymlinks cannot be overridden.
#Options +FollowSymLinks
Options +SymLinksIfOwnerMatch
RewriteEngine ON
RewriteRule ^home$ /index.php [nc]
RewriteRule ^(about|contact|giving-tree)/?$ /$1.php [nc]
RewriteRule ^giving-tree/([0-9+]?)/?$ giving-tree.php?ageBegin=$1 [nc]
RewriteRule ^giving-tree/([0-9+]?)/([0-9+]?)/?$ giving-tree.php?ageBegin=$1&ageEnd=$2 [nc]
RewriteRule ^giving-tree/([0-9+]?)/([0-9+]?)/([0-9+]?)/?$ giving-tree.php?ageBegin=$1&ageEnd=$2&page=$3 [nc]
What I want to be able to do is make some of the parts in the 3 bottom rules optional. I know that I can accomplish this with RewriteCond, but I'm not sure how. What I need is basically this:
RewriteCond %{HTTP_HOST} ^hearttohandparadise.org/giving-tree
RewriteRule /beginAge-([0-9+]) #make it send GET request with beginAge as the variable
RewriteRule /endAge-([0-9+]) \?beginAge=$1 #make it send GET request with endAge as the variable
etc... etc...
Is there any way to accomplish this just by relying on .htaccess? or am I just fantasizing?
Forgive me is I sound stupid.
No, it's a perfectly valid idea. You'd basically want to allow the user to write the URI in an unstructured manner, without a strict order imposed, right? Like, I could write giving-tree/page-6/endAge-23?
If so, this is what you're looking for:
RewriteRule /beginAge-([0-9]+) giving-tree.php?beginAge=$1 [QSA,NC]
RewriteRule /endAge-([0-9]+) giving-tree.php?endAge=$1 [NC,QSA]
RewriteRule /page-([0-9]+) giving-tree.php?page=$1 [NC,QSA]
You see, if any part of the URI matches the expression "/beginAge-([0-9]+)", it'll be redirected to giving-tree.php?beginAge=$1; the magic is done by the QSA, Query String Append, option, which, well, appends any existing query string to the resulting URI. So as more and more matches are found and more and more GET parameters added, the query string just grows.
If you want a stricter thing, where some parameters are optional, but their order is fixed, then it's uglier by magnitudes:
RewriteRule /(beginAge-)?([0-9]+)/?(endAge-)?([0-9]+)?/?(page-)?([0-9]+)? giving-tree.php?beginAge=$2&endAge=$4&page=$6 [NC]
I just made everything optional by using the ? operator. This one may use some prettifying/restructuring.
(Alternatively, you could just do this:
RewriteRule ^giving-tree/([^/]+)/?$ process.php?params=$1 [nc]
That is, grabbing the entire part of the URI after the giving-tree part, lumping the whole thing into a single parameter, then processing the thing with PHP (as it's somewhat better equipped to string manipulation). But the first version is certainly more elegant.)
By the way, are you sure about the ([0-9+]?) parts? This means "One or no single character, which may be a digit or the plus sign". I think you meant ([0-9]+), i.e. "one or more digit".

Apache / Linux - .htaccess how to get specific variable from a query / url and apply to rewrite

I have a rule that works for one "direction" but, not the other.
A typical incoming url / query would be: (long url)
http://somedomain.com/getme.pl?dothis=display&partnum=1234567 (could be up to 9 digits)
I have this rule in place in my htaccess file:
RewriteRule ^([0-9]*)$ /getme.pl?dothis=display&partnum=$1 [L]
Which works great for a bit of ease getting one of the unique part numbers:
http://somedomain.com/1234567.
However, I would like to make the long url "pretty" so, I assumed I could reverse(ish) it.
So, when a link on the site is clicked on (the long url) the htaccess file would process the long url to the beautified version.
I tried MANY attempts.
Here was my latest failure.
RewriteRule ^([0-9]*)$ /getme.pl?dothis=display&partnum=$1 [L] #(works)
RewriteCond %{QUERY_STRING} ^partnum=([0-9]*) #(tried to get partnum)
RewriteRule ^.* http://%{HTTP_HOST}/%1 [R] #(make the short url)
RewriteRule ^([0-9]*)$ /getme.pl?dothis=display&partnum=$1 [L] #(the known working rule)
I have tried a plethora of rules and visited many sites for advice.
I tried with just rules, just conditions and variations of query_string.
So, I believe I must just grab the "partnum" from the query and rewrite to /1234567 or http_host/1234567
Then, allow the other rule (works) to process.
So BOTH:
http://somedomain.com/getme.pl?dothis=display&partnum=1234567
and
http://somedomain.com/1234567
Display as: http://somedomain.com/1234567 in the browser.
and both passed the whole query to the getme.pl script properly.
I found some close answers here but, none that really explained what I needed.
Can someone please help?
From the sounds of it, this should get you moving down the right path:
# Your working rewrite, with extra param on the rewrite
RewriteRule ^([0-9]*)$ /getme.pl?dothis=display&partnum=$1&rewrite [L]
# Redirect for long urls, to pretty url
# -The appended '&rewrite' on the first rule will force this not to match
# -The trailing '?' on the rewrite will strip the query string
RewriteCond %{QUERY_STRING} partnum=([0-9]*)$
RewriteRule (.*) /%1? [L,R=301]
Hope that helps.

Resources