mod_rewrite inserting full path to file - apache

I need to create a rewrite to take traffic going to mp3/mp4 files in a specific subdirectory and then route them to a PHP file that tracks download stats etc before routing them to the actual file location since iTunes requires your podcast RSS contain actual media file extensions (.mp3, .mp4, etc)
I have created rewrites before with no problem but now I am running into an odd issue on this company's server.
My .htaccess located at www.company.com/companytools/podcasts
RewriteEngine on
RewriteRule ^/(.*).mp3$ /test.php?file=$1 [r=301,L]
Right now it is partially working it does act upon the mp3 file but ends up including the full path to test.php after the domain, so I end up with a 404 page looking for this URL:
www.company.com/www/internal/docs/companytools/podcasts/test.php?file=test
basically I need the path, but only the /companytools/podcasts part.
Any help is appreciated.

You may not need R=301 here to hide actual PHP handler.
Try this rule with RewriteBase:
RewriteEngine on
RewriteBase /companytools/podcasts/
RewriteRule ^(.+?)\.mp3$ test.php?file=$1 [L,QSA]

Related

.htaccess Redirect Media File Requests to a Different Domain/Server

Simply speaking, I want to substitute one file path for another in the URI, but only for certain file types.
I have a load of image files (PNG, GIF and JPG) on one server and a wordpress installation on another server. I can't put them all on the same server at the moment (for reasons too complicated to go into).
So, when I get a request for a PNG, GIF or JPG file on e.g.
http://www.server1.com/images1/image1.png
I want to be able to divert this request to the same image, but on server 2, potentially in a different top level subfolder e.g. "allimages" such as:
http://www.server2.com/allimages/images1/image1.png
Then, say divert:
http://www.server1.com/images2/image2.png
to
http://www.server2.com/allimages/images2/image2.png
I tried to make a start with .htaccess (on SERVER1) but haven't got very far. I put a .htaccess file in the root of Server 1, with these lines in:
RewriteEngine On
RewriteCond %{REQUEST_URI} (\.png|\.jpg|\.gif|)$
RewriteRule ^(.*)$ http://www.server2.com/allimages/$1 [L,R=301]
But I know this isn't correct. Can anyone help? Many thanks!
Try with:
RewriteEngine On
RewriteRule ^(.+(?:\.png|\.jpg|\.gif))$ http://www.server2.com/allimages/$1 [L,R=301]

How to use apache to reroute files to other directory?

I am maintaining a website someone else wrote. He used absolute path in the html to request assets files, and he assumed the project is always installed at the root of the domain.
Now I am testing the website; I installed the project at a subdirectory. And I want to redirect files that start with a certain characters to a subfolder.
For example, he wrote something like this
<img src="/en/wp-content/themes/.....">
So now the server will start searching files at the root like example.com/en/wp-content/....
I installed the project at /foo/en, example.com/foo/en. I want to use .htaccess to reroute urls that start with /en/wp-content/themes to /foo/en/wp-content/themes. What should I do?
This is how I wrote it:
RewriteEngine On
RewriteRule ^en/wp-content/themes/(.*)$ /foo/en/wp-content/themes/$1
But it doesn't work....
I would change the line only a little bit just to be sure that this is not interfering with any other htaccess files use [L] or [END]:
RewriteEngine On
RewriteRule ^/?en/wp-content/themes/(.*)$ /foo/en/wp-content/themes/$1 [L]
[L] means Last https://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_l
[END] https://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_end

htaccess RewriteRule problems

I have a web page which works fine on live server. However some links to files (jpg, pdf and others) which are created with cms editor contain relative paths.
When I run that page on my local test server which serves the pages out of a sub folder of localhost the relative paths to the files are wrong since they are missing the subfolder at the beginning. The html page loads fine. It's just some files in it that have wrong path and won't load.
page loads from http://localhost/level1/
files are trying to load from http://localhost/level2/ and I get 404s.
They should be loading from http://localhost/level1/level2/
So I setup a RewriteRule to correct the path but no matter what I have tried I can't get it to work. I have tried various flags including [R,L] but nothing changes the URI in the html.
currently I have:
RewriteRule ^/level2/(.*)$ /level1/level2/$1 [R]
Any suggestions?
Thanks
Sounds like those links are not relative paths but absolute ones (starting with a leading slash (/). That is why the issue occurs at all. Relative paths make much more sense.
This would be the version to be used inside your http servers host configuration:
RewriteEngine on
RewriteRule ^/level2/(.*)$ /level1/level2/$1 [L,QSA]
Here the version for .htaccess style files (note the missing leading slash):
RewriteEngine on
RewriteRule ^level2/(.*)$ /level1/level2/$1 [L,QSA]
You could use a version that can be used in both situations:
RewriteEngine on
RewriteRule ^/?level2/(.*)$ /level1/level2/$1 [L,QSA]
Note however that in general one should always prefer to place such rules inside the http servers host configurations. .htaccess style files are notoriously error prone, hard to debug and they really slow down the server, often for nothing. .htaccess style files only offer a last option for those who are using a really cheap web hosting provider. Or for situations where a web application has to write its own rewrite rules, which obviously is a security nightmare on its own...

How do I force Apache to simply redirect the user and ignore the directory structure?

Ok, so this problem recently arose and I don't know why it is happening; it's actually two problems in one...
0. My .htaccess file, for reference. (EDITED)
Options -Indexes +FollowSymLinks
RewriteEngine On
RewriteBase /
ErrorDocument 400 /index.php?400
ErrorDocument 401 /index.php?401
ErrorDocument 403 /index.php?403
ErrorDocument 404 /index.php?404
ErrorDocument 410 /index.php?410
ErrorDocument 414 /index.php?414
ErrorDocument 500 /global/500.php
RewriteCond %{HTTP_HOST} !^$ [NC]
RewriteRule .* index.php [L]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?(animuson)\.(biz|com|info|me|net|org|us|ws)/.*$ [NC]
RewriteRule ^.*$ - [F]
1. My 'pictures' folder is following the hard path instead of the redirect.
I have no idea WHY it is doing this. It's really bugging me. The 'pictures' folder is a symbolic link to another place so that I can easily upload files to that folder without having to search through folders and such via my FTP account, but that's the only thing I use it for. However, when I visit http://example.com/pictures my htaccess sees it as accessing that other folder, which is restricted, and throws a 403 error rather than redirecting to index.php and displaying the page like normal.
I figured it has something to do with that specific folder being a symbolic link causing it to act oddly, but I have determined that my rules are not being applied to folders at all. If I visit folders such as 'css' and 'com' which are folders in the web root, it displays a 404 error page and adds the '/' to the end of the URL because it's treating it as a directory. It also does the same 403 error for my 'images' directory which is set up in the same fashion.
So, the question here is how do I modify my RewriteRule to apply to the directories as well? I want everything accessed via the web to be redirected back to index.php while maintaining the full access path in the address bar, why is it not working? (I'm pretty sure it was working fine before.)
Here's a small chart to show the paths they're following...
example.com/pictures -> pictures/ -> /home/animuson/animuson-pictures -> 403
example.com/com -> com/ -> 404
example.com/test -> index.php
example.com/ -> index.php
example.com/images -> images/ -> /home/animuson/animuson-images -> 403
example.com/css -> css/ -> 404
EDIT: Following information added.
Apache is processing the structure of the directory first. It's determining if the path exists based on what was typed into the address bar. If someone types in a folder name that happens to exist, it will redirect the user to the path with the "/" at the end of the URL signifying that it's a directory. For the 'pictures' directory explained above, the user does not have permission to access that folder so it is redirecting them to a 403 Access Denied page rather than simply showing the page that is supposed to be displayed there via the RewriteRule above. My biggest question is why is Apache processing the directory first and how do I make it stop doing that? I would really love an answer to this question.
2. Why is my compression not working? (EDIT: This part is fixed.)
When analyzing my site through a web optimizer, it keeps saying my page isn't using web compression, but I'm almost 100% positive that it was working fine before under the same settings. Can anyone suggest any reasons why it might not be working with this set up or suggest a better way of doing it?
Where is this .htaccess file situated? At the root or in the pictures directory?
1) You're using Options -Indexes which will deny access to directory listings. This is handled by /index.php?403 which in turn will redirect to /403. (I confirmed this by manually going to /index.php?403) I don't see any other rules in the posted .htaccess that are supposed to affect this. So this either happens because either index.php or some other .htaccess file or server rule makes that redirect.
You might also want to check the UNIX file permissions of the directory in question.
2) According to this aptimizer, http://www.websiteoptimization.com/services/analyze/, compression is indeed enabled for html, js and css files, as specified in the rules. My bet is that the optimizer is being stupid and does one of these three things:
1)) Complaining about images not being compressed. (It's generally a bad idea to compress images because they're typically already compressed and the extra CPU load typically isn't worth it since the net gain is so small. So your rules are OK in this regard.)
2)) It might think that DEFLATE doesn't count as compression, and wants you to use GZip.
3)) It might also react to the externally included StatCounter js file, which is not compressed. (And there's not much you can do about that.)
After a while of deliberating on Apache's IRC channel, I was finally able to figure out the real reasoning behind this on a fluke. I just happened to be looking at the directory structure using ls -l and noticed that all of the symbolic links had somehow has their permissions changed to animuson:animuson from the root:root original. I tried to run a simple chown root:root on them and it had no effect, so I deleted them all and recreated them and the problem has gone away. I don't really have any idea why the permissions made any different in this scenario but the solution worked and everything is okay now. I've also added a DirectorySlash Off to my .htaccess file to get rid of the slashes after folders that exist, just to make it look all that much nicer.

Apache redirect 404 for only the files that are not found?

What I'm looking to do is basically take all requests to a directory, and if the file exists, send it. If not, send it from the parent directory (assume it exists there). The files are large and there can be a lot, and the subdirectories will change frequently, so filesystem links isn't a great way to manage. Is there some Apache config way of doing this? e.g.
/path/file0
/path/file1
/path/sub1/fileA
/path/sub1/fileB
/path/sub1/fileC
/path/sub2/fileA
/path/sub2/fileB
/path/sub2/fileC
So, if a request comes in for /path/sub1/fileB they get /path/sub1/fileB (normal-case). If a request comes in for /path/sub1/file0 they get /path/file0 (special-case).
Or maybe there's a way in PHP, if I could have Apache redirect all requests in one folder to a specific php file that checks if the file is present and if not checks 'up' a folder?
Thanks.
You could use mod_rewrite to do that:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^path/[^/]+/([^/]+)$ path/$1 [L]
This rule will rewrite a request of /path/foo/bar to /path/bar only if /path/foo/bar is not a regular file.
Yes, PHP can redirect to a parent directory.