Why is this .htaccess not silently redirecting? - php

Can anyone tell me why the following visibly changes the URL in the browser, rather than redirecting silently? The redirect works, but visibly.
Example URL: http://domain.com/_test/sportswire/uk/football/huddersfield
...visibily redirects with query string arguments showing.
RewriteEngine on
RewriteBase /_test/sportswire
#favour naked domain over www
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^(.*) http://%1/$1 [R=301,NE,L]
#disallow trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
###THIS RULE### channel pages - territory/sport/channel/[res type?]
RewriteRule ^(\w+)\/(\w+)\/(\w+)(?:\/(\w+))?$ channel.php?territory=$1&sport=$2&team=$3&res_type=$4 [L,NC,R=301]
#channel pages - with item (if from external referrer) - territory/sport/channel/res_type/"item"/item_id/pretty
RewriteRule ^(\w+)\/(\w+)\/(\w+)\/(\w+)\/story\/\w{11}\/[^\/]+$ channel.php?territory=$1&sport=$2&team=$3&res_type=$4&item=$5 [L,NC,R=301]
What I've tried/read:
Remove the R flag (no joy; and I have other .htaccess files with R flags that redirect silently)
Add/remove a rewrite base (done; also tried an absolute one)
Don't use absolute URLs (I'm not)
I'm fairly convinced there's nothing on planet earth quite as perplexing as mod-rewrite.

Try removing the [R] flag altogether, so that the server won't notify the browser of the change.
htaccess changes take effect immediately, so you don't need to restart the server. However, since you previously tried R=301, your browser may remember to go straight to the URL with the query string and never even ask the server for the URL you're trying to redirect. To see the effect of the change I recommended, start a new browser instance in incognito or private browsing mode and test the new rule.
Side note: why are you escaping all the / in your paths? I don't think you need to.

[R] flag should not be there. Try restarting Apache if that is possible, I've noticed that it helps sometimes.
Try another browser or different URL, they can cache redirects.

Related

htccess redirect all .php?123 to another url

How to redirect all urls with .php? to only .php ?
I´m using
RewriteEngine On
RewriteRule ^(.+\.php)/.*$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?secure/(.*) https://example.org$1 [R,L]
How can i prevent somone using urls that doesn´t exist on my server?
It´s all about blocking everything that comes after .php like ?123456789
Why should it be an issue if someone adds a query string to a URL? Unless your php scripts react to that, of course, but that is something you can control, can't you?
Nevertheless it certainly is possible to drop such query strings if you want to:
RewriteEngine on
RewriteCond %{QUERY_STRING} !^$
RewriteRule \.php$ %{REQUEST_URI} [QSD,R=301,L]
For this to work the apache rewrite module needs to be loaded into the http server, obviously.
It is a good diea to start with a R=302 temporary redirection first. And to only change that to a R=301 permanent redirection once everything works as desired. That prevents nasty caching issues for your users.
You should prefer to implement such rules in the actual http server's host configuration. If you have no access to that you can also use a distributed configuration file (".htaccess"), but that comes with a few disadvantages. And has to be enabled first.

.htaccess URL rewrite works, but address bar then shows 'dirty' URL

User clicks link (from their email): http://www.site.com/edit/wih293f73y
Browser window opens and gets them to the correct page.
But now the browser's address bar shows: http://www.site.com/editor.php?editCode=wih293f73y
Extra info:
My rewrite rule is:RewriteRule ^edit/([A-Za-z0-9-]+)/?$ editor.php?editCode=$1 [NC,L]
This problem ONLY occurs when the user has clicked a link. It works perfectly when you just type the pretty url into the address bar.
This problem ONLY occurs for links that include the www. - the link http://site.com/edit/wih293f73y works like a charm.
My .htaccess file includes the following code (from HTML5 boilerplate, which I wasn't aware of previously):
# Rewrite www.example.com → example.com
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
</IfModule>
If it's important, this occurs after my other rewrite rules.
I just took a look and it is apparent that your www rules is causing this. Question is do you want it be fixed? If you do then move this rule on top of all other rules and your problem should be fixed.
Move this to top of all other rules
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
You can use use the redirect directive
redirect 301 ^edit/([A-Za-z0-9-]+)/?$ editor.php?editCode=$1
There are some pros and cons to this strategy. The pros being;
It's super fast. You don't even need to load up your application for this to work.
It's minimal code.
Redirects are an intrinsic part of Apache (or any http server) and aren't going anywhere soon.
The cons being;
It's not part of your application proper. Should you decide to change logic or URLs, you'll have to change this, too.
It's slower, as you need to invoke php, as opposed to just having Apache issue the redirect.

Rewriting url with htaccess when a directory exists

I'm trying to redirect a dynamic page to a dir, example:
url.com/index.php?page=download
to
url.com/download
The rule is very simple:
RewriteRule ^download$ /index.php?page=download
FULL .HTACCESS
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.url\.com$
RewriteRule ^(.*) http://url.com/$1 [R=301,L]
Redirect 301 /index.php?page=download http://url.com/download
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
RewriteRule ^download$ /index.php?page=download
The problem is that I already have a directory named "download" and it's returning me a "403 Forbidden Error".
I have noticed that renaming the directory to anything different than the name (download) the rule is using will work.
So, my question is: how can I have my url rewritten the way I need and keep the directory?
-- EDIT --
My server, by default, protects every directory with a "403 Forbbiden Error". I believe this is the reason why it's not working, but I'm not sure.
Is it a conflict indeed?
What is happening?
/download/?page=download
The reason why this is happening is because somewhere mod_dir redirects all requests for directories that are missing the trailing slash to include the trailing slash. This is interferring with your rewrite rule. Since your server is automatically setup to deny listing of directories, it's probably safe to go ahead and turn directory slashes off:
DirectorySlash Off
Answer by: https://stackoverflow.com/users/851273/jon-lin
Your problem is, I think, due to this specific rewrite rule:
RewriteRule .* - [L]
Apache will read your htaccess in detail, line by line, and will try to map each rewrite rule in turn (+ conditions, obviously). Let's follow it in detail.
RewriteCond %{HTTP_HOST} !^www\.url\.com$
RewriteRule ^(.*) http://url.com/$1 [R=301,L]
These two by themselves are NOT fine but not the source of your problem. If the HTTP HOST is anything but www.url.com, it will redirect to http://url.com/... which is not www.url.com, which will then redirect to url.com. You have a potential infinite loop but only if the HTTP HOST is not www.url.com to start with. If it matched, due to the L flag, it breaks processing and returns the redirect.
Redirect 301 /index.php?page=download http://url.com/download
This line is fine. You're doing a 301 redirect to anyone who happens to know index.php?page=download.
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
This line is NOT fine. The rewrite condition specifies that, so far, anything that is not a redirect from above will work for the next rule. The next rule matches EVERYTHING (.* means everything. 0 or more characters of anything) and in-rewrites to -, which in mod_rewrite language is a do not touch flag. This is fine. However, the L flag breaks the chain and returns, which causes your download/ folder to show as the list of your actual download folder, which is the source of your 403 error.
Remove the L flag to get the next rule to process:
RewriteRule ^download$ /index.php?page=download
Which is fine by itself.

Strange Rewriting (Apache mod_rewrite)

I'm very much confused about the result of my rewrite-rules. I use WAMP to host on my local machine.
RewriteEngine on
RewriteBase /niklasrosenstein/
RewriteCond %{REQUEST_URI} !res/(.+)$
RewriteCond %{REQUEST_URI} !index.php$
RewriteRule ^(.*)$ index.php?uri=$1 [QSA]
Going to
http://localhost/niklasrosenstein/res
expands to
http://localhost/niklasrosenstein/res/?uri=res
in the browsers' address-bar. I have tested it under Firefox 14, Opera 11.62 and Internet Explorer 8.
Adding a slash at the end of the URL, which would be
http://localhost/niklasrosenstein/res/
is ok.
Does anyone know why the URL is adjusted in the browsers' address-bar? I want to use mod_rewrite in order to get rid of the fuzzy URL formatting, but that issue actually breaks it down..
Does anyone know why the URL is adjusted in the browsers' address-bar?
This looks like a mod_dir/mod_rewrite conflict. By default, mod_dir is loaded, and the directory module's defaults are to have:
DirectoryIndex index.html
DirectorySlash On
The second default makes it so anytime a request appears to access a directory, and is missing a trailing slash, 301 redirect to the same URI with the slash. This happens somewhere in the URI-file mapping pipeline and is interferring with the internal rewrite that mod_rewrite applies via your rules
Since you are routing everything through index.php, it may not be detrimental to turn off DirectorySlash, so in the htaccess file in your /niklasrosenstein/ directory, try turning it off:
DirectorySlash Off
Otherwise, you can try handling that using mod_rewrite:
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond !.+[^/]$
RewriteRule ^(.+)$ $1/ [L]

htaccess redirect without user knowing

We are running multiple domains through the same code and we want to save their images in their respective folders. Here's what we are doing.
/images/www.domain1.com/logo.jpg
/images/www.domain2.com/logo.jpg
now, what I want to know is, is this possible in htaccess that we rewrite the urls without user suspecting anything. This is what I want that
<img src="/images/logo.jpg" />
should internally become through htaccess
RewriteRule ^images/(.*)$ /images/{HTTP_HOST}/$1 [L,R=301]
But my question is,
The above redirect continually loops
Can I achieve the img effect without user or admin suspecting anything?
Sincerely,
Khuram
Remove the R=301 to simply do a rewrite rather than a redirect:
RewriteRule ^images/(.*)$ /images/{HTTP_HOST}/$1 [L]
The reason it's continually looping is that the 301 redirect causes a new request to be created for the url images/www.domain1.com/logo.jpg. That URL also matches your ^images/(.*)$ rule, so it is redirected again, ad infinitum.
If you really want to do a 301 redirect (I suspect you don't, but if you did), you could solve the infinite looping problem by adding some rewrite conditions to skip the redirect if the domain is already included:
RewriteCond {REQUEST_URI} !^images/www.domain1.com/(.*)$
RewriteCond {REQUEST_URI} !^images/www.domain2.com/(.*)$
RewriteRule ^images/(.*)$ /images/{HTTP_HOST}/$1 [L,R=301]
You definitely should not use R flag if you don't want to change URL in browser. However even without R flag your RewriteRule will loop infinitely and you will eventually get internal server error. Use RewriteRule like this:
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteRule ^images/(.*)$ images/%{HTTP_HOST}/$1 [L,NC]
Which is using a special internal variable called {ENV:REDIRECT_STATUS} that is set to 200 once RewriteRule rule is applied successfully.

Categories