skip to Main Content

Related to a previous Question: .htaccess – Recursively mapping slashes to underscores

The code that was listed as the "full solution" worked for 12 months. Then stopped working. The .htaccess code wasn’t changed either – just to make things harder.

The Question

Can anyone help me achieve The Desired Outcome?

The Desired Outcome

Take https ://domain.com/this/is/mah/page/structure and show the file /this_is_mah_page_strucutre.php which lives in the root of the website.

The Code Currently

The below is contents from the file

<IfModule mod_negotiation.c>
Options -MultiViews
Options All -Indexes
</IfModule>

<IfModule mod_rewrite.c>
    RewriteEngine on
    DirectorySlash off

    # Error Redirects
        ErrorDocument 404 /incs/404.php

        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME}.php !-f
        RewriteRule ^ - [R=404,L]

    # remove .php
        RewriteCond %{THE_REQUEST} s/+(.+?).php[s?] [NC]
        RewriteRule ^ /%1 [R=302,NE,L]

        # map the .php extension
        RewriteRule ^([^.]+?)/?$ $1.php [L]

    # map the slashes to underscores
        # when there are more than one / then "recursively" replace it by _
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d

# This next line appears to be the problem
        RewriteRule ^([^/]+)/([^/]+/.+)$ $1_$2 [N,DPI]


# This next section appears to be doubling up, but was originally meant to catch anything that missed the previous block
        # when there is only one / then replace it by _ and redirect
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^([^/]+)/([^/]+)$ /$1_$2 [L]

</IfModule>

The Possible Problem

As noted, RewriteRule ^([^/]+)/([^/]+/.+)$ $1_$2 [N,DPI] doesn’t seem to work as intended.

If https://htaccess.madewithlove.be/?share=9bd3c5a0-4002-4324-a82e-0065b7286f82 is to be believed, then what is happening is that the [N] isn’t causing the recursion (a) I require, and (b) it used to provide.

The MadeWithLove tester outcome states that /this/is/mah/page/structure is becoming /this_is/mah/page/structure.

I have tried rejiggering the PCRE RegEx, and so has @anubhava – but have been unable to get it working.

The Server

The server is using version 2.4.37-30.module_el8.3.0+561+97fdbbcc for httpd and is running on CentOS 8. The code in question was migrated from CentOS 7 about 5 months go, and it’s been working happily till about the last 7 days.

As far as the Apache settings and .htaccess file, nothing has changed within the last two weeks.

2

Answers


  1. Try:

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} ^(.+)/(.*)$
    RewriteRule ^ %1_%2 [L]
    

    So, your full htaccess be:

    <IfModule mod_negotiation.c>
    Options -MultiViews
    Options All -Indexes
    </IfModule>
    
    <IfModule mod_rewrite.c>
        RewriteEngine on
        DirectorySlash off
    
        # Error Redirects
            ErrorDocument 404 /incs/404.php
    
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME}.php !-f
            RewriteRule ^ - [R=404,L]
    
        # remove .php
            RewriteCond %{THE_REQUEST} s/+(.+?).php[s?] [NC]
            RewriteRule ^ /%1 [R=302,NE,L]
    
            # map the .php extension
            RewriteRule ^([^.]+?)/?$ $1.php [L]
    
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_URI} ^(.+)/(.*)$
            RewriteRule ^ %1_%2 [L]
    
    </IfModule>
    
    Login or Signup to reply.
  2. Have it this way:

    <IfModule mod_negotiation.c>
    Options All -Indexes -MukltiViews
    </IfModule>
    
    <IfModule mod_rewrite.c>
        RewriteEngine on
        DirectorySlash off
        # Error Redirects
        ErrorDocument 404 /incs/404.php
    
        RewriteCond %{REQUEST_FILENAME} -d [OR]
        RewriteCond %{REQUEST_FILENAME} -f
        RewriteRule ^ - [L]
    
        # remove .php
        RewriteCond %{THE_REQUEST} s/+(.+?).php[s?] [NC]
        RewriteRule ^ /%1 [R=301,NE,L]
    
        # map the slashes to underscores
        # when there are more than one / then "recursively" replace it by _
        # This next line appears to be the problem
        RewriteRule ^([^/]+)/(.+)$ $1_$2 [N,DPI]
    
        # map the .php extension
        RewriteCond %{DOCUMENT_ROOT}/$1.php -f
        RewriteRule ^([^.]+?)/?$ $1.php [L]
    </IfModule>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search