# Vision Videoke .htaccess Configuration # Place this file as /var/www/html/music/.htaccess # This enables the application to work in a subdirectory RewriteEngine On # Security headers Header always set X-Content-Type-Options nosniff Header always set X-Frame-Options DENY Header always set X-XSS-Protection "1; mode=block" Header always set Referrer-Policy "strict-origin-when-cross-origin" # HTTPS security header (only if using HTTPS) Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" env=HTTPS # CORS headers for API requests Header always set Access-Control-Allow-Origin "*" Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" Header always set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With" # Handle preflight OPTIONS requests RewriteCond %{REQUEST_METHOD} OPTIONS RewriteRule ^(.*)$ $1 [R=200,L] # API proxy rules - forward API requests to Node.js backend RewriteCond %{REQUEST_URI} ^/music/api/(.*)$ RewriteRule ^api/(.*)$ http://127.0.0.1:3001/api/$1 [P,L] # React Router (SPA) routing # Redirect all non-file requests to index.html for client-side routing RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !^/music/api/ RewriteCond %{REQUEST_URI} !^/music/health$ RewriteRule ^(.*)$ index.html [L,QSA] # File upload handling RewriteCond %{REQUEST_URI} ^/music/api/upload RewriteRule ^(.*)$ http://127.0.0.1:3001/$1 [P,L] # Static file caching ExpiresActive On # Cache static assets for 1 year ExpiresByType text/css "access plus 1 year" ExpiresByType application/javascript "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType image/jpg "access plus 1 year" ExpiresByType image/jpeg "access plus 1 year" ExpiresByType image/gif "access plus 1 year" ExpiresByType image/ico "access plus 1 year" ExpiresByType image/svg+xml "access plus 1 year" ExpiresByType font/woff "access plus 1 year" ExpiresByType font/woff2 "access plus 1 year" ExpiresByType font/ttf "access plus 1 year" ExpiresByType font/eot "access plus 1 year" # Cache HTML files for 1 hour ExpiresByType text/html "access plus 1 hour" # Gzip compression SetOutputFilter DEFLATE # Don't compress images SetEnvIfNoCase Request_URI \ \.(?:gif|jpe?g|png)$ no-gzip dont-vary # Don't compress archives SetEnvIfNoCase Request_URI \ \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary # Security: Block access to sensitive files Require all denied # Prevent access to node_modules if accidentally uploaded RewriteRule ^node_modules/ - [F,L] # Custom error pages (optional) # ErrorDocument 404 /music/index.html # ErrorDocument 500 /music/error.html # File upload size limits (adjust as needed) php_value upload_max_filesize 100M php_value post_max_size 100M php_value max_execution_time 300 php_value max_input_time 300 # Directory browsing disabled for security Options -Indexes # Follow symbolic links Options +FollowSymLinks # Allow .htaccess overrides AllowOverride All