I assume these directives are working OK and you are just after an explanation as to why?
- How did my hostname (without
www.) end up in %1?
%1 is a backreference to the first captured group in the last matched CondPattern. So, given the following condition:
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
The regex (ie. CondPattern) ^www\.(.*)$ is matched against the HTTP_HOST server variable. The match is successful when HTTP_HOST satisfies the regex ^www\.(.*)$, which is www. followed by anything. That anything is part of a captured group (parenthesised subpattern). ie. (.*), not simply .*. Whatever matches the (.*) group is saved in the %1 backreference and can be used later in the RewriteRule substitution. For example, given a request for www.example.com/something, this becomes:
RewriteCond www.example.com ^www\.(.*)$ [NC]
%1 will therefore contain example.com.
Why isn't the query string lost when the second rule is applied?
Because, if you don't explicitly include a query string on the RewriteRule substitution then the query string from the request is automatically appended onto the end of the resulting substitution.
However, if you included a query string on the end of the substitution, even just an empty query string (a ? followed by nothing), then the query string from the request is not appended. For example:
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI}? [R=301,L,NE]
This will result in the query string being stripped from the request (note the trailing ?). Alternatively, on Apache 2.4+ you can use the QSD (Query String Discard) flag to prevent the query string being appended.
Aside: I also removed the parentheses from the RewriteRule pattern. You don't need a captured group here, since you are using the REQUEST_URI server variable instead. (This would be available in the $1 backreference - note the $ prefix. Storing backreferences when you don't need them is just waste of resources and hampers readability.)
RewriteCond %{HTTP:X-Forwarded-Proto} !https
I assume your server is behind a proxy server that is setting the X-Forwarded-Proto header?
%{REQUEST_URI}and$1would behave the same in both rules and are different only because I got the parts from different examples? If so, how should one choose which to use? And to expand on query string - is anything else "automatically appended" or only that? – Džuris Apr 22 '17 at 15:23example.organdassets.example.com. The assets onexample.orgare included usingassets.example.comdomain name which points to a proxy that caches the assets. That's why I had to put twoRewriteConds there. – Džuris Apr 22 '17 at 15:29%1is a backreference to the last matchedRewriteConddirective and$1is a backreference to theRewriteRulepattern. Using%{REQUEST_URI}or$1in this instance is largely a matter of preference. However, they are not necessarily the same - it depends on context. In a directory (incl..htaccess) context then they are slightly different, however, in a server config/virtual host context they are probably the same. – MrWhite Apr 22 '17 at 16:12.htaccessthen a request forexample.com/path/to/filewould result inREQUEST_URIcontaining/path/to/file, but$1would containpath/to/file(note the missing slash prefix). This is consistent with your code example and from that I would assume you are in a directory (or.htaccess) context? – MrWhite Apr 22 '17 at 16:13.htaccess. – Džuris Apr 22 '17 at 16:16RedirectandRedirectMatch(mod_alias) directives. As regards which to use...REQUEST_URIor$1...REQUEST_URIis always the same, regardless of whether you are using server config or.htaccess. But it's not always possible to use$1like this (instead ofREQUEST_URI), for example:RewriteRule !^foo$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]- this only redirects when the request is not/foo. (It's not possible to have a captured group in a negated regex.) – MrWhite Apr 22 '17 at 16:29