Search code examples
apache.htaccessmod-rewriteurl-rewriting

Apache2.4.54 - Rewrite does not work in .htaccess


I have this .htaccess file in /path/to/project/

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !system

    RewriteRule ^(.*)/([^/]+)/?$ $1/some/folders/$2.php [PT]
</IfModule>

and, as you can see, I want to redirect https://example.com/path/to/project/folder to https://example.com/path/to/project/some/folders/folder.

I know that this was answered like 1M times, but even a RewriteRule ^ / with no conditions doesn't work.

I have enabled mod_rewrite and checked that it was enabled, by including a Header set in the <IfModule> and it worked.

I have checked that AllowOverride All is in the /path/to/project/ directory, like so:

<Directory ${APACHE_ROOT_DIR}/path/to/project>
    AllowOverride All
</Directory>

I have no ideas anymore. I hope someone can help me.

UPDATE:

I tested the rewrite on another server and there the rewrite works. I copied the exact rewrite and it doesn't work. I even recreated the filestructure. Now only the mod_rewrite itself has a problem or the server VirtualHost or simular has a problem.

UPDATE 2:

I got it working in the sites-available/default-ssl.conf but not in the .htaccess. So the problem is in .htaccess and with mod_rewrite in combination. Because .htaccess works with Header set test test and mod_rewrite works in the default-ssl.conf.


Solution

  • I think you should track down the possible problems step by step.
    Please do not join some of the tests, as each test requires its own prove!

    While doing this, please stay at your required virtualhost.conf. Jumping between default-ssl.conf and your virtualhost.conf might give some hints, but is not helpful, when trying to track down a problem systematically in a row of tests.

    1. Access rights

    Please verify that the visitors are allowed to access the directory. So add Require all granted, if not yet present:

    File: httpd.conf or included *.conf

    <Directory "/var/www/vhosts/myhost/htdoc/PATH/TO/PROJECT">
        Require all granted
        AllowOverride All
    </Directory>
    

    After this reconfiguration a restart of the Apache daemon required:

    At the web server issue the command:

    apachectl -k graceful
    

    Open your project URL http://example.com/PATH/TO/PROJECT/:
    You should not see an 403 Access denied
    => Else this problem has to be solved first. (index file0 present? / Apache restarted properly? / Any rewrite rules?)

    STATUS-Update: Functionality OK

    2. Check the usage of the .htaccess file

    By the AllowOverride All the usage of the .htaccess file should work. Please test it, as typos etc. can render invalid any assumption:

    Add a line of nonsense in the .htaccess of your project folder:

    File: /var/www/vhosts/myhost/htdoc/PATH/TO/PROJECT/.htaccess

    asflksdflkj
    

    Calling the page http://example.com/PATH/TO/PROJECT/ should produce a

    500  Server Error
    

    Remove the line of nonsense in the .htaccess and call the page again:
    => The 500 error should disappear.

    The .htaccess is evaluated by Apache, if the behavior is as described.

    STATUS-Update: Functionality OK

    3. Check the presence of the ReWrite Engine

    To be sure, the rewrite engine is present AND the .htaccess file is accessed: Delete or set as comment the module check for mod_rewrite.c, but leave the active the RewriteEngine On:

    # <IfModule mod_rewrite.c>
        RewriteEngine On
    # </IfModule>
    

    Calling the page http://example.com/PATH/TO/PROJECT/ should not produce a

    500  Server Error
    

    => If this 500 happens, the module mod_rewrite is not loaded.

    When tested positive, you can re-enable the module check.
    For my projects, I think twice about this step as it might be better to clearly see the server problem than to get obscure side effects by not evaluated rewrite rules.

    STATUS-Update: Functionality OK

    4. Check for concurrent ReWrite rules

    Rewrite rules get evaluated dir by dir:

    1.  /.htaccess
    2.  /PATH/.htaccess
    3.  /PATH/TO/.htaccess
    4.  /PATH/TO/PROJECT/.htaccess
    

    So any rules in parent directories might manipulate the REQUEST_URI in an way that the project's directory will not be reached and no rule in there will be triggered.

    => If there are rules in the parent directories, disable them while testing.
    => Do not forget to check the apache CONF files for concurrent ReWrite rules.

    To see ReWrite at work, enable the DEBUG feature. Extend your LogLevel for your VirtualHost definition:

    LogLevel  notice rewrite:trace5
    

    Now (after apachectl -k graceful) the error_log should be filled excessively.

    For all rewrite rules in the parent dirs there should be the set of lines:

    ... applying pattern ...
    ... pass through ....
    
    # or
    ... applying pattern ...
    ... RewriteCond: ....  => not-matched, ...
    ... pass through ....
    

    For the lines of your project there should be the set of lines (and more) like:

    ... applying pattern ...
    ... RewriteCond: ....  => matched
    ... rewrite ....
    

    How are the tests? => might be useful to provide a logfile

    STATUS-Update:

    1. There are Rewrite rules executed before
    2. None of the ReWrite rules exits evaluation by [L]eave.
      ([L] would not not be a problem, as after a RewriteRule ... [L] ReWrite will restart evaluation at the beginning)
    3. At least one of the earlier evaluated ReWrite rules changes the URI of the project (added the DocumentRoot to the URI) in an unintended manner, triggering the problem.
      => Change of the rule in question solved the problem.

    5. Define the proper RewriteBase

    File: /var/www/vhosts/myhost/htdoc/PATH/TO/PROJECT/.htaccess

    RewriteEngine On
    
    RewriteBase /
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !system
    
    RewriteRule ^(.*)/([^/]+)/?$ $1/some/folders/$2.php [PT]
    

    Depending on details and further context, another RewriteBase might be better. (provide feedback? logfile?)


    For each step provide a short result, please.