Reputation: 167
I have got this htaccess code
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule Topics/([^/]+)$ topics.php?topic_name=$1 [L,QSA]
So all my URLs are presented like this
Topics/Eminem
But when i have /
in my topic name then URL returns "Not found".
For example AC/DC becomes Topics/AC%2FDC
but url refuses accepting it.
Upvotes: 1
Views: 520
Reputation: 45914
But when i have / in my topic name then URL returns "Not found".
You actually have 2 main problems here, only the first is addressed by the current answers:
Your RewriteRule
pattern (ie. ([^/]+)
) does not allow slashes (/
) in this part of the URL, so AC/DC
will never be matched. As stated in the other answers, you need to modify this pattern to something like (.+)
. (Although, ideally, you should be as restrictive as possible.) NB: The pattern matches the %-decoded URL, so you need a regex that matches AC/DC
, not AC%2FDC
.
Apache will, by default, block any URLs that contain an encoded slash in the path part of the URL ie. %2F
. In this situation, it will automatically return a system generated 404 Not Found before mod_rewrite gets to have a go. This is a security feature. And is most probably the result you are seeing here. If you need encoded slashes in the URL then you'll need to explicitly enable this with AllowEncodedSlashes On
in the Apache server config (this can't be enabled in .htaccess
).
Note that, as mentioned, this is an Apache generated 404 message. If you have a custom 404 defined, then you should notice a difference.
Reference:
https://httpd.apache.org/docs/2.4/mod/core.html#allowencodedslashes
RewriteRule ^([^\.]+)$ $1.php [NC,L] RewriteRule Topics/([^/]+)$ topics.php?topic_name=$1 [L,QSA]
UPDATE: These rules conflict. The first rule will likely "win" for most of your URLs. You need to be more specific in the RewriteRule
pattern. For instance, a URL like Topics/AC%2FDC
will also match the first rule, so the second rule is never processed.
Upvotes: 0
Reputation: 42935
Your pattern explicitly prevents the acceptance of a further slash in the request URL, the [^/]
describes a character set that may contain anything but a slash. You can modify it such that it accepts and rewrites an arbitrary character set:
RewriteEngine on
RewriteRule ^/?Topics/(.+)/?$ topics.php?topic_name=$1 [L,QSA]
However keep in mind that this now rewrites all incoming requests starting with /Topic/
.
I also modified the pattern slightly so that it is a bit more robust and will work likewise in the http servers host configuration and in dynamic configuration files (".htaccess")...
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess
style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).
UPDATE:
You added another existing rewrite rule that certainly will interfere here. Actually I would expect it to create an endless rewrite loop... I would recommend to add two conditions to that additional rule limiting the application of that rule to only those requests that do not immediately hit an existing file and that do reference an existing file with added .php
extension. That probably is what you want:
RewriteEngine on
RewriteRule ^/?Topics/(.+)/?$ topics.php?topic_name=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Upvotes: 2
Reputation: 549
In the regex Topics/([^/]+)$
the [^/]+
part means "everything that is more than one character up to a '/' symbol". So when you try to match Topics/AC/DC
the [^/]+
part will only match AC. And since you added a $
sign to the end (which means "this is the end of the input") the string won't match.
For more information see this demo: https://regex101.com/r/GJTDik/1
Upvotes: 1
Reputation: 146540
You are filtering out slashes and complaining that slashes do not match. If you want to capture everything, just do so:
RewriteRule Topics/(.+)$ topics.php?topic_name=$1 [L,QSA]
Upvotes: 1