# =============================================================================
# OPTION B — front controller AT the app root (your CURRENT /aiseo/ layout)
#
# Use this only when index.php and assets/ sit directly in the app folder and
# the contents of the package public/ folder have been moved up one level.
# Save as .htaccess in that folder. See deploy/DEPLOY.md.
# Use this file when the FRONT CONTROLLER SITS AT THE APP ROOT — which is your
# layout today:
#
# /aiseo/ <- web-accessible, index.php + assets/ live here
# /aiseo/bootstrap.php
# /aiseo/3-source-code/src/ <- source, MUST NOT be web-readable
# /aiseo/3-source-code/templates/
# /aiseo/3-source-code/db/migrations/
# /aiseo/config/
# /aiseo/bin/
# /aiseo/var/ <- logs; better still, move it above the web root
#
# If instead you can point the document root at a dedicated public/ directory,
# delete this file and use public/.htaccess — that layout is safer because the
# source is not under the web root at all.
#
# VERIFY after deploying. All four must return 403 or 404:
# /aiseo/.env
# /aiseo/3-source-code/src/Core/Env.php
# /aiseo/config/paths.php
# /aiseo/var/logs/app.log
# `php bin/doctor.php` probes all of them and fails loudly if any is readable.
# =============================================================================
RewriteEngine On
# Set this to the URL path the app is served from. For
# https://dghanalytics.com/aiseo/ that is /aiseo/.
RewriteBase /aiseo/
# ---- HARD BLOCKS -------------------------------------------------------
# These run BEFORE the front-controller rewrite. Order matters: without
# them, the catch-all below would happily hand a source path to index.php,
# which returns 200 and makes the exposure look fine when it is not.
#
# Add a line here for any directory you introduce that is not public.
RewriteRule ^(\.env|\.git|\.htaccess|bootstrap\.php|composer\.(json|lock)) - [F,L]
RewriteRule ^(3-source-code|source-code|src|templates|config|bin|db|tests|var|storage|render-service|node_modules|vendor)(/|$) - [F,L]
# Numbered-folder layouts tend to grow siblings (1-docs, 2-design, 4-…).
# This blocks every numbered directory except the one serving assets, so a
# new folder is private by default rather than public by accident.
RewriteCond %{REQUEST_URI} !^.*/assets/
RewriteRule ^[0-9]+-[A-Za-z0-9_-]+(/|$) - [F,L]
# ---- FRONT CONTROLLER --------------------------------------------------
# Real files and directories (CSS, JS, images) are served untouched.
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Everything else is routed by the app.
RewriteRule ^ index.php [L]
# Belt and braces: even with mod_rewrite off, these files are never served.
Require all denied
Order allow,deny
Deny from all
# PHP files anywhere except the front controller are library code, not entry
# points. On a misconfigured host a stray .php can be fetched as text.
Require all denied
Order allow,deny
Deny from all
Require all granted
Order allow,deny
Allow from all
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json image/svg+xml
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set X-Frame-Options "SAMEORIGIN"
# This is an internal tool. Keep it out of every index, AI crawlers included.
Header always set X-Robots-Tag "noindex, nofollow, noarchive"
Options -Indexes