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

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.

Related

Specify to load index.html file for every request in apache config file

I have a React application hosted on my server and I need to always load index.html file for every request users make.
Let's say that I have a website that has the address xyz.com, and the root directory contains the React build files, including this index.html file. There are many routes that users can specify to access to certain parts of the website, for example to register on the website they can access xyz.com/register. So, what I want to accomplish is instruct server to always serve this index.html every time users access my site, even though they are visiting different routes of the website.
So I'm assuming that this is something that I can set up in the .conf file for the website, and if it is, can you please let me know how I can achieve it?
You can use the below rewrite rule.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/index.html$
RewriteRule .* /index.html [L,R=302]

.htaccess rewrites root to subfolder, yet subfolder app 302 redirects right back to full path

I have a standard .htaccess RewriteRule that silently rewrites any request for webroot into a subfolder which contains a MantisBT installation. So the user types in "example.com" and my server secretly serves them files from "example.com/path/to/mantisbt".
The problem now is that MantisBT's index page immediately does some authentication based logic routing and sends a 302 redirect to the FULL "example.com/path/to/mantis/login", which subverts my rewriting. I'm trying to have everyone access my MantisBT installation as if it resided in the webroot.
Now, I'm aware that after MantisBT's 302 redirect to the full path, I could redirect them AGAIN back to webroot. But redirecting people twice every time MantisBT goes through some routing logic seems like a dirty hack. I also know that I could hack up the MantisBT code, but I hate re-hacking code every time a new version comes out.
So, is there a way to trick MantisBT (or any other app for that matter) into thinking it resides in root, and therefore crafts it's redirect paths based on a webroot-relative url? For example: "example.com/login" instead of "example.com/path/to/mantis/login".
I'd really prefer to resolve this using an Apache .htaccess method, or httpd.conf change. Perhaps DocumentRoot or RewriteBase?
Try adding this rule above the internal rewrite rule that you had before
RewriteCond %{THE_REQUEST} \ /+path/to/mantisbt/([^\?\ ]*)
RewriteRule ^ /%1 [L,R]
this redirects the browser when the browser directly requests anything in /path/to/mantisbt/. Then the rule that you already have to internally rewrite into the mantisbt directory would take effect.

mod_rewrite inserting full path to file

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]

How manage several folders in my domain?

I want create subdomains like this:
domain.com/type/city
An examples:
domain.com/restaurants/new_york
domain.com/hotels/new_york
domain.com/restaurants/chicago
I have thousand of cities in a mysql database.
I thinked in some options:
Thousand of folders with an index.php for redirect (I think wrong way).
Create an sitemap with all links (domain.com?type=hotels&city=chicago) and manage they by code with the database.
Apache?
Please, which will be the best way for this? Thanks in advance!
You can solve this with a combination of PHP and Apache configuration. That is the most common solution and seen in popular PHP website software such as Drupal and Wordpress.
The idea is to let Apache send all traffic to one index.php file and pass the rest of the path as a parameter for PHP to handle with it.
You will need to be carefull with a few edgecases though; if file such as ./public/styles.css is requested, you don't want to serve that trough your PHP application but want apache to serve the file directly. Existing files will need to be handled by apache, all else by you application.
In your .htaccess:
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
The first line tells Apache to send normal files by itlself. Second line does the same for existing directories. Third line avoids that browsers (most notably version IE6) who request the example.com/favicon.ico don't hammer your PHP application.
Then it passes everything along to index.php and adds the rest of the path into the q param.
Inside index.php you can then read that, and take action with that:
<?php
$path = $_GET['q'];
$params = explode('/', $path);
print $path;
print_r($params);
?>
Thousands of folders would be the wrong way that is for sure.
If you start creating the sitemap with links of the type domain.com/?type=hotels&city=chicago you get a nice structure that you can manage programatically.
First get this started and working, then look up .htaccess and mod_rewrite which you can then use to map from domain.com/type/city to your links already functioning.
This seems both to be a good strategy for getting something working fast, and for ending up with the prettiest solution.

Short-urls without index files?

I'm wondering how urls like these are generated: http://www.example.com/Xj7hF
This is a practice I have seen used by many url shorteners as well as other websites that supposedly don't want to display data in the url in a parameter format.
Surely they can't be placing index files in the folder destination /Xj7hF etc with a redirect to the actual url, so I'm wondering how this is done.
Any help would be very appreciated!
(I'm running on a Linux server with Apache).
Different web development frameworks and web servers do it in different ways, but, the most common is probably using mod_rewrite with apache. Basically, the web server sends the request to a dynamic scripting language (eg. PHP) rewritten in such a way that the script doesn't need to know what the original request URI looked like and the client browser doesn't need to know what script actually processed the request.
For example, You will often see:
http://something.com/123/
This is a request for /123 which Apache may rewrite as a request to /my_script.php?id=123 based on how the user configured mod_rewrite.
(.htaccess example)
# if the request is for a file or directory that
# does not actually exist, serve index.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?url=$1
This is known as URL rewriting and is usually performed via proper configuration of the webserver. StackOverflow has several tags for this, so you should be able to find more information there.