fuzzyworld-tools / files / server / site / htaccess
htaccess
623239b7 2026-10-26 Pavel Safronov | 1 | # code.fuzzyworld.net. Installed as .htaccess by fuzzyworld-tools (server/install.sh). |
| 2 | Options -Indexes -Includes -ExecCGI | |
| 3 | DirectoryIndex index.html | |
| 4 | ErrorDocument 404 /404.html | |
| 5 | ||
| 6 | RewriteEngine On | |
| 7 | # www.<site> -> <site>, keeping path and query. | |
| 8 | RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] | |
| 9 | RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L] | |
| 10 | ||
20127f8f 2026-10-28 Pavel Safronov | 11 | # Redirect /why/ to /why-i-left-gitlab/ (old URL from GitLab repo READMEs) |
| 12 | RewriteRule ^/why/?$ /why-i-left-gitlab/ [R=301,L] | |
| 13 | ||
| 14 | # Redirect /principles/ to /why-i-left-gitlab/#principles (content was consolidated) | |
| 15 | RewriteRule ^/principles/?$ /why-i-left-gitlab/#principles [R=301,L] | |
| 16 | ||
623239b7 2026-10-26 Pavel Safronov | 17 | # Nothing in this tree is ever executed: pages are pre-generated HTML, raw copies |
| 18 | # are images only, and public clone copies are plain git data. | |
| 19 | RemoveHandler .php .php3 .php4 .php5 .php7 .php8 .phtml .phar .shtml .cgi .pl .py | |
| 20 | RemoveType .php .php3 .php4 .php5 .php7 .php8 .phtml .phar | |
| 21 | <FilesMatch "\.(php\d?|phtml|phar|shtml|cgi|pl|py|sh)$"> | |
| 22 | Require all denied | |
| 23 | </FilesMatch> | |
| 24 | ||
1758548c 2026-10-27 Pavel Safronov | 25 | # objects/<sha>: file contents for VS Code in the browser (apps.fuzzyworld.net/vscode/). Always sent |
| 26 | # as downloads, so a repo's .html or .svg file can never render as a page on this site. | |
| 27 | <If "%{REQUEST_URI} =~ m#^/[^/]+/objects/[0-9a-f]{40}$#"> | |
| 28 | ForceType application/octet-stream | |
| 29 | Header set Content-Disposition attachment | |
| 30 | </If> | |
| 31 | ||
623239b7 2026-10-26 Pavel Safronov | 32 | # Public clone copies: serve only what dumb-HTTP git needs. |
| 33 | RedirectMatch 404 ^/[^/]+\.git/(config|description|hooks/|logs/|info/exclude|FETCH_HEAD|ORIG_HEAD) | |
| 34 | ||
| 35 | <IfModule mod_headers.c> | |
| 36 | Header always set Content-Security-Policy "default-src 'self'; img-src 'self' https: data:; style-src 'self' 'unsafe-inline'; script-src 'none'; frame-ancestors 'none'" | |
| 37 | Header always set X-Content-Type-Options nosniff | |
| 38 | Header always set Referrer-Policy strict-origin-when-cross-origin | |
| 39 | # Pages change on every push: browsers must revalidate (cheap 304 when unchanged). | |
| 40 | <FilesMatch "\.(html|css)$"> | |
| 41 | Header set Cache-Control "no-cache" | |
| 42 | </FilesMatch> | |
1758548c 2026-10-27 Pavel Safronov | 43 | # VS Code in the browser reads files.json and objects/ from apps.fuzzyworld.net. |
| 44 | <If "%{REQUEST_URI} =~ m#^/[^/]+/(branch/[^/]+/)?files\.json$|^/[^/]+/objects/#"> | |
| 45 | Header set Access-Control-Allow-Origin "*" | |
| 46 | </If> | |
| 47 | <If "%{REQUEST_URI} =~ m#^/[^/]+/(branch/[^/]+/)?files\.json$#"> | |
| 48 | Header set Cache-Control "no-cache" | |
| 49 | </If> | |
55e5fc3e 2026-11-04 Pavel Safronov | 50 | # A bug report's run record is read by the replay viewer on apps.fuzzyworld.net. |
| 51 | <If "%{REQUEST_URI} =~ m#^/[^/]+/issues/[0-9]+/record\.json$#"> | |
| 52 | Header set Access-Control-Allow-Origin "https://apps.fuzzyworld.net" | |
| 53 | Header set Cache-Control "no-cache" | |
| 54 | </If> | |
1758548c 2026-10-27 Pavel Safronov | 55 | # objects/<sha> is named by its contents, so it never changes. |
| 56 | <If "%{REQUEST_URI} =~ m#^/[^/]+/objects/[0-9a-f]{40}$#"> | |
| 57 | Header set Cache-Control "public, max-age=31536000, immutable" | |
| 58 | </If> | |
623239b7 2026-10-26 Pavel Safronov | 59 | # Git objects and packs never change; refs do. |
| 60 | <If "%{REQUEST_URI} =~ m#^/[^/]+\.git/objects/(pack/|[0-9a-f]{2}/)#"> | |
| 61 | Header set Cache-Control "public, max-age=31536000, immutable" | |
| 62 | </If> | |
| 63 | <If "%{REQUEST_URI} =~ m#^/[^/]+\.git/(HEAD|info/refs|objects/info/packs)$#"> | |
| 64 | Header set Cache-Control "no-cache" | |
| 65 | </If> | |
| 66 | </IfModule> |