URL rewrite issues using .htaccess - .htaccess

I'm trying to write a URL like below, but when I try to call the seo queryparam, it always returns index.php. Any idea why it isn't returning the correct value for 'seo'?
RewriteRule ^([^/]*)$ index.php?c=home&m=details&seo=$1 [L]
The URL it should forward from would be something like this: http://domain.com/The-Name-of-the-Product. That URL should be rewritten to http://domain.com/index.php?c=home&m=details&seo=The-Name-of-the-Product, but instead it ends up as http://domain.com/index.php?c=home&m=details&seo=index.php

Various events cause a URL to go back through the rewrite process. You can use RewriteCond to prevent this:
RewriteCond $1 !^index.php$
RewriteRule ^/?([^/]+)$ index.php?c=home&m=details&seo=$1 [L,NS]
From the mod_rewrite technical details:
When you manipulate a URL/filename in per-directory context mod_rewrite first rewrites the filename back to its corresponding URL (which is usually impossible, but see the RewriteBase directive below for the trick to achieve this) and then initiates a new internal sub-request with the new URL. This restarts processing of the API phases.
This catches people all the time.

Related

Redirect all URLs starting with https:// to same URLs starting with http://

I've been looking for this solution but can't get it anywhere.
I have a website (shop) with SSL set up on it, working fine except in the area where customers would get an URL to the file they just purchased.
So, my working url to a download file should look something like this:
https://www.mywebsite.com/index.php?eddfile=123456etc
But the files only work if you browse them without HTTPS prefix:
http://www.mywebsite.com/index.php?eddfile=123456etc
So what I need is just to remove the https from these URLs that start with:
https://www.mywebsite.com/index.php?eddfile
And redirect them to the same URLs but without https prefix rather with regular prefix:
http://www.mywebsite.com/index.php?eddfile
Note: this is not a regular https to http (or vice versa) redirection for which I found answers here - Although this should be a simple .htaccess redirection, I need to make sure that this only happens to the urls that are beginning as described above
I tried to do something like this:
RewriteEngine On
RewriteCond %{REQUEST_URI} eddfile
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]]
But no success with that
As Martin suggests in comments, the real solution would be to fix why your HTTPS URL does "not work". (But also, why not just link directly to the HTTP URL if that "works"?)
Anyway, to answer your specific question... try the following near the top of your .htaccess file instead:
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteCond %{QUERY_STRING} ^eddfile=.
RewriteRule ^index\.php$ http://%{HTTP_HOST}%{REQUEST_URI} [R,L]
This is only a "temporary" (302) redirect, since this is only a "temporary" fix.
eddfile is part of the query string, not the URL-path. The query string is automatically passed through to the substitution, providing you don't provide a query string.
Since you say the HTTP URL "works" then I assume you don't have an HTTP to HTTPS redirect?? Otherwise, you would need to include an exception with this redirect in order to avoid a redirect loop.

Using mod_rewrite to mask a directory/file name in a URL

I've taken my site down for some prolonged maintenance and am using mod_rewrite to send all requests to a single page: www.mysite.com/temp/503.php
This is my .htaccess file which works fine.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/temp/503.php [NC]
RewriteRule .* /temp/503.php [R,L]
However, what I'd also like to be able to do is to hide /temp/503.php in the resulting URL from the visitor.
I know this is perhaps trivial and I'm sure fairly simple to achieve, but with my limited mod_rewrite skills I can't seem to get it to work.
Any help would be much appreciated.
Thanks.
Just get rid of the R flag in the rewrite rule, which tells the rule to redirect the request, thus changing the URL in the browser's location bar. So the rule would look like:
RewriteRule .* /temp/503.php [L]
which internally rewrites the requested URI instead of externally telling the browser that it's been moved to a new URL.

I changed the structure of my site to reach index cards

Excuse me for my english.
I make a brands directory web site.
Before to acces to the brands pages I use requests like this :
mydomain.com/fiche.php?id=115
where id is the id of the brand in my directory
I change the structure of the brands pages and now use this request:
mydomain.com/annuaire.php?type=fiche&id_marq=115
where id has become id_marq
I try to use a rewritebrule like this:
RewriteRule ^fiche.php$ http://www.annuaire-sites-officiels.com/annuaire.php?detail=fiche&id_marq=$1 [L,QSA,R=301]
to redirect the old links to the new pages but result dont pass the id_marq value and the url is:
http://www.annuaire-sites-officiels.com/annuaire.php?detail=fiche&id_marq=&id=115
&id= is too.
What am I doing wrong?
Your rule is not evaluating query string and that's why its not capturing id query parameter.
Change your code to:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^id=([^&]+) [NC]
RewriteRule ^fiche\.php$ /annuaire.php?detail=fiche&id_marq=%1 [R=302,L,QSA,NC]
Once you verify it is working fine, replace R=302 to R=301. Avoid using R=301 (Permanent Redirect) while testing your mod_rewrite rules.
Check out Regex Back Reference Availability:
You have to capture the query string. [QSA] passes it forward unaltered, so unless you're using id for anything you don't need that bit of code. Your 301 redirect is correct since this is a permanent redirect. Remember if you add a failed redirect your browser may cache that redirect so it might not look like it's working.
In this string match I'm only catching numbers to prevent someone from passing something like an asterisk * and XSS exploiting your site.
I've not included and [NC] matches in my code because when you allow multiple cases they can seem like different URLs to search engines (bad for SEO).
RewriteCond %{QUERY_STRING} id=([0-9]+)
RewriteRule ^fiche.php$ http://%{HTTP_HOST}/annuaire.php?detail=fiche&id_marq=%1 [R=301,L]

.htaccess and SEO URLs - why is this an infinite loop?

I have a dirty URL like this: http://www.netairspace.com/photos/photo.php?photo=3392.
I want to do something like http://www.netairspace.com/photos/OH-LTU/Finnair_Airbus_330-202X/OUL_EFOU_Oulu/photo_3392/ (and later support short URLs like http://www.netairspace.com/pic/3392/ but I'll leave that out).
So I have a script photo_seo_url.php, which takes the photo ID, builds the SEO URL, and does a redirect (302 for testing, 301 when I'm happy with it). I then planned to add .htaccess mod_rewrite rules so that on calling the old URL:
the old URL would be rewritten internally to photo_seo_url.php
photo_seo_url.php would 301/302 redirect to the SEO URL
the SEO URL would be rewritten internally to the original photo.php
That way I would, in theory, get the benefits of the SEO URL while being able to retire the old ones at my leisure.
These are the rules I used:
RewriteEngine on
RewriteRule ^photos/.*/photo_([0-9]+)/?$ photos/photo.php?photo=$1 [NC,L]
RewriteCond %{QUERY_STRING} photo=([0-9]+)
RewriteRule ^photos/photo\.php$ photos/photo_seo_url.php?photo=%1 [NC,L]
But that goes into an infinite redirect loop. Why, if these two are doing internal rewrites rather than external redirects - or is that what I'm missing?
I've solved the problem adding a new file showphoto.php, which does nothing but include the original photo.php, and changing line 2:
RewriteEngine on
RewriteRule ^photos/.*/photo_([0-9]+)/?$ photos/showphoto.php?photo=$1 [NC,L]
RewriteCond %{QUERY_STRING} photo=([0-9]+)
RewriteRule ^photos/photo\.php$ photos/photo_seo_url.php?photo=%1 [NC,L]
But I'd still like to understand why the original version goes into an infinite loop. I've missed or misunderstood something. Is my approach sound?
To answer your question, why does this loop occur? This is what happens with an SEO URI, with a GET /photos/OH-LTU/Finnair_Airbus_330-202X/OUL_EFOU_Oulu/photo_3392/, say.
Rule 1 fires converting this to a GET /photos/photo.php?photo=3392 which triggers an internal redirect which then restarts the scan of the .htaccessfile.
Rule 2 then fires converting this to a GET photos/photo_seo_url.php?photo=339 which triggers an internal redirect which again restarts the scan of the .htaccessfile.
No further matches occur and hence this is passed to the script photos/photo_seo_url.php which then does a 302 to /photos/OH-LTU/Finnair_Airbus_330-202X/OUL_EFOU_Oulu/photo_3392/ and the browser detects a redirection loop.
What you need happen is for rule 1 firing to prevent rule 2 firing even after an internal redirect. One way to do this is to set an environment variable, say END (which gets converted to REDIRECT_END on the next pass) and to skip the rules if this is set:
RewriteEngine on
RewriteBase /
RewriteRule ^photos/.*/photo_([0-9]+)/?$ photos/photo.php?photo=$1 [NC,E=END:1,L]
RewriteCond %{ENV:REDIRECT_END}:%{QUERY_STRING} ^:photo=([0-9]+)$
RewriteRule ^photos/photo\.php$ photos/photo_seo_url.php?photo=%1 [NC,L]
An alternative approach is to add a dummy noredir parameter to the rewritten URI and add a:
RewriteCond %{QUERY_STRING} !\bnoredir
to the original second rule. However, photo.php would need to ignore this. Hope this helps :-)
RewriteEngine on
RewriteRule ^photos/.*/photo_([0-9]+)/?$ photos/photo.php?photo=$1&rewritten [NC,L]
RewriteCond %{QUERY_STRING} !rewritten
RewriteCond %{QUERY_STRING} photo=([0-9]+)
RewriteRule ^photos/photo\.php$ photos/photo_seo_url.php?photo=%1 [NC,L]

.htaccess to rewrite a get variable to something more elegant

I have just finished writing a new site. It is a simple blog. The only advice I have received from my readers is that I should consider changing the www.example.com/?page=3 to something like www.example.com/1.
How should I go about writing this rewrite rule?
If your URLs have a common pattern and parts of the externally used URL can directly be mapped onto the internally used URL while retaining a uniquely identifiable URL (like your URL probably does), you can do something like this with mod_rewrite:
RewriteEngine on
RewriteRule ^[0-9]+$ /?page=$1 [L,QSA]
This will rewrite a request of /12345 internally to /?page=12345.
Otherwise, if there isn’t a pattern or the mapping is not trivial, you will probably need to specify each case like:
RewriteEngin on
RewriteRule ^foo$ /?page=1 [L,QSA]
RewriteRule ^bar$ /?page=2 [L,QSA]
RewriteRule ^baz$ /?page=3 [L,QSA]
You could also just pass the request to your PHP file and do the mapping in there.

Resources