GROVER.
GROVER.

Reputation: 4378

htaccess redirecting to the wrong page when using multiple rewriterules

I have a htaccess file which looks like the following:

Options -Indexes
RewriteEngine On

# no php extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]

# only allow rewriting to paths that dont exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f

# example.com/username
RewriteRule ^([\w\d_\-]+)/?$ profile.php?uid=$1 [L,QSA]
# example.com/username/$tab
RewriteRule ^([\w\d_\-]+)\/([\w]+)/?$ profile.php?uid=$1&tab=$2

# example.com/listen/$id
RewriteRule ^listen\/([\w\d_\-]+)?\/?([\w\d_\-]+)?$ track.php?id=$1&secret=$2 [L,QSA]

The way it is supposed to work is to redirect any URL looking like these:

1. example.com/example points to profile.php?id=example
or
2. example.com/example/tab points to profile.php?id=example&tab=tab


3. example.com/listen/example points to track.php?id=example
or
4. example.com/listen/example/code points to track.php?id=example&secret=code

The problem is that sometimes, a link which looks like the third one will point to the profile page. However, what's weirder, is that if example has a dash in it, it will point to the right place. This shouldn't be happening because my regex is matching after listen.

All help is appreciated.

Upvotes: 1

Views: 20

Answers (1)

anubhava
anubhava

Reputation: 784998

Both of your listen/ rules should appear before other rules and moreover 2 RewriteCond are only being applied to next immediate RewriteRule.

You may use these rules to replace all of your code:

Options -Indexes
RewriteEngine On

# only allow rewriting to paths that don't exist
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]

# example.com/listen/$id
RewriteRule ^listen/([\w-]+)/?$ track.php?id=$1 [L,QSA,NC]

# example.com/listen/$id/secret
RewriteRule ^listen/([\w-]+)/([\w-]+)/?$ track.php?id=$1&secret=$2 [L,QSA,NC]

# no php extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]

# example.com/username
RewriteRule ^([\w-]+)/?$ profile.php?uid=$1 [L,QSA]

# example.com/username/$tab
RewriteRule ^([\w-]+)/([\w-]+)/?$ profile.php?uid=$1&tab=$2 [L,QSA]

Also note that \w means [a-zA-Z0-9_] so no need to add \d_ in character class.

Upvotes: 1

Related Questions