Redirect to full URL with htaccess RewriteRule - apache

I want to load images from production website if they don't exist on my local environment, for that, I have this htaccess rule:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule uploads/(.*)$ http://www.productionserver.com/uploads/$1 [R=302,L,NC]
The problem:
Original URL:
http://localhost:8080/myproject/uploads/image.jpg
Output:
http://localhost:8080/myproject/http://www.productionserver.com/uploads/image.jpg
Desired output:
http://www.productionserver.com/uploads/image.jpg
What must I change in order to achieve that?

The code was correct.
I moved it to the top of my .htaccess file and it worked. Some other rule was interfering with it.
I believe the tool I was using to debug the "Output" was wrong. The tool is: http://htaccess.madewithlove.be
Thanks everyone who replied on the comments.

Related

htaccess mod_rewrite - rewrite folder and file to parameters

I have the follow folder structure for images:
http://www.localhost/memes/01/blaa.jpg
http://www.localhost/memes/02/blaa2.pg
etc.
Now I want to move the structure but the old one must still be available for PHP file.
So it should be rewritten like:
http://www.localhost/memes/01/blaa.jpg
to:
http://www.localhost/memes/?folder=01&pic=blaa.jpg
or to:
http://www.localhost/memes/?pic=blaa.jpg (ignoring the subfolder of memes)
yes it's www.localhost for what ever reason and I don't mind it so far :D
Could you please try following, written and tested with your shown samples. Please make sure you clear your browser cache before testing your URLs.
RewriteEngine ON
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^memes/([^/]*)/(.*jpg)$ memes/?folder=$1&pic=$2 [NC,L]

mod_rewrite - Removing index.php from URL (in subfolder)

I'm trying to get an API working (locally, for now), which lives in a subfolder. I've been trying every example I can find, but all are ending up in 404 errors.
I have this URL:
http://127.0.0.1/~owner/personal/api/v1/index.php/tasks
I want to be able to use this:
http://127.0.0.1/~owner/personal/api/v1/tasks
Eventually, it will become this:
http://api.mydomain.com/tasks
I just can't seem to get my .htaccess rules setup correctly. This keeps getting suggested, but does nothing:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
What am I missing?
Update
I have setup my virtual hosts to use http://api.local/ instead of the previously used addresses.
Accessing http://api.local/index.php/tasks works.
Accessing http://api.local/tasks does not.
Maybe part of your problem is your development environment. You are using a local server to do this on with several subfolders deep and I think it's messing with your .htaccess depending on the location.
If your .htaccess is in the root of your website http://127.0.0.1/.htaccess then it's not going to work properly.
Make sure it's in the same directory as your index.php file and make sure /~owner/personal/api/v1/ is your document root for your dev environment as specified in your apache config file.
Then you can test out your htaccess rules and see how they work. Your current rule should be ok providing /tasks won't be a real directory in the root.
On another note,
I always suggest using your real domain name so you could see how it works as if it were in production. You can do that by modifying your HOST file on your PC and the site will only available to you and you can access via yoursite.com. This quick easy guide will show you.
Try specifying the rewrite base.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
You are using the parameters of RewriteRule backwards. You need this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*?)/index.php(.+)?$ /$1$2
This means:
if it's not a file
and it's not a directory
and it looks like / (optional), possibly some more characters, then /index.php, then possibly some more characters, go to the URL without the /index.php part.
Note that I deleted the [L] for now -- it means "if the URL matches this rule, don't apply any more rules." You say you want to keep transforming it into http://api.mydomain.com/tasks, so you shouldn't use [L].

Forwarding all htm file extensions to a a specific file

I have been given a task to change 100's of .htm files on a site to only show the contact page. As appose to changing the files I am thinking to just use a .htaccess file and force all requests which includes a ".htm" or ".html" to the contact.htm page.
I have very limited knowledge about .ht_access files and the one I have which forces all requests through a index.php isn't working because one of the rewrite conditions is to check whether the file is real or not.
Any advice or tips will greatly be appreciated:
// My .htaccess rules at the moment:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ contact.htm [NC,L]
You can try something like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[^\.]*\.htm$ contact.htm [NC,L]
This will replace everything that ends with .htm to contact.htm
EDIT: Made a mistake, checked it and fixed it
If you want to maintain your SEO and prevent link rot (which is bad), you'll want to let the client know that the old HTML file is no longer valid:
RedirectMatch 301 ^.*html?$ http://example.com/contact.html
Edit: as an interesting side note, returning a 410 might be a more appropriate response.

Why won't this mod-rewrite rule work?

I have a development site on my machine at
localhost/~Jason/hfh/admin/?admin=collections
My .htaccess file is in the /hfh/admin/ directory. It says:
RewriteEngine On
RewriteBase /~Jason/hfh/
RewriteRule ^([A-Za-z0-9\-\_]*)$ index.php?admin=$1
But when I go to
localhost/~Jason/hfh/admin/collections
I get a "page not found" error. Can anyone tell me why?
(This is related to another question at this link.)
If you have the .htaccess file in /hfh/admin/ make that the base to begin with.
RewriteBase /~Jason/hfh/admin/
then you may see what you expect. Also you'll may want a clause to not redirect when the File/Directory exists.
Does typing the expected result URL work?
/~Jason/hfh/admin/index.php?admin=Collections
Edit:
So what happens if you change the whole lot to:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /~Jason/hfh/admin/index.php?admin=$1 [L]
It looks like that would be sending you to the page /~Jason/hfh/index.php?admin=collections, when you want /~Jason/hfh/admin/index.php?admin=collections.
Try changing the rule to:
RewriteRule ^([A-Za-z0-9\-\_]*)$ admin/index.php?admin=$1
The short, direct answer for now appears to be: you can't use mod_rewrite on your localhost.

How do I ignore a directory in mod_rewrite?

I'm trying to have the modrewrite rules skip the directory vip. I've tried a number of things as you can see below, but to no avail.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
#RewriteRule ^vip$ - [PT]
RewriteRule ^vip/.$ - [PT]
#RewriteCond %{REQUEST_URI} !/vip
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
How do I get modrewrite to entirely ignore the /vip/ directory so that all requests pass directly to the folder?
Update:
As points of clarity:
It's hosted on Dreamhost
The folders are within a wordpress directory
the /vip/ folder contains a webdav .htaccess etc (though I dont think this is important
Try putting this before any other rules.
RewriteRule ^vip - [L,NC]
It will match any URI beginning vip.
The - means do nothing.
The L means this should be last rule; ignore everything following.
The NC means no-case (so "VIP" is also matched).
Note that it matches anything beginning vip. The expression ^vip$ would match vip but not vip/ or vip/index.html. The $ may have been your downfall. If you really want to do it right, you might want to go with ^vip(/|$) so you don't match vip-page.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
This says if it's an existing file or a directory don't touch it. You should be able to access site.com/vip and no rewrite rule should take place.
The code you are adding, and all answers that are providing Rewrite rules/conditions are useless! The default WordPress code already does everything that you should need it to:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Those lines say "if it's NOT an existing file (-f) or directory (-d), pass it along to WordPress. Adding additional rules, not matter how specific or good they are, is redundant--you should already be covered by the WordPress rules!
So why aren't they working???
The .htaccess in the vip directory is throwing an error. The exact same thing happens if you password protect a directory.
Here is the solution:
ErrorDocument 401 /err.txt
ErrorDocument 403 /err.txt
Insert those lines before the WordPress code, and then create /err.txt. This way, when it comes upon your WebDAV (or password protected directory) and fails, it will go to that file, and get caught by the existing default WordPress condition (RewriteCond %{REQUEST_FILENAME} !-f).
In summary, the final solution is:
ErrorDocument 401 /misc/myerror.html
ErrorDocument 403 /misc/myerror.html
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
I posted more about the cause of this problem in my specific situation, involving Wordpress and WebDAV on Dreamhost, which I expect many others to be having on my site.
You mentioned you already have a .htaccess file in the directory you want to ignore - you can use
RewriteEngine off
In that .htaccess to stop use of mod_rewrite (not sure if you're using mod_rewrite in that folder, if you are then that won't help since you can't turn it off).
Try replacing this part of your code:
RewriteRule ^vip/.$ - [PT]
...with the following:
RewriteCond %{REQUEST_URI} !(vip) [NC]
That should fix things up.
RewriteCond %{REQUEST_URI} !^pilot/
is the way to do that.
In my case, the answer by brentonstrine (and I see matdumsa also had the same idea) was the right one... I wanted to up-vote their answers, but being new here, I have no "reputation", so I have to write a full answer, in order to emphasize what I think is the real key here.
Several of these answers would successfully stop the WordPress index.php from being used ... but in many cases, the reason for doing this is that there is a real directory with real pages in it that you want to display directly, and the
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
lines already take care of that, so most of those solutions are a distraction in a case like mine.
The key was brentonstrine's insight that the error was a secondary effect, caused by the password-protection inside the directory I was trying to display directly. By putting in the
ErrorDocument 401 /err.txt
ErrorDocument 403 /err.txt
lines and creating error pages (I actually created err401.html and err403.html and made more informative error messages) I stopped the 404 response being generated when it couldn't find any page to display for 401 Authentication Required, and then the folder worked as expected... showing an apache login dialog, then the contents of the folder, or on failure, my error 401 page.
I’ve had the same issue using wordpress and found that the issue is linked with not having proper handler for 401 and 403 errors..
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
These conditions are already supposed not to rewrite the url of existing folders but they don’t do their job for password protected folders. In my case, adding the following two lines to my root .htaccess fixed the problem:
ErrorDocument 401 /misc/myerror.html
ErrorDocument 403 /misc/myerror.html
Of course you need to create the /misc/myerror.html,
This works ...
RewriteRule ^vip - [L,NC]
But ensure it is the first rule after
RewriteEngine on
i.e.
ErrorDocument 404 /page-not-found.html
RewriteEngine on
RewriteRule ^vip - [L,NC]
AddType application/x-httpd-php .html .htm
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
etc
I'm not sure if I understand your objective, but the following might do what you're after?
RewriteRule ^/vip/(.*)$ /$1?%{QUERY_STRING} [L]
This will cause a URL such as http://www.example.com/vip/fred.html to be rewritten without the /vip.