RewriteRule, url wrongly displayed - apache

I am new to mod_rewrite and I have this problem:
I have a working redirect with mod_rewrite, my .htaccess:
RewriteEngine on
RewriteRule ^microsite/([^/\.]+)/$ micrositecontroller.php?name=$1 [L]
micrositecontroller.php only echoes a text
On the browser when I enter my URL:
localhost/project/microsite/test/
I am redirected to where wanted but when I enter:
localhost/project/microsite/test
It still redirects to where wanted but the URL becomes like this:
localhost/project/microsite/test/?name=test
Now what I want is that trailing "/?name=test" not to show up.
I tried different combinations of the regex but to no avail and I have no idea if it is normal of not. Any idea?

You have a slash in your regex, so your regex handles slash... just remove it:
RewriteEngine on
RewriteRule ^microsite/([^/\.]+)$ micrositecontroller.php?name=$1 [L]

What you want is:
RewriteEngine on
RewriteRule ^microsite/([^/\.]+)/?$ micrositecontroller.php?name=$1 [L]
# Note the "?"-------------------^
To accommodate both ending with a slash and no slash. The problem with leaving the slash on (or off) is apache forces a browser redirect, thus making the ?name=test show up in the browser's location bar.
This is because mod_dir and the DirectorySlash on directive is interferring. The DirectorySlash directive tells apache to redirect the browser when it accesses what looks to be a directory (in your case localhost/project/microsite/test to the smae URI except with a trailing slash.

Related

Exclude a URL from folder redirection

I am redirecting all URLs from www.example.com/forums to www.example.com/blog/.
so I made this rule in .htaccess:
RewriteRule ^forums blog/$1 [L,R=301]
the thing is that I want to exclude some URLs that also begin with forums/ and redirect them to particular URL other than /blog.
For example, forums/8/some-made-up-word-here-1681 to /studies/some-made-up-studies.
Right now, it redirects to /blog like all URLs that start with forum/
You just need to include the more specific redirects first, before the more general rule. For example:
RewriteEngine On
# Specific redirects
RewriteRule ^forums/8/some-made-up-word-here-1681 /studies/some-made-up-studies [R,L]
# Redirect all other URLs that start /forums
RewriteRule ^forums/?(.*) /blog/$1 [R,L]
I've also modified your existing directive to redirect /forums/<something> to /blog/<something>, which I assume was perhaps the original intention, since you were using a $1 backreference in the substitution, but did not have a capturing group in the RewriteRule pattern. Your original directive would have redirected /forums/<something> to /blog/.
I've also included a slash prefix on the substitution. This is required for redirects, although you may have set RewriteBase instead, in which case you do not need to do this.
You will need to clear your browser cache before testing, since the earlier catch-all 301 will have been cached hard by the browser. For this reason it is often easier to test with temporary 302s in order to avoid the caching problem. Change the above temporary redirects to 301s only after you have confirmed this is working as intended.
UPDATE: To redirect all URLs that start /forums to /blog/, without copying the remainder of the URL, then change the last directive to read:
# Redirect all other URLs that start /forums
RewriteRule ^forums /blog/ [R,L]
Basically, the $1 in your original directive was superfluous.

Apache mod_rewrite links proxy

I want to make a proxy for external links with apache's mod_rewrite module.
I want it to redirect user from, ie http://stackoverflow.com/go/http://example.com/ to http://example.com/ where http://stackoverflow.com/ is my site's URL. So I added a rule to .htaccess file.
RewriteRule ^/go/http://(.+) http://$1 [R=302,L]
But it doesn't work at all. How to fix this?
I am not sure if Apache or the browser reduces // to /, but since it doesn't change the directory one of them reduces this to a single slash on my setup. That's why the second slash has a ? behind it in the rule below:
RewriteRule ^go/http://?(.*)$ http://$1 [R,L]
This will redirect the user to that domain.
This will rewrite all urls (without the beginning http://) to new complete URL. If you're gonna use https links also, you need something like the second rule.
RewriteRule ^go/(.*) http://$1 [R=302,L,QSA,NE]
RewriteRule ^gos/(.*) https://$1 [R=302,L,QSA,NE]
I also added the QSA if your need to include parameters

Mod Rewrite -- redirect all content from subdirectory

I have a scenario where there is a a site with subdirectories and content etc originally in a subdirectory /main
The site and all content has been moved back to the root and is working fine
We need to rewrite so that any http call to /main/, /main/page1, /main/page2 etc is redirected back to the / directory but the uri /page1, /page2 etc
This is what we have so far
RewriteCond %{REQUEST_URI} ^/main/.*
RewriteRule ^/main/(.*) /$1 [L]
Any comments welcome
Thanks very much
In .htaccess context, the url that is matched in the first parameter of RewriteRule doesn't include a leading slash and doesn't include the query string. Having a leading slash will cause the rule to never match. In your case your RewriteCond is unnecessary, as it matches exactly what the RewriteRule would match. Change your rule to the following url and it should work. Please note that this is an internal rewrite (the client won't see this change). If you need a redirect (the client will display the url without main in the address bar), add the [R] flag to the rule.
RewriteRule ^main/(.*)$ $1 [L]
See the documentation.

.htaccess mod_rewrite linking to wrong page

I have in my .htaccess the following code:
RewriteEngine On
RewriteRule ^/?([^/\.]+)/?$ $1.php [L]
RewriteRule ^/?([^/\.]+).php$ $1/ [R,L]
RewriteRule ^/?([^/\.]+)/?$ $1.php [L] is working fine. What this is doing is taking a url like http://www.example.com/whatever and making it read the page as http://www.example.com/whatever.php.
However, what I'd like to be able to do is take a url like http://www.example.com/whatever.php and automatically send it to http://www.example.com/whatever, hence the second line of the code. However, this isn't working. What its doing now, is as soon as it comes across a link ending in .php, the url becomes http://localhost/C:/Sites/page/whatever/, and pulling a 403: Forbidden page.
All I want to know is what I can to so that http://www.example.com/whatever.php will be read as http://www.example.com/whatever, and that if http://www.example.com/whatever.php is entered into the URL bar, it will automatically redirect to http://www.example.com/whatever.
Does that make any sense?
EDIT
Ok, so it appears I wasn't all too clear.. basically, I want /whatever/ to read as whatever.php while the URL still stays as /whatever/, right? However, if the URL was /whatever.php, I want it to actually redirect the users URL to /whatever/, and then once again read it as whatever.php. Is this possible?
If you're rules are inside an .htaccess file, you can omit the leading slash when you match against a URI:
RewriteRule ^([^/\.]+)/?$ /$1.php [L]
Also note that a leading slash is included in the target (/$1.php), this makes sure /whatever/ gets rewritten to /whatever.php. When you redirect, if you are missing this leading slash, apache prepends the document root to it. Thus /whatever.php gets redirected to the document root C:/Sites/page/whatever/. Even if you include the leading slash, this will never work because you're going to cause a redirect loop:
Enter "http://www.example.com/whatever.php" in your address bar
apache redirects you to "http://www.example.com/whatever/"
apache gets the URI whatever/ and applies the first rule and the URI gets rewritten to /whatever.php
The URI gets put through the rewrite engine again
the URI /whatever.php matches the second rule and redirects the browser to "http://www.example.com/whatever/"
repeat steps 3-5
You need to add a condition that the actual request is for /whatever.php:
RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /([^/\.]+)\.php
RewriteRule ^ /%2/ [R,L]
So altogether, you'll have:
RewriteEngine On
RewriteRule ^([^/\.]+)/?$ /$1.php [L]
RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /([^/\.]+)\.php
RewriteRule ^ /%2/ [R,L]
You're making a relative path substitution in a per-directory context (.htaccess is a per-directory context). This requires RewriteBase. Per-directory rewrites are done in a later stage of processing, when URLs have been mapped to paths. But the rewrite must produce a URL, which is processed again. I think without the RewriteBase to supply the URL prefix, you end up with a filesystem prefix instead of the URL. That may be why you're getting the C:/Sites thing. Try RewriteBase. But after a correct RewriteBase to specify the correct URL prefix to be tacked in front to the relative rewritten part, I'm afraid you will have the rewrite loop, because you're rewriting whatever.php to whatever; and whatever to whatever.php.
Reference: http://httpd.apache.org/docs/current/rewrite/tech.html

Who adds a slash at the end of my url?

I'm using mod_rewrite to rewrite /products to /products.php. I've got this code in /.htaccess
Options FollowSymLinks
RewriteEngine on
RewriteRule ^([a-zA-z]+)$ /$1.php [PT,L]
Unfortunately there is also a folder /products/ on my server.
My problem is, when I try to access http://mydomain.com/products my request is redirected to http://mydomain.com/products/ and showing me an error because I don't have an index for that directory.
Who is redirecting me? Apache, my UserAgent?
How do I prevent that this happens without changing the folder name or the rewrite rule?
You need to look up the "DirectorySlash Directive".
The DirectorySlash directive
determines whether mod_dir should
fixup URLs pointing to a directory or
not.
http://httpd.apache.org/docs/2.2/mod/mod_dir.html
You could also try adding an optional slash to you rewrite rule:
RewriteRule ^([a-zA-z]+)/?$ /$1.php [PT,L]
Trailing slashes problem
You have probably enabled MultiViews on your Apache.
Every browser is adding the trailing slash after your request if it doesn't by ".something" because it thinks it is a folder. To avoid this, your rewrite rule should look like this:
RewriteRule /products(.*)$ /index.php?page=products
OR
RewriteRule /products /index.php?page=products
That way, it will rewrite every request with "/products" in it, with or without the trailing slash.
The only thing is your folder /products/ will not be accessible by an http request. If you want so, you must change the name of the folder or the page name.