Apache rewrite harness for dropping index.php from BMLT main_server URLs.
Target production shape (Metro Rich NA):
https://metrorichna.org/BMLT/main_server/index.php#/login
→ should become
https://metrorichna.org/BMLT/main_server/#/login
The #/login fragment is never sent to the server. The rewrite only cleans the path; the browser keeps the hash.
docker compose up -d
BASE_URL=http://127.0.0.1:8088 ./tests/run-tests.sh
BASE_URL=http://127.0.0.1:8088 ./tests/compare-bases.shRead-only GET suite — no POSTs. Defaults to https://metrorichna.org.
# After rewrite is deployed (expects 301 away from index.php):
./tests/run-production-tests.sh
# Baseline before rewrite is live (index.php may still be 200):
EXPECT_REDIRECT=0 ./tests/run-production-tests.shCovers: index.php redirect, query-string keep, clean SPA shell / apiBaseUrl, no redirect loop, robots.txt, build/manifest.json, semantic workshop, GetServerInfo JSON, serverInfo.xml.
Active file: htaccess/fixed.htaccess (copied to public/BMLT/main_server/.htaccess)
| Behavior | Result |
|---|---|
.../index.php → 301 .../main_server/ |
pass |
Query string preserved (?foo=bar) |
pass |
Clean / hits front controller |
pass |
Virtual paths (/login, nested) → index.php PATH_INFO |
pass |
Real files (static.txt, assets/ok.txt) not rewritten |
pass |
| No redirect loop on clean URL | pass |
RewriteBase / is wrong when .htaccess lives under /BMLT/main_server/.
| Behavior | Proposed (RewriteBase /) |
Fixed |
|---|---|---|
301 strip index.php |
works (no trailing /) |
works (with trailing /) |
/BMLT/main_server/ |
works | works |
/BMLT/main_server/login |
404 | 200 → front controller |
| Static files | works | works |
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /BMLT/main_server/
# External requests with index.php → clean URL (keep query string)
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^\s?]*)/index\.php [NC]
RewriteRule ^ %1/ [R=301,L,QSA]
# Front-controller for non-files / non-dirs
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]RewriteBase /BMLT/main_server/— required for subdirectory installs; bare/breaks internal rewrites (SPA/API paths 404).- Tighter
THE_REQUESTcapture —[^\s?]*so?queryis not swallowed by the path group. QSA+ trailing slash — keep query strings; normalize to.../main_server/.
apache/httpd.conf # AllowOverride All + mod_rewrite + CGI .php stub
public/BMLT/main_server/ # mirrors production path
.htaccess # currently = fixed rules
index.php # stub front controller (prints request meta)
static.txt / assets/ # real files that must not be rewritten
htaccess/proposed.htaccess # exact draft under test
htaccess/fixed.htaccess # recommended
tests/run-tests.sh
tests/compare-bases.sh