Reputation: 1097
I have a simple php web application with this directory structure
.
├── custom_403.html
├── custom_404.html
├── home
│ └── home.php
├── .htaccess
├── index.php
├── login
│ └── login.php
├── public
│ ├── bootstrap
│ ├── css
│ ├── error_pages
│ ├── fontawesome
│ ├── .htaccess
│ └── js
├── signup
│ └── signup.php
├── test.php
I made an .htacess
file that basically looks like this
ErrorDocument 404 /public/error_pages/404.php
ErrorDocument 500 /public/error_pages/500.php
ErrorDocument 403 /index.php
When I type something like http://localhost/login/
it should give me a 403 Forbidden
error because the directory login
exists but doesn't have the file index.php
. According to my .htacess
it should serve the default index.php
file.I take advantage of this on the index.php
to load the file in the specified path from the adress bar using jquery.
I search for window.location.pathname
to load the corresponding file from that path with a resolveUrl()
function.
Here's an example
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- Boostrap 4.3 -->
<link rel="stylesheet" href="/public/bootstrap/css/bootstrap.css">
<!-- Fontawesome 5 Free -->
<link rel="stylesheet" href="/public/fontawesome/css/all.css">
<link rel="stylesheet" href="/public/css/style.css">
<script src="/public/js/jquery.js"></script>
<script src="/public/bootstrap/js/bootstrap.js"></script>
</head>
<body>
<nav class="navbar navbar-expand-lg r-shadow">
<a class="navbar-brand" href="#"><img width="50" class="d-inline-block align-top" src="https://seeklogo.com/images/M/marvel-comics-logo-31D9B4C7FB-seeklogo.com.png" alt="" srcset=""></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarText">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="home">Home</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="login">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" href="signup">Sign Up</a>
</li>
</ul>
</nav>
<div class="root">
<div class="container mt-3 rounded" style="background-color: rgba(255, 255, 255, 0.1); ">dcfdcf</div>
<div id="loader">
<div class="spinner"><i class="fas fa-spinner fa-spin"></i></div>
</div>
</div>
</body>
<script>
function resolveUrl(url) {
if (url) {
var path = url.replace(/\//gi, '').trim();
$(".container").load("/" + path + "/" + path + ".php");
return path;
} else {
$(".container").load("/home/home.php");
console.log(path)
}
}
function resolveActiveTab(pathName) {
$(".nav-item").removeClass("active");
if (pathName) {
$("li > a[href='" + pathName + "']").parent().addClass("active");
} else {
$("li > a").first().parent().addClass("active");
}
}
$(document).ready(function () {
console.log(window.location.pathname)
var currentPath = resolveUrl(window.location.pathname);
resolveActiveTab(currentPath)
$(document).ajaxStart(function () {
$("#loader").css({
"display": "block"
});
})
$(document).ajaxStop(function () {
$("#loader").css({
"display": "none"
});
})
$('.nav-link').click(function (e) {
e.preventDefault();
var path = $(this).attr("href");
$(".container").load("/" + path + "/" + path + ".php");
resolveActiveTab(path)
window.history.pushState("", "", "/" + path);
})
})
</script>
</html>
this means that if the refresh the page with a path like http://localhost/login/
the jquery will load login.php
.
This works fine except I get an error on the apache log that looks like this
AH01276: Cannot serve directory /var/www/html/test/login/: No matching DirectoryIndex (index.php,index.html,index.cgi,index.pl,index.xhtml,index.htm) found, and server-generated directory index forbidden by Options directive
When I try to solve this problem by changing the filenames from login.php signup.php etc
to index.php
I get served those files back since they do exist, meaning I won't get the 403
error. I tried denying access to these specific files in my .htaccess
but then they are denied for everything including the jquery .load()
function. My question is how do what I'm doing efficiently without the apache error.
Upvotes: 0
Views: 460
Reputation: 898
Your .htaccess
is wrong, you are using ErrorDocument
403
to load a file index.php
, (ErrorDocument
is used normally for custom error pages not for loading a normal resource) you wish have a Forbidden
when try to load login/
because this folder doesn't have a index.php
file but I suspect that you have in your VirtualHost
the option Indexes
, this directive loads the folder contents but doesn't serve a 403
error.
My VirtualHost
for testing purpose is:
<VirtualHost localhost-test:80>
ServerName localhost-test
ServerAlias localhost-test
ErrorLog "logs/localhost-test-error.log"
TransferLog "logs/localhost-test-access.log"
DocumentRoot "D:/Web/test"
<Directory />
Require all granted
Options FollowSymLinks Includes ExecCGI
AllowOverride All
</Directory>
</VirtualHost>
If you remove Indexes
from your VirtualHost
you can see the Forbidden
error custom page. You should have:
ErrorDocument 404 /public/error_pages/404.php
ErrorDocument 500 /public/error_pages/500.php
ErrorDocument 403 /public/error_pages/403.php
Now if you try to load the folder /login/
without an index.php
file inside, you should have a Forbidden
403
with your custom page error but using JQuery in meanwhile you can load the login.php
file instead.
I hope this helps.
Upvotes: 1