skip to Main Content

On the website.conf file I have:

<VirtualHost *:80>
    DocumentRoot /srv/http/website/cgi-bin
    ServerName website
    ServerAlias www.website

    RewriteEngine on
    RewriteRule ^$ ""
    RewriteRule ^([a-z]+)$ /?tab=repo

...

My goal is to have http://localhost/ redirect to localhost and http://localhost/word redirect to http://localhost/?tab=word.
With the current directives I get a 404 error, because it’s trying to open the file repo @ DocumentRoot. All I need is to rewrite the URL to make the word be a GET variable.

A directive like the following works:

RewriteRule /word$ http://localhost/?tab=word

This is obviously somewhat simplistic because I would then have to do it for every possibility.

I experimented with those directives on this website https://htaccess.madewithlove.com/, that I found from another thread on SO, the results are what I expect them to be, I.E.: http://localhost/word is transformed to http://localhost/?tab=word.

Extra info: The website does not have any PHP.

2

Answers


  1. Chosen as BEST ANSWER

    After tinkering a bit more I got down to this:

    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -f 
    RewriteRule ^(.*)$ %{REQUEST_FILENAME} [PT,L] 
    
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d 
    RewriteRule ^(.*)$ %{REQUEST_FILENAME} [PT,L] 
    
    RewriteRule ^/([^index.cgi]{1}.+)$ /index.cgi?tab=$1 [L]
    

    It opens files if they exist and sends requests that don't exist to my C++ cgicc program. The only thing I don't understand is why the -d condition isn't opening directories the same way the -f one opens files.


  2. # Virtual Host
    RewriteRule ^$ ""
    RewriteRule ^([a-z]+)$ /?tab=repo
    

    A directive like the following works:

    RewriteRule /word$ http://localhost/?tab=word
    

    The difference with the "working directive" is that you’ve included a slash prefix. The regex ^([a-z]+)$ does not allow for a slash prefix, so never matches.

    You are also failing to use the captured backreference (ie. $1) in the substitution string, so it would always rewrite to /?tab=repo regardless of the URL requested.

    Consequently, the first rule, that matches against ^$ will never match either – but this rule is not required. You are not performing a redirect when requesting the root – you just don’t want to do anything and instead allow mod_dir to serve the directory index.

    In a virtualhost context the URL-path matched by the RewriteRule pattern is a root-relative URL-path, starting with a slash.

    So, your rule(s) should be like this instead:

    RewriteEngine On
    RewriteRule ^/([a-z]+)$ /?tab=$1 [L]
    

    (Or, make the slash prefix optional, ie. ^/?([a-z]+)$)

    However, /?tab=<word> is not strictly a valid end-point. What is the actual file that is handling the request? This should be included in the rewrite (and not rely on the DirectoryIndex). You state you are not using PHP, so how are you reading the URL parameter?

    I experimented with those directives on this website https://htaccess.madewithlove.com/,

    You are not using .htaccess in your example. mod_rewrite behaves slightly differently depending on context (.htaccess, directory, virtualhost and server).


    Reference:

    What is matched?

    In VirtualHost context, The Pattern will initially be matched against
    the part of the URL after the hostname and port, and before the query
    string (e.g. "/app1/index.html"). This is the (%-decoded) URL-path.

    In per-directory context (Directory and .htaccess), the Pattern is
    matched against only a partial path, for example a request of
    "/app1/index.html" may result in comparison against "app1/index.html"
    or "index.html" depending on where the RewriteRule is defined.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search