So I put an index.php in /pipe/index.php
I’d like to rewrite (internal, not redirect)
https://host/pipe?token=abc
to https://host/pipe/index.php?token=abc
what I tried (caveat, assumes there is always a ? in the url):
RewriteEngine on
RewriteRule "^([^?]*)(.*)$" "$1/$2" [PT]
my hope was to split at the ? and just insert a / there.
But it seems apache finds out that "oh, pipe is a folder" before checking my .htacces (?) Because despite my [PT] it still redirects with 301 to /pipe/?token=abc
, when I hoped for internal rewrite.
2
Answers
This probably is what you are looking for:
The
QSA
flag is actually redundant here, it is the default, but it makes things clearer if you compare it to that variant (both work):The documentation of the rewriting module, more specific of the
RewriteRule
directive clearly points out that the query string is not part of the path the rule’s pattern is matched against.If you want to have more control about the content of the query string you can use a
RewriteCond
:Also you might want to redirect the original URL:
And finally you might also want to take a look at the
DirectoryIndex
directive which might offer a solution without any rewriting at all, though this depends a bit on your setup …Yes, mod_dir will append the trailing slash with a 301 redirect. Although this occurs after mod_rewrite has processed the URL (if indeed it is being processed at all – see below). (The
PT
flag is irrelevant in.htaccess
, since the resulting rewrite is passed through as a URL-path by default.)However, your existing rule (by itself) would result in a rewrite-loop (500 Internal Server Error) since it matches itself and repeatedly appends a slash. If you are seeing a 301 redirect as mentioned above then either this rule is not doing anything (are
.htaccess
overrides enabled?) or you have a conflict with other rules.As you’ve stated, this rule also assumes that the query string (with leading
?
) is also matched by theRewriteRule
pattern. TheRewriteRule
directive matches against the URL-path only, not the query string.$2
in the above rule is therefore always empty (unless you have%3F
in the URL-path, ie. a %-encoded?
).The query string is contained in its own variable,
QUERY_STRING
. But you simply want to pass through the same query string, so you don’t need to do anything special here, since that happens by default.Solution
To prevent mod_dir appending the trailing slash, you need to set
DirectorySlash Off
at the top of the root.htaccess
file.For example:
However, you need to then manually append the trailing slash to any directory, where it is omitted, with an internal rewrite to "fix" the URL (and to correctly serve the
DirectoryIndex
document, ie.index.php
).The trailing slash on the directory (via the internal rewrite) is required in order to serve the
DirectoryIndex
document, otherwise, you get a 403 Forbidden, even if theDirectoryIndex
document is present.If the trailing slash is omitted and directory listings (mod_autoindex) are enabled (disabled above) then a directory listing would be generated even if a
DirectoryIndex
document is present in that directory. (Which is why directory listings must be disabled whenDirectorySlash Off
is set.)NB: You will need to make sure the browser cache is cleared since the earlier 301 redirect by mod_dir to append the trailing slash will have been cached by the browser.