I am newby on working with mod_rewrite on apache and I am currently trying to write an url-shortener that takes an URL like mydomain/s/short/{UriToShorten}
and shortens the given URI.
What happens
When I pass an URI to the shortening route in my browser, like localhost/s/short/http://example.com
, the script shorten.php is invoked and the shortening process works as expected. However, if I encode the URL-Component and pass an URI like localhost/s/short/http%3A%2F%2Fexample.com
(which should be the correct use), I get the message
Not Found
The requested URL /s/short/http://example.com was not found on this server.
And debugging indicates, that neither shorten.php or index.php got run (so I believe, that the server really tries to search a subdirectory http:
of short
). This seems to happen independently where the slash encoding %2F is.
What is expected
I would expect, that the encoded version works, and maybe the unencoded URI will lead to an error (since URL-Encoding is specifily made to avoid those errors).
What I use
I use the following as .htaccess:
RewriteEngine On
RewriteBase /s/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^short/(.*)$ shorten.php?url=$1 [L,NC]
RewriteRule ^([a-z0-9]{5})$ index.php?slug=$1 [L,NC]
My folder structure is:
-www
-s
-.htaccess
-shorten.php
-index.php
and my Apache version is Apache/2.4.33
What I tried
Since I have no idea, why this happens, I could only search the mod_rewrite documentation and tried adding the [NE] Flag, that obviously didn’t work.
2
Answers
Okay, I found out what was causing the Problem:
The error did not occur on every encoded url character, but always when the URL contained %2F. So my Problem seems to be this SO question about encoded Slashes
I needed to set
AllowEncodedSlashes NoDecode
(or ON) inhttpd.conf
AND inhttpd-vhosts.conf
to make it work.Lesson Learned: Always Check the httpd.conf-features and turn on features explicitely, that you would expect to be on by default
This is happening because Apache blocks encoded slashes by default. Since Apache 2, it’s possible to allow them:
https://httpd.apache.org/docs/2.4/mod/core.html#allowencodedslashes
However, be careful about setting
AllowEncodedSlashes On
. This is a security measure made by Apache.If you want to enable encoded slashes, use
AllowEncodedSlashes NoDecode
instead. For example: