1

I'm trying to have all requests going to //my.domain/download?id=xx (be it http or https) be processed by /path/to/my/download.php?id=xx.

I've tried all sorts of RewriteRule rules to no avail, so there's no point in me posting anything I have, but this is a Wordpress install, so this shouldn't conflict with WP's existing rules, which are:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

I would very much appreciate an explanation for any provided answer. Thank you!

EDIT

I already took a look at Redirect, Change URLs or Redirect HTTP to HTTPS in Apache - Everything You Ever Wanted to Know About Mod_Rewrite Rules but Were Afraid to Ask and can't seem to even pinpoint what section would cover this situation, as all that is too general. I'm looking for help wiht this specific situation.

EDIT 2

This is the code that is failing, with a 404, even if https://htaccess.madewithlove.be/ sais it shoudl all be good:

RewriteEngine on
RewriteCond %{REQUEST_URI} !^download
RewriteRule ^download(.*)$ wp-content/themes/XXX/inc/download.php$1

EDIT 3 I was having unrelated issues. For anyone else interested, see my answer below for the rules that worked.

Hlsg
  • 113
  • 5
  • 1
    Possible duplicate of [Redirect, Change URLs or Redirect HTTP to HTTPS in Apache - Everything You Ever Wanted to Know About Mod\_Rewrite Rules but Were Afraid to Ask](https://serverfault.com/questions/214512/redirect-change-urls-or-redirect-http-to-https-in-apache-everything-you-ever) – Gerald Schneider Nov 21 '19 at 13:45

2 Answers2

1

I'm trying to have all requests going to //my.domain/download?id=xx (be it http or https) be processed by /path/to/my/download.php?id=xx.

For this you probably want to internally rewrite the URL rather than externally redirect the request, as in your existing answer. An internal rewrite won't change the URL in the browser's address bar.

The directives in your existing answer can also be simplified.

Try the following instead, before the existing WordPress directives, in order to rewrite any request for /download?id=N to /path/to/my/download.php?id=N, where N is 1 or more digits.

RewriteCond %{QUERY_STRING} ^id=\d+$
RewriteRule ^download$ path/to/my/download.php [L]

\d is a shorthand character class which matches any digit. The same as [0-9]. The + quantifier matches 1 or more digits, so this will fail (404) if id= (with no value) is included in the query string. Change back to * if id= should be successful. There is no need to capture this value (ie. surround the pattern in parentheses as in ([0-9]*) since you are not using this in the substitution.

The query string, ie. id=N is copied through to the substitution by default.

There is no need to repeat the RewriteEngine On directive, since this is already part of the WordPress code block.

MrWhite
  • 11,643
  • 4
  • 25
  • 40
  • This worked, though i had to change to `RewriteCond %{QUERY_STRING} ^id=\d+(&direct)?$` since i may sometimes have the `direct` query variable aswell. Excellent! That being said, I think you may be right on the money about me actually needing to `internally rewrite` instead of redirect, because I'm also using `mod_xsendfile`, and I have to change to `RewriteRule ^download$ path/to/my/download.php [L,R]` for it to work( as per https://stackoverflow.com/questions/20705731/mod-xsendfile-wont-work-with-cgi-and-mod-rewrite ), which exposes the actual location of my php file. How would I do that? – Hlsg Nov 22 '19 at 12:05
0

This is the code that got what was asked working:

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/download$
RewriteCond %{QUERY_STRING} ^id=([0-9]*)$
RewriteRule ^download(.*)$ path/to/my/download.php$1 [L,R]
Hlsg
  • 113
  • 5
  • You probably want a "rewrite", rather than an external "redirect"? But these directives can also be simplified... The first `RewriteCond` directive is superfluous, since you are simply repeating the check already performed by the `RewriteRule` _pattern_. The capturing group `(.*)` and corresponding backreference `$1` are also not required. I've added an answer showing these changes with more explanation. – MrWhite Nov 21 '19 at 22:13