I am developing a Mojolicious web application and want to deploy it to shared web hosting which offers Apache with CGI and Perl including Mojolicious. How to configure it via .htaccess?
https://myapp.mydomain.example/ is set up as a vhost at the provider and any request to this vhost should be handled by Mojolicous, possibly except static files in the
public/directory—they may be directly served by Apache.https://myapp.mydomain.example/ should be app’s homepage with the internal
/route.https://myapp.mydomain.example/page should be some page in the app with internal route
/page.The Mojolicious App consists of a
myapp.plin the project root, alib/folder with my Perl modules and apublic/folder with static files:
/home/myuser/www/myapp.mydomain.example/ ├── myapp.pl ├── lib │ └── MyApp │ └── Person.pm └── public └── style.css - Requests to https://myapp.mydomain.example/myapp.pl MUST NOT return the script content but should return a 403 or 404 from Apache or even better be handled by the Mojolicious app which will return its default 404 page.
- Mojolicious’
$c->uri_for()method builds external URLs including hostname, port number, path parts, etc. for any given internal app path. CGI request headers must be correct for Mojolicious to assemble external URLs correctly without going through extra hoops.
My only way to configure Apache is via .htaccess files.
My approach so far:
RewriteEngine on # Rewrite only if the request isn't for a real file, directory, or symlink. RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-l #RewriteCond %{REQUEST_FILENAME} !-d Options +ExecCGI # ONLY FOR DEBUGGING AddHandler cgi-script .sh RewriteRule ^env$ env.sh/$1 [END] RewriteRule ^(.*)$ myapp.pl/$1 [END] Servings pages works so far but I’m stuck with this: $c->url_for("/page") returns https://myapp.mydomain.example/myapp.pl/page and not https://myapp.mydomain.example/page.
You can see I’ve placed a script env.sh which just prints env:
#!/bin/bash echo -ne "Content-Type: text/plain\r\n\r\n" env The result (values carefully replaced with placeholders):
HTTP_ACCEPT_ENCODING=gzip, deflate, br, zstd SERVER_NAME=myapp.mydomain.example HTTPS=on UNIQUE_ID=aK4EKWlXO0tWVailYKOtrAACND0 SCRIPT_NAME=/env.sh REDIRECT_STATUS=200 GATEWAY_INTERFACE=CGI/1.1 SERVER_SOFTWARE=Apache PATH_INFO=/ DOCUMENT_ROOT=/home/myuser/www/myapp.mydomain.example HTTP_UPGRADE_INSECURE_REQUESTS=1 PWD=/home/myuser/www/myapp.mydomain.example REQUEST_URI=/env PATH_TRANSLATED=redirect:/myapp.pl/ SERVER_SIGNATURE= REQUEST_SCHEME=https QUERY_STRING= HTTP_TE=trailers HTTP_ACCEPT_LANGUAGE=en-US,en;q=0.5 HTTP_SEC_FETCH_DEST=document CONTEXT_DOCUMENT_ROOT=/home/myuser/www/myapp.mydomain.example HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 HTTP_PRIORITY=u=0, i REMOTE_PORT=16889 [email protected] HTTP_HOST=myapp.mydomain.example SSL_TLS_SNI=myapp.mydomain.example HTTP_SEC_FETCH_USER=?1 HTTP_SEC_FETCH_SITE=none SERVER_ADDR=127.0.0.2 HTTP_USER_AGENT=Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0 CONTEXT_PREFIX= SHLVL=1 HTTP_SEC_FETCH_MODE=navigate SERVER_PROTOCOL=HTTP/2.0 SERVER_PORT=443 SCRIPT_FILENAME=/home/myuser/www/myapp.mydomain.example/env.sh REMOTE_ADDR=79.246.0.0 PATH=/usr/local/bin:/usr/bin:/bin REDIRECT_URL=/env REQUEST_METHOD=GET _=/usr/bin/env
.htaccessfile, it would seem yourmyapp.plscript is reading the requested URL-path from the additional pathname information (PATH_INFO) - is that the case? Although I wonder if this is in error, as you are also usingenv.sh/$1on the preceding rule, which makes no sense (since there is no backreference here).myapp.pltoenv.shand didn’t bother to remove the$1reference but Apache doesn’t seem to care.