Make 404 error not redirect when on different domain/subdomain
.htaccess files are extremely useful in many cases for users who either do not have root permissions or for users who simply aren't comfortable in making changes in their web server's configuration file. Trying to debug .htaccess not working isn't always the easiest thing to do, however, hopefully by checking the discuss below mentioned about htaccess, php, , , .htaccess common problems as well as the troubleshooting tips, you'll have a better grasp on what you may have to modify to get your .htaccess file running smoothly.Problem :I have a PHP file on my error subdomain (https://errors.example.com).
And this is meant to serve as the error page for all subdomains.
The format it goes through is https://errors.example.com?type=error?error=404 just an example but when I receive a 404 on a different sub. Or the main I get redirected to there. And that messes with the path that it shows... And it exposes where my error pages are...
My .htaccess file:
Options +Indexes
Order deny,allow
<IfModule !mod_ssl.c>
Redirect permanent / https://www.example.com/
</IfModule>
ErrorDocument 400 https://errors.example.com?type=error&error=400
ErrorDocument 401 https://errors.example.com?type=error&error=401
ErrorDocument 403 https://errors.example.com?type=error&error=403
ErrorDocument 404 https://errors.example.com?type=error&error=404
ErrorDocument 451 https://errors.example.com?type=error&error=451
ErrorDocument 500 https://errors.example.com?type=error&error=500
## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType text/html "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"
</IfModule>
## EXPIRES CACHING ##
ErrorDocument 400 https://errors.example.com?type=error&error=400
In order to prevent Apache triggering an external redirect to the error document you need to remove the absolute URL (scheme + hostname) and specify a root-relative filesystem path to your error document instead. By including an absolute URL, Apache implicitly triggers an external redirect (not desirable).
Basically, you can't get Apache to serve an error document via an internal subrequest that's on a different host.
If your main domain and all subdomains (including the errors subdomain) point to the same area on the filesystem then there shouldn't be a need to change hosts (ie. having a special errors subdomain is going to cause problems). The ErrorDocument URL is hidden from users anyway.
Another "problem" with the URL-path you've given is that you've not actually specified the error document filename (this becomes more obvious when you strip the scheme + hostname). I assume you are using the DirectoryIndex (eg. index.php)? But if you omit this then mod_dir will trigger another subrequest to the directory index.
So, try something like:
ErrorDocument 400 /index.php?type=error&error=400
Aside: If you are using PHP, then there is no real need to explicitly pass the HTTP status code to the error document (eg. &error=400). Providing the error document is triggered by an internal subrequest (as opposed to an external redirect, as mentioned above), then the HTTP status is available in the $_SERVER['REDIRECT_STATUS'] superglobal. This can also be used to determine whether the error document has been requested directly (REDIRECT_STATUS is not set in this instance). Although this may require a slight reworking of your PHP script.
ErrorDocument 400 /index.php?type=error
ErrorDocument 401 /index.php?type=error
ErrorDocument 403 /index.php?type=error
:
UPDATE: With regards to the use of $_SERVER['REDIRECT_STATUS'] and your error URL parameter... Note that (as mentioned above) REDIRECT_STATUS is not set on direct access. At other times it is set to the HTTP status code (a numeric string - the variable type is a string). It can also be set to "200" (OK) after a successful internal rewrite (this may or may not apply to your system, but it is worth checking for).
You should also assume that your error URL param might not be set. So, something like this in PHP:
// Get the HTTP status code...
// "error" URL param (if set) will override the REDIRECT_STATUS variable
$httpStatus = isset($_SERVER['REDIRECT_STATUS']) ? $_SERVER['REDIRECT_STATUS'] : null;
$httpStatus = isset($_GET['error']) ? $_GET['error'] : $httpStatus;
if (empty($httpStatus))
// Direct access without the "error" parameter - abort?
// Or force a 403 or 404 plus suitable response.
exit();
elseif ($httpStatus == '404')
// Process 404 error
// etc.
elseif ($httpStatus == '200')
// Not an error...
else
// Unknown error
This allows your error URL param to always override the REDIRECT_STATUS superglobal.
Comments
Post a Comment