GurusGuru
GurusGuru

Reputation: 59

htaccess RewriteRule with a variable not working

This rule takes us to the error page RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]

I have the following in my .htaccess file

# BEGIN - Allow Sucuri Services
<IfModule mod_rewrite.c>
    RewriteRule ^sucuri-(.*)\.php$ - [L]
</IfModule>
# END - Allow Sucuri Services

<Files 403.shtml>
order allow,deny
allow from all
</Files>

ErrorDocument 404 /404.php

Options +FollowSymLinks
Options +MultiViews

RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteCond %{HTTP_HOST} !^www.xxxxx.com$ [NC]
RewriteRule ^(.*)$ https://www.xxxxx.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ci_index.php?/$1 [L]

## Remove php extension
RewriteCond %{REQUEST_URI} !^/index.php$
RewriteRule ^([^\.]+)$ $1.php [NC,L]

RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]

With the following rule

RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]

Trying to achieve the following:

https://www.xxxxx.com/latest?auth=US-mobile-county

to

https://www.xxxxx.com/latest/US-mobile-county

Upvotes: 1

Views: 127

Answers (1)

MrWhite
MrWhite

Reputation: 45987

This rule takes us to the error page RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]

You've not stated precisely what "error page" you are referring to? Or what is expected to handle this request. This directive is not correct by itself, so it's not immediately clear what it is you are trying to do. I'm assuming the intention is to rewrite to latest.php (not latest as suggested by this rule, and mentioned later in the question) - since this would seem to be the only reason to implement such a rule (and your question is tagged php). By rewriting to latest only you are dependent on other directives appending the .php extension - and therein lies a conflict.

There are a number of issues with the directives as posted that is preventing this from working. Notably, the rules are in the wrong order and the use of MultiViews (probably in an attempt to get extensionless URLs working) is compounding matters. In fact, it doesn't look like the rule in question is actually being processed at all.

Without MultiViews, and due to the order of the directives, a request of the form /latest/something would be rewritten to /ci_index.php?/latest/something (presumably a CodeIgniter front-controller) which I would guess would result in a CI generated 404 response. However, since MultiViews has been enabled mod_negotiation first "rewrites" the request to /latest.php/something, which doesn't match any of your rules so either results in a 404 (depending on your server config) or calls latest.php but without any URL parameter, which presumably causes your script to fail?

https://www.xxxxx.com/latest/US-mobile-county

Also, note that your example URL contains hyphens (-), but the regex in your directive (ie. ^latest/([A-Za-z0-9]+)$) does not permit hyphens so it wouldn't have matched anyway.

Try the following instead, replacing everything after the ErrorDocument directive:

# Disable MultiViews
Options +FollowSymLinks -MultiViews

RewriteEngine on

# Redirect HTTP to HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# Redirect non-www to www
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]

# Rewrite "/latest/something" to "/latest.php?auth=something"
RewriteRule ^latest/([A-Za-z0-9-]+)$ latest.php?auth=$1 [L]

# Allow extensionless PHP URLs to work
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]

# Front-controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ci_index.php?/$1 [L]

Note that I've reversed the order of the directives so that the rule in question is now first and the CI front-controller is now last. The order of the directives in .htaccess is important.

Since you had enabled MultiViews (now disabled in the above), your rule to enable PHP extensionless URLs (that you had labelled "Remove php extension") was not actually being used at all (unless you had directories or files that contained dots, other than that used to delimit the file extension).

Upvotes: 1

Related Questions