# Query part included in location match after rewrite (bug or feature?)

**URL:** <https://www.ruby-forum.com/t/query-part-included-in-location-match-after-rewrite-bug-or-feature/236549>\
**Category:** NGINX\
**Created:** [September 13, 2013, 2:49pm UTC](https://www.ruby-forum.com/t/query-part-included-in-location-match-after-rewrite-bug-or-feature/236549 "2013-09-13T14:49:11Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![alcina](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@alcina](https://www.ruby-forum.com/u/alcina)\
**Post date:** [September 13, 2013, 2:49pm UTC](https://www.ruby-forum.com/t/query-part-included-in-location-match-after-rewrite-bug-or-feature/236549/1 "2013-09-13T14:49:11Z")

</div>

Hi,

According to documentation, “location” matches only against URI path,  
ignoring query string. However, after “rewrite”, when using variables  
containing “?” character (like $request\_uri for illustration), query  
becomes  
part of $uri:

location /src/ {  
rewrite ^ /dst$request\_uri;  
}

location /dst/ {

# At this point, $uri contains query part from /src, like

/dst/src/?arg=val  
add\_header Content-Type text/plain;  
return 200 “$request\_uri $uri $args”;  
}

For request like “/src/?arg=val” the output will be: /src/?arg=val  
/dst/src/?arg=val arg=val

Thus, $uri (and matched part) contains query, and $args _also_ contains  
query (inherited from original request). All together, this may lead to  
quite unexpected results in some configurations.

So, my question is - is this expected behavior (just undocumented) or is  
a  
bug? To me it looks like a bug - allowing matching anything past “?” in  
location and making it part of $uri.

Posted at Nginx Forum:

> **[query part included in location match after rewrite (bug or feature?)](https://forum.nginx.org/read.php?2,242829,242829#msg-242829)**
>
> Hi, According to documentation, "location" matches only against URI path, ignoring query string. However, after "rewrite", when using variables containing "?" character (like $request\_uri for illustration), query becomes...

---

<div class="post-metadata">

**Author:** ![aldem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/74df32/32.png) [@aldem](https://www.ruby-forum.com/u/aldem)\
**Post date:** [September 13, 2013, 3:20pm UTC](https://www.ruby-forum.com/t/query-part-included-in-location-match-after-rewrite-bug-or-feature/236549/2 "2013-09-13T15:20:08Z")

</div>

On Fri, Sep 13, 2013 at 08:48:55AM -0400, aldem wrote:

Hi there,

> According to documentation, “location” matches only against URI path,  
> ignoring query string. However, after “rewrite”, when using variables  
> containing “?” character (like $request\_uri for illustration), query becomes  
> part of $uri:

My reading of this is that you must give rewrite an explicit ? to mark  
the query string, so a ? within a variable _is_ part of $uri if it comes  
before a ?. If you want to have your own query string, or to lose the  
original query string during the rewrite, you must use an explicit ?.

> So, my question is - is this expected behavior (just undocumented) or is a  
> bug? To me it looks like a bug - allowing matching anything past “?” in  
> location and making it part of $uri.

? is a valid character in a normalised uri. ? is special in an escaped  
uri, since it marks the query string. “rewrite” creates a normalised uri  
(at least, when given variables to expand).

I’d say “expected”, unless there’s an example where “rewrite” does not  
create a normalised uri.

## f

Francis D. removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![aldem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/74df32/32.png) [@aldem](https://www.ruby-forum.com/u/aldem)\
**Post date:** [September 13, 2013, 3:48pm UTC](https://www.ruby-forum.com/t/query-part-included-in-location-match-after-rewrite-bug-or-feature/236549/3 "2013-09-13T15:48:46Z")

</div>

Well, this is where I am lost a bit - documentation only says  
“replacement  
string”, and from my understanding this includes possible expansion of  
variables (like everywhere else), and it doesn’t mention (or I couldn’t  
find, at least) that rewrite target is normalized URI (or that variables  
could be processed differently). Probably, this is the only case where  
expansion is processed differently from literal values.

On the other hand, if rewrite target expects a normalized URI, then  
mangling  
with arguments there should not be possible at all, as there could be  
mixture of normalized and escaped values in single string.

Posted at Nginx Forum:

> **[Re: query part included in location match after rewrite (bug or feature?)](https://forum.nginx.org/read.php?2,242829,242831#msg-242831)**
>
> Hi, According to documentation, "location" matches only against URI path, ignoring query string. However, after "rewrite", when using variables containing "?" character (like $request\_uri for illustration), query becomes...

---

<div class="post-metadata">

**Author:** ![aldem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/74df32/32.png) [@aldem](https://www.ruby-forum.com/u/aldem)\
**Post date:** [September 13, 2013, 4:25pm UTC](https://www.ruby-forum.com/t/query-part-included-in-location-match-after-rewrite-bug-or-feature/236549/4 "2013-09-13T16:25:34Z")

</div>

On Fri, Sep 13, 2013 at 09:48:05AM -0400, aldem wrote:

Hi there,

reading through ngx\_http\_rewrite\_module.c and thinking about it some  
more,  
I believe I was wrong in my previous mail.

I tried to simplify too much.

> Well, this is where I am lost a bit - documentation only says “replacement  
> string”, and from my understanding this includes possible expansion of  
> variables (like everywhere else), and it doesn’t mention (or I couldn’t  
> find, at least) that rewrite target is normalized URI (or that variables  
> could be processed differently). Probably, this is the only case where  
> expansion is processed differently from literal values.

The only true documentation for what the current version does is in the  
directory called “src”. Anything else is someone’s interpretation. (In  
many cases, the interpretation is correct; but there are often reasons  
why some edge cases are not documented outside of the source.)

My understanding is that rewrite will populate $uri with its  
“replacement”  
argument up to the first ?, and will populate $args after that if  
appropriate. While populating, it expands $variables.

For internal-to-nginx use, $uri and $args now have their values.

For external-to-nginx use, $uri and $args are concatenated with a  
separating ? if appropriate, and it is up to whatever reads the complete  
string to decide what to do with it.

> On the other hand, if rewrite target expects a normalized URI, then mangling  
> with arguments there should not be possible at all, as there could be  
> mixture of normalized and escaped values in single string.

The general philosophy of the nginx configuration seems to be that  
common  
things are straightforward, and uncommon things are no more than a  
module  
or a local patch away.

And also, the administrator is trusted to know what they are doing,  
so it is their responsibility to properly handle unescaped and escaped  
values. In the specific case of escaping, nginx in general can’t guess  
what the user wants.

It still looks like NOTABUG to me; but I’m not the one who wrote it.

## f

Francis D. removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![aldem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/74df32/32.png) [@aldem](https://www.ruby-forum.com/u/aldem)\
**Post date:** [September 13, 2013, 4:51pm UTC](https://www.ruby-forum.com/t/query-part-included-in-location-match-after-rewrite-bug-or-feature/236549/5 "2013-09-13T16:51:52Z")

</div>

Francis, thank you for your time and looking through the source 🙂

Though I still consider this issue as a “bug” (either in documentation  
or in  
consistence), what really matters is that understanding how it works is  
very  
helpful, and you did the perfect job explaining this.

Hopefully, someone, someday will describe this behavior in the  
documentation

- some things in nginx are not exactly intuitive…

Posted at Nginx Forum:

> **[Re: query part included in location match after rewrite (bug or feature?)](https://forum.nginx.org/read.php?2,242829,242835#msg-242835)**
>
> Hi, According to documentation, "location" matches only against URI path, ignoring query string. However, after "rewrite", when using variables containing "?" character (like $request\_uri for illustration), query becomes...
