/unit/src/ |
H A D | nxt_job.c | diff 2403:81b1e3a34636 Tue Mar 14 17:31:00 UTC 2023 Andrew Clayton <a.clayton@nginx.com> Prevent a possible NULL de-reference in nxt_job_create().
We allocate 'job' we then have a check if it's not NULL and do stuff with it, but then we accessed it outside this check.
Simply return if job is NULL.
Reviewed-by: Alejandro Colomar <alx@nginx.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
|
H A D | nxt_http_return.c | diff 2081:c68e6afffb84 Tue Apr 05 09:47:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Supporting variables in "location".
............ Description: ............
Before this commit, the encoded URI could be calculated at configuration time. Now, since variables can only be resolved at request time, we have different situations:
- "location" contains no variables:
In this case, we still encode the URI in the conf structure, at configuration time, and then we just copy the resulting string to the ctx structure at request time.
- "location" contains variables:
In this case, we compile the var string at configure time, then when we resolve it at request time, and then we encode the string.
In both cases, as was being done before, if the string is empty, either before or after resolving variables, we skip the encoding.
........... Usefulness: ...........
An example of why this feature may be useful is redirecting HTTP to HTTPS with something like:
"action": { "return": 301, "location": "https://${host}${uri}" }
..... Bugs: .....
This feature conflicts with the relevant RFCs in the following:
'$' is used for Unit variables, but '$' is a reserved character in a URI, to be used as a sub-delimiter. However, it's almost never used as that, and in fact, other parts of Unit already conflict with '$' being a reserved character for use as a sub-delimiter, so this is at least consistent in that sense. VBart suggested an easy workaround if we ever need it: adding a variable '$sign' which resolves to a literal '$'.
...... Notes: ......
An empty string is handled as if "location" wasn't specified at all, so no Location header is sent.
This is incorrect, and the code is slightly misleading.
The Location header consists of a URI-reference[1], which might be a relative one, which itself might consist of an empty string[2].
[1]: <https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2> [2]: <https://stackoverflow.com/a/43338457>
Now that we have variables, it's more likely that an empty Location header will be requested, and we should handle it correctly.
I think in a future commit we should modify the code to allow differentiating between an unset "location" and an empty one, which should be treated as any other "location" string.
................. Testing (manual): .................
{ "listeners": { "*:80": { "pass": "routes/str" }, "*:81": { "pass": "routes/empty" }, "*:82": { "pass": "routes/var" }, "*:83": { "pass": "routes/enc-str" }, "*:84": { "pass": "routes/enc-var" } }, "routes": { "str": [ { "action": { "return": 301, "location": "foo" } } ], "empty": [ { "action": { "return": 301, "location": "" } } ], "var": [ { "action": { "return": 301, "location": "$host" } } ], "enc-str": [ { "action": { "return": 301, "location": "f%23o#o" } } ], "enc-var": [ { "action": { "return": 301, "location": "f%23o${host}#o" } } ] } }
$ curl --dump-header - localhost:80 HTTP/1.1 301 Moved Permanently Location: foo Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:06 GMT Content-Length: 0
$ curl --dump-header - localhost:81 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:08 GMT Content-Length: 0
$ curl --dump-header - localhost:82 HTTP/1.1 301 Moved Permanently Location: localhost Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:15 GMT Content-Length: 0
$ curl --dump-header - -H "Host: bar" localhost:82 HTTP/1.1 301 Moved Permanently Location: bar Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:82 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:29 GMT Content-Length: 0
$ curl --dump-header - localhost:83 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:44 GMT Content-Length: 0
$ curl --dump-header - -H "Host: alx" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23oalx#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:52 GMT Content-Length: 0
$ curl --dump-header - -H "Host: a#l%23x" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%2523oa#l%2523x%23o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:23:09 GMT Content-Length: 0
$ curl --dump-header - -H "Host: b##ar" localhost:82 HTTP/1.1 301 Moved Permanently Location: b#%23ar Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:25:01 GMT Content-Length: 0 diff 2081:c68e6afffb84 Tue Apr 05 09:47:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Supporting variables in "location".
............ Description: ............
Before this commit, the encoded URI could be calculated at configuration time. Now, since variables can only be resolved at request time, we have different situations:
- "location" contains no variables:
In this case, we still encode the URI in the conf structure, at configuration time, and then we just copy the resulting string to the ctx structure at request time.
- "location" contains variables:
In this case, we compile the var string at configure time, then when we resolve it at request time, and then we encode the string.
In both cases, as was being done before, if the string is empty, either before or after resolving variables, we skip the encoding.
........... Usefulness: ...........
An example of why this feature may be useful is redirecting HTTP to HTTPS with something like:
"action": { "return": 301, "location": "https://${host}${uri}" }
..... Bugs: .....
This feature conflicts with the relevant RFCs in the following:
'$' is used for Unit variables, but '$' is a reserved character in a URI, to be used as a sub-delimiter. However, it's almost never used as that, and in fact, other parts of Unit already conflict with '$' being a reserved character for use as a sub-delimiter, so this is at least consistent in that sense. VBart suggested an easy workaround if we ever need it: adding a variable '$sign' which resolves to a literal '$'.
...... Notes: ......
An empty string is handled as if "location" wasn't specified at all, so no Location header is sent.
This is incorrect, and the code is slightly misleading.
The Location header consists of a URI-reference[1], which might be a relative one, which itself might consist of an empty string[2].
[1]: <https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2> [2]: <https://stackoverflow.com/a/43338457>
Now that we have variables, it's more likely that an empty Location header will be requested, and we should handle it correctly.
I think in a future commit we should modify the code to allow differentiating between an unset "location" and an empty one, which should be treated as any other "location" string.
................. Testing (manual): .................
{ "listeners": { "*:80": { "pass": "routes/str" }, "*:81": { "pass": "routes/empty" }, "*:82": { "pass": "routes/var" }, "*:83": { "pass": "routes/enc-str" }, "*:84": { "pass": "routes/enc-var" } }, "routes": { "str": [ { "action": { "return": 301, "location": "foo" } } ], "empty": [ { "action": { "return": 301, "location": "" } } ], "var": [ { "action": { "return": 301, "location": "$host" } } ], "enc-str": [ { "action": { "return": 301, "location": "f%23o#o" } } ], "enc-var": [ { "action": { "return": 301, "location": "f%23o${host}#o" } } ] } }
$ curl --dump-header - localhost:80 HTTP/1.1 301 Moved Permanently Location: foo Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:06 GMT Content-Length: 0
$ curl --dump-header - localhost:81 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:08 GMT Content-Length: 0
$ curl --dump-header - localhost:82 HTTP/1.1 301 Moved Permanently Location: localhost Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:15 GMT Content-Length: 0
$ curl --dump-header - -H "Host: bar" localhost:82 HTTP/1.1 301 Moved Permanently Location: bar Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:82 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:29 GMT Content-Length: 0
$ curl --dump-header - localhost:83 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:44 GMT Content-Length: 0
$ curl --dump-header - -H "Host: alx" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23oalx#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:52 GMT Content-Length: 0
$ curl --dump-header - -H "Host: a#l%23x" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%2523oa#l%2523x%23o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:23:09 GMT Content-Length: 0
$ curl --dump-header - -H "Host: b##ar" localhost:82 HTTP/1.1 301 Moved Permanently Location: b#%23ar Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:25:01 GMT Content-Length: 0
|
H A D | nxt_http_variables.c | diff 2110:048281cd3d73 Thu May 26 12:38:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Var: Added $request_uri (as in NGINX).
This supports a new variable $request_uri that contains the path and the query (See RFC 3986, section 3). Its contents are percent encoded. This is useful for example to redirect HTTP to HTTPS:
{ "return": "301", "location": "https://$host$request_uri" }
When <http://example.com/foo%23bar?baz> is requested, the server redirects to <https://example.com/foo%23bar?baz>.
===
Testing:
//diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c //index 82c9156..adeb3a1 100644 //--- a/src/nxt_http_return.c //+++ b/src/nxt_http_return.c //@@ -196,6 +196,7 @@ nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data) // field->value = ctx->encoded.start; // field->value_length = ctx->encoded.length; // } //+ fprintf(stderr, "ALX: target[%1$i]: <%2$.*1$s>\n", (int)r->target.length, r->target.start); // // r->state = &nxt_http_return_send_state; //
{ "listeners": { "*:81": { "pass": "routes/ru" } },
"routes": { "ru": [{ "action": { "return": 301, "location": "$request_uri" } }] } }
$ curl -i http://localhost:81/*foo%2Abar?baz#arg HTTP/1.1 301 Moved Permanently Location: /*foo%2Abar?baz Server: Unit/1.27.0 Date: Mon, 30 May 2022 16:04:30 GMT Content-Length: 0
$ sudo cat /usr/local/unit.log | grep ALX ALX: target[15]: </*foo%2Abar?baz> diff 2110:048281cd3d73 Thu May 26 12:38:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Var: Added $request_uri (as in NGINX).
This supports a new variable $request_uri that contains the path and the query (See RFC 3986, section 3). Its contents are percent encoded. This is useful for example to redirect HTTP to HTTPS:
{ "return": "301", "location": "https://$host$request_uri" }
When <http://example.com/foo%23bar?baz> is requested, the server redirects to <https://example.com/foo%23bar?baz>.
===
Testing:
//diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c //index 82c9156..adeb3a1 100644 //--- a/src/nxt_http_return.c //+++ b/src/nxt_http_return.c //@@ -196,6 +196,7 @@ nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data) // field->value = ctx->encoded.start; // field->value_length = ctx->encoded.length; // } //+ fprintf(stderr, "ALX: target[%1$i]: <%2$.*1$s>\n", (int)r->target.length, r->target.start); // // r->state = &nxt_http_return_send_state; //
{ "listeners": { "*:81": { "pass": "routes/ru" } },
"routes": { "ru": [{ "action": { "return": 301, "location": "$request_uri" } }] } }
$ curl -i http://localhost:81/*foo%2Abar?baz#arg HTTP/1.1 301 Moved Permanently Location: /*foo%2Abar?baz Server: Unit/1.27.0 Date: Mon, 30 May 2022 16:04:30 GMT Content-Length: 0
$ sudo cat /usr/local/unit.log | grep ALX ALX: target[15]: </*foo%2Abar?baz>
|
H A D | nxt_port.c | diff 81:87fd26c34ebe Fri Jun 23 16:20:00 UTC 2017 Max Romanov <max.romanov@nginx.com> Extruded nxt_port_send_port() to send port to one process.
|
H A D | nxt_port.h | diff 81:87fd26c34ebe Fri Jun 23 16:20:00 UTC 2017 Max Romanov <max.romanov@nginx.com> Extruded nxt_port_send_port() to send port to one process.
|
H A D | nxt_conf_validation.c | diff 2081:c68e6afffb84 Tue Apr 05 09:47:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Supporting variables in "location".
............ Description: ............
Before this commit, the encoded URI could be calculated at configuration time. Now, since variables can only be resolved at request time, we have different situations:
- "location" contains no variables:
In this case, we still encode the URI in the conf structure, at configuration time, and then we just copy the resulting string to the ctx structure at request time.
- "location" contains variables:
In this case, we compile the var string at configure time, then when we resolve it at request time, and then we encode the string.
In both cases, as was being done before, if the string is empty, either before or after resolving variables, we skip the encoding.
........... Usefulness: ...........
An example of why this feature may be useful is redirecting HTTP to HTTPS with something like:
"action": { "return": 301, "location": "https://${host}${uri}" }
..... Bugs: .....
This feature conflicts with the relevant RFCs in the following:
'$' is used for Unit variables, but '$' is a reserved character in a URI, to be used as a sub-delimiter. However, it's almost never used as that, and in fact, other parts of Unit already conflict with '$' being a reserved character for use as a sub-delimiter, so this is at least consistent in that sense. VBart suggested an easy workaround if we ever need it: adding a variable '$sign' which resolves to a literal '$'.
...... Notes: ......
An empty string is handled as if "location" wasn't specified at all, so no Location header is sent.
This is incorrect, and the code is slightly misleading.
The Location header consists of a URI-reference[1], which might be a relative one, which itself might consist of an empty string[2].
[1]: <https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2> [2]: <https://stackoverflow.com/a/43338457>
Now that we have variables, it's more likely that an empty Location header will be requested, and we should handle it correctly.
I think in a future commit we should modify the code to allow differentiating between an unset "location" and an empty one, which should be treated as any other "location" string.
................. Testing (manual): .................
{ "listeners": { "*:80": { "pass": "routes/str" }, "*:81": { "pass": "routes/empty" }, "*:82": { "pass": "routes/var" }, "*:83": { "pass": "routes/enc-str" }, "*:84": { "pass": "routes/enc-var" } }, "routes": { "str": [ { "action": { "return": 301, "location": "foo" } } ], "empty": [ { "action": { "return": 301, "location": "" } } ], "var": [ { "action": { "return": 301, "location": "$host" } } ], "enc-str": [ { "action": { "return": 301, "location": "f%23o#o" } } ], "enc-var": [ { "action": { "return": 301, "location": "f%23o${host}#o" } } ] } }
$ curl --dump-header - localhost:80 HTTP/1.1 301 Moved Permanently Location: foo Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:06 GMT Content-Length: 0
$ curl --dump-header - localhost:81 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:08 GMT Content-Length: 0
$ curl --dump-header - localhost:82 HTTP/1.1 301 Moved Permanently Location: localhost Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:15 GMT Content-Length: 0
$ curl --dump-header - -H "Host: bar" localhost:82 HTTP/1.1 301 Moved Permanently Location: bar Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:82 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:29 GMT Content-Length: 0
$ curl --dump-header - localhost:83 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:44 GMT Content-Length: 0
$ curl --dump-header - -H "Host: alx" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23oalx#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:52 GMT Content-Length: 0
$ curl --dump-header - -H "Host: a#l%23x" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%2523oa#l%2523x%23o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:23:09 GMT Content-Length: 0
$ curl --dump-header - -H "Host: b##ar" localhost:82 HTTP/1.1 301 Moved Permanently Location: b#%23ar Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:25:01 GMT Content-Length: 0 diff 2081:c68e6afffb84 Tue Apr 05 09:47:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Supporting variables in "location".
............ Description: ............
Before this commit, the encoded URI could be calculated at configuration time. Now, since variables can only be resolved at request time, we have different situations:
- "location" contains no variables:
In this case, we still encode the URI in the conf structure, at configuration time, and then we just copy the resulting string to the ctx structure at request time.
- "location" contains variables:
In this case, we compile the var string at configure time, then when we resolve it at request time, and then we encode the string.
In both cases, as was being done before, if the string is empty, either before or after resolving variables, we skip the encoding.
........... Usefulness: ...........
An example of why this feature may be useful is redirecting HTTP to HTTPS with something like:
"action": { "return": 301, "location": "https://${host}${uri}" }
..... Bugs: .....
This feature conflicts with the relevant RFCs in the following:
'$' is used for Unit variables, but '$' is a reserved character in a URI, to be used as a sub-delimiter. However, it's almost never used as that, and in fact, other parts of Unit already conflict with '$' being a reserved character for use as a sub-delimiter, so this is at least consistent in that sense. VBart suggested an easy workaround if we ever need it: adding a variable '$sign' which resolves to a literal '$'.
...... Notes: ......
An empty string is handled as if "location" wasn't specified at all, so no Location header is sent.
This is incorrect, and the code is slightly misleading.
The Location header consists of a URI-reference[1], which might be a relative one, which itself might consist of an empty string[2].
[1]: <https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2> [2]: <https://stackoverflow.com/a/43338457>
Now that we have variables, it's more likely that an empty Location header will be requested, and we should handle it correctly.
I think in a future commit we should modify the code to allow differentiating between an unset "location" and an empty one, which should be treated as any other "location" string.
................. Testing (manual): .................
{ "listeners": { "*:80": { "pass": "routes/str" }, "*:81": { "pass": "routes/empty" }, "*:82": { "pass": "routes/var" }, "*:83": { "pass": "routes/enc-str" }, "*:84": { "pass": "routes/enc-var" } }, "routes": { "str": [ { "action": { "return": 301, "location": "foo" } } ], "empty": [ { "action": { "return": 301, "location": "" } } ], "var": [ { "action": { "return": 301, "location": "$host" } } ], "enc-str": [ { "action": { "return": 301, "location": "f%23o#o" } } ], "enc-var": [ { "action": { "return": 301, "location": "f%23o${host}#o" } } ] } }
$ curl --dump-header - localhost:80 HTTP/1.1 301 Moved Permanently Location: foo Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:06 GMT Content-Length: 0
$ curl --dump-header - localhost:81 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:08 GMT Content-Length: 0
$ curl --dump-header - localhost:82 HTTP/1.1 301 Moved Permanently Location: localhost Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:15 GMT Content-Length: 0
$ curl --dump-header - -H "Host: bar" localhost:82 HTTP/1.1 301 Moved Permanently Location: bar Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:82 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:29 GMT Content-Length: 0
$ curl --dump-header - localhost:83 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:44 GMT Content-Length: 0
$ curl --dump-header - -H "Host: alx" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23oalx#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:52 GMT Content-Length: 0
$ curl --dump-header - -H "Host: a#l%23x" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%2523oa#l%2523x%23o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:23:09 GMT Content-Length: 0
$ curl --dump-header - -H "Host: b##ar" localhost:82 HTTP/1.1 301 Moved Permanently Location: b#%23ar Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:25:01 GMT Content-Length: 0
|
H A D | nxt_php_sapi.c | diff 1700:81c7ce33cd2a Tue Nov 10 21:09:00 UTC 2020 Valentin Bartenev <vbart@nginx.com> PHP: implementation of the fastcgi_finish_request() function.
This closes #219 issue on GitHub.
|
/unit/docs/ |
H A D | changes.xml | diff 2110:048281cd3d73 Thu May 26 12:38:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Var: Added $request_uri (as in NGINX).
This supports a new variable $request_uri that contains the path and the query (See RFC 3986, section 3). Its contents are percent encoded. This is useful for example to redirect HTTP to HTTPS:
{ "return": "301", "location": "https://$host$request_uri" }
When <http://example.com/foo%23bar?baz> is requested, the server redirects to <https://example.com/foo%23bar?baz>.
===
Testing:
//diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c //index 82c9156..adeb3a1 100644 //--- a/src/nxt_http_return.c //+++ b/src/nxt_http_return.c //@@ -196,6 +196,7 @@ nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data) // field->value = ctx->encoded.start; // field->value_length = ctx->encoded.length; // } //+ fprintf(stderr, "ALX: target[%1$i]: <%2$.*1$s>\n", (int)r->target.length, r->target.start); // // r->state = &nxt_http_return_send_state; //
{ "listeners": { "*:81": { "pass": "routes/ru" } },
"routes": { "ru": [{ "action": { "return": 301, "location": "$request_uri" } }] } }
$ curl -i http://localhost:81/*foo%2Abar?baz#arg HTTP/1.1 301 Moved Permanently Location: /*foo%2Abar?baz Server: Unit/1.27.0 Date: Mon, 30 May 2022 16:04:30 GMT Content-Length: 0
$ sudo cat /usr/local/unit.log | grep ALX ALX: target[15]: </*foo%2Abar?baz> diff 2110:048281cd3d73 Thu May 26 12:38:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Var: Added $request_uri (as in NGINX).
This supports a new variable $request_uri that contains the path and the query (See RFC 3986, section 3). Its contents are percent encoded. This is useful for example to redirect HTTP to HTTPS:
{ "return": "301", "location": "https://$host$request_uri" }
When <http://example.com/foo%23bar?baz> is requested, the server redirects to <https://example.com/foo%23bar?baz>.
===
Testing:
//diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c //index 82c9156..adeb3a1 100644 //--- a/src/nxt_http_return.c //+++ b/src/nxt_http_return.c //@@ -196,6 +196,7 @@ nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data) // field->value = ctx->encoded.start; // field->value_length = ctx->encoded.length; // } //+ fprintf(stderr, "ALX: target[%1$i]: <%2$.*1$s>\n", (int)r->target.length, r->target.start); // // r->state = &nxt_http_return_send_state; //
{ "listeners": { "*:81": { "pass": "routes/ru" } },
"routes": { "ru": [{ "action": { "return": 301, "location": "$request_uri" } }] } }
$ curl -i http://localhost:81/*foo%2Abar?baz#arg HTTP/1.1 301 Moved Permanently Location: /*foo%2Abar?baz Server: Unit/1.27.0 Date: Mon, 30 May 2022 16:04:30 GMT Content-Length: 0
$ sudo cat /usr/local/unit.log | grep ALX ALX: target[15]: </*foo%2Abar?baz> diff 2081:c68e6afffb84 Tue Apr 05 09:47:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Supporting variables in "location".
............ Description: ............
Before this commit, the encoded URI could be calculated at configuration time. Now, since variables can only be resolved at request time, we have different situations:
- "location" contains no variables:
In this case, we still encode the URI in the conf structure, at configuration time, and then we just copy the resulting string to the ctx structure at request time.
- "location" contains variables:
In this case, we compile the var string at configure time, then when we resolve it at request time, and then we encode the string.
In both cases, as was being done before, if the string is empty, either before or after resolving variables, we skip the encoding.
........... Usefulness: ...........
An example of why this feature may be useful is redirecting HTTP to HTTPS with something like:
"action": { "return": 301, "location": "https://${host}${uri}" }
..... Bugs: .....
This feature conflicts with the relevant RFCs in the following:
'$' is used for Unit variables, but '$' is a reserved character in a URI, to be used as a sub-delimiter. However, it's almost never used as that, and in fact, other parts of Unit already conflict with '$' being a reserved character for use as a sub-delimiter, so this is at least consistent in that sense. VBart suggested an easy workaround if we ever need it: adding a variable '$sign' which resolves to a literal '$'.
...... Notes: ......
An empty string is handled as if "location" wasn't specified at all, so no Location header is sent.
This is incorrect, and the code is slightly misleading.
The Location header consists of a URI-reference[1], which might be a relative one, which itself might consist of an empty string[2].
[1]: <https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2> [2]: <https://stackoverflow.com/a/43338457>
Now that we have variables, it's more likely that an empty Location header will be requested, and we should handle it correctly.
I think in a future commit we should modify the code to allow differentiating between an unset "location" and an empty one, which should be treated as any other "location" string.
................. Testing (manual): .................
{ "listeners": { "*:80": { "pass": "routes/str" }, "*:81": { "pass": "routes/empty" }, "*:82": { "pass": "routes/var" }, "*:83": { "pass": "routes/enc-str" }, "*:84": { "pass": "routes/enc-var" } }, "routes": { "str": [ { "action": { "return": 301, "location": "foo" } } ], "empty": [ { "action": { "return": 301, "location": "" } } ], "var": [ { "action": { "return": 301, "location": "$host" } } ], "enc-str": [ { "action": { "return": 301, "location": "f%23o#o" } } ], "enc-var": [ { "action": { "return": 301, "location": "f%23o${host}#o" } } ] } }
$ curl --dump-header - localhost:80 HTTP/1.1 301 Moved Permanently Location: foo Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:06 GMT Content-Length: 0
$ curl --dump-header - localhost:81 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:08 GMT Content-Length: 0
$ curl --dump-header - localhost:82 HTTP/1.1 301 Moved Permanently Location: localhost Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:15 GMT Content-Length: 0
$ curl --dump-header - -H "Host: bar" localhost:82 HTTP/1.1 301 Moved Permanently Location: bar Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:82 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:29 GMT Content-Length: 0
$ curl --dump-header - localhost:83 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:44 GMT Content-Length: 0
$ curl --dump-header - -H "Host: alx" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23oalx#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:52 GMT Content-Length: 0
$ curl --dump-header - -H "Host: a#l%23x" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%2523oa#l%2523x%23o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:23:09 GMT Content-Length: 0
$ curl --dump-header - -H "Host: b##ar" localhost:82 HTTP/1.1 301 Moved Permanently Location: b#%23ar Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:25:01 GMT Content-Length: 0 diff 2081:c68e6afffb84 Tue Apr 05 09:47:00 UTC 2022 Alejandro Colomar <alx.manpages@gmail.com> Supporting variables in "location".
............ Description: ............
Before this commit, the encoded URI could be calculated at configuration time. Now, since variables can only be resolved at request time, we have different situations:
- "location" contains no variables:
In this case, we still encode the URI in the conf structure, at configuration time, and then we just copy the resulting string to the ctx structure at request time.
- "location" contains variables:
In this case, we compile the var string at configure time, then when we resolve it at request time, and then we encode the string.
In both cases, as was being done before, if the string is empty, either before or after resolving variables, we skip the encoding.
........... Usefulness: ...........
An example of why this feature may be useful is redirecting HTTP to HTTPS with something like:
"action": { "return": 301, "location": "https://${host}${uri}" }
..... Bugs: .....
This feature conflicts with the relevant RFCs in the following:
'$' is used for Unit variables, but '$' is a reserved character in a URI, to be used as a sub-delimiter. However, it's almost never used as that, and in fact, other parts of Unit already conflict with '$' being a reserved character for use as a sub-delimiter, so this is at least consistent in that sense. VBart suggested an easy workaround if we ever need it: adding a variable '$sign' which resolves to a literal '$'.
...... Notes: ......
An empty string is handled as if "location" wasn't specified at all, so no Location header is sent.
This is incorrect, and the code is slightly misleading.
The Location header consists of a URI-reference[1], which might be a relative one, which itself might consist of an empty string[2].
[1]: <https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2> [2]: <https://stackoverflow.com/a/43338457>
Now that we have variables, it's more likely that an empty Location header will be requested, and we should handle it correctly.
I think in a future commit we should modify the code to allow differentiating between an unset "location" and an empty one, which should be treated as any other "location" string.
................. Testing (manual): .................
{ "listeners": { "*:80": { "pass": "routes/str" }, "*:81": { "pass": "routes/empty" }, "*:82": { "pass": "routes/var" }, "*:83": { "pass": "routes/enc-str" }, "*:84": { "pass": "routes/enc-var" } }, "routes": { "str": [ { "action": { "return": 301, "location": "foo" } } ], "empty": [ { "action": { "return": 301, "location": "" } } ], "var": [ { "action": { "return": 301, "location": "$host" } } ], "enc-str": [ { "action": { "return": 301, "location": "f%23o#o" } } ], "enc-var": [ { "action": { "return": 301, "location": "f%23o${host}#o" } } ] } }
$ curl --dump-header - localhost:80 HTTP/1.1 301 Moved Permanently Location: foo Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:06 GMT Content-Length: 0
$ curl --dump-header - localhost:81 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:08 GMT Content-Length: 0
$ curl --dump-header - localhost:82 HTTP/1.1 301 Moved Permanently Location: localhost Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:15 GMT Content-Length: 0
$ curl --dump-header - -H "Host: bar" localhost:82 HTTP/1.1 301 Moved Permanently Location: bar Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:82 HTTP/1.1 301 Moved Permanently Server: Unit/1.27.0 Date: Thu, 07 Apr 2022 23:30:29 GMT Content-Length: 0
$ curl --dump-header - localhost:83 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:23 GMT Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23o#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:44 GMT Content-Length: 0
$ curl --dump-header - -H "Host: alx" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%23oalx#o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:22:52 GMT Content-Length: 0
$ curl --dump-header - -H "Host: a#l%23x" localhost:84 HTTP/1.1 301 Moved Permanently Location: f%2523oa#l%2523x%23o Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:23:09 GMT Content-Length: 0
$ curl --dump-header - -H "Host: b##ar" localhost:82 HTTP/1.1 301 Moved Permanently Location: b#%23ar Server: Unit/1.27.0 Date: Sat, 09 Apr 2022 11:25:01 GMT Content-Length: 0
|