[njs] Fetch: fixed request Host header when the port is non-standard.

Dmitry Volyntsev xeioex at nginx.com
Mon Apr 29 21:25:00 UTC 2024


details:   https://hg.nginx.org/njs/rev/7456fe29ac0a
branches:  
changeset: 2323:7456fe29ac0a
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Fri Apr 26 16:48:17 2024 -0700
description:
Fetch: fixed request Host header when the port is non-standard.

This fixes #707 issue on Github.

diffstat:

 nginx/ngx_js_fetch.c        |   5 +++
 nginx/t/js_fetch_resolver.t |  69 ++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 67 insertions(+), 7 deletions(-)

diffs (122 lines):

diff -r 622387b5b612 -r 7456fe29ac0a nginx/ngx_js_fetch.c
--- a/nginx/ngx_js_fetch.c	Fri Apr 26 16:27:52 2024 -0700
+++ b/nginx/ngx_js_fetch.c	Fri Apr 26 16:48:17 2024 -0700
@@ -786,6 +786,11 @@ ngx_js_ext_fetch(njs_vm_t *vm, njs_value
     if (!has_host) {
         njs_chb_append_literal(&http->chain, "Host: ");
         njs_chb_append(&http->chain, u.host.data, u.host.len);
+
+        if (!u.no_port) {
+            njs_chb_sprintf(&http->chain, 32, ":%d", u.port);
+        }
+
         njs_chb_append_literal(&http->chain, CRLF);
     }
 
diff -r 622387b5b612 -r 7456fe29ac0a nginx/t/js_fetch_resolver.t
--- a/nginx/t/js_fetch_resolver.t	Fri Apr 26 16:27:52 2024 -0700
+++ b/nginx/t/js_fetch_resolver.t	Fri Apr 26 16:48:17 2024 -0700
@@ -65,6 +65,23 @@ http {
         location /loc {
             js_content test.loc;
         }
+
+        location /host {
+            return 200 8080:$http_host;
+        }
+    }
+
+    server {
+        listen       127.0.0.1:8081;
+        server_name  aaa;
+
+        location /loc {
+            js_content test.loc;
+        }
+
+        location /host {
+            return 200 8081:$http_host;
+        }
     }
 
     server {
@@ -80,19 +97,29 @@ http {
 EOF
 
 my $p0 = port(8080);
+my $p1 = port(8081);
 
 $t->write_file('test.js', <<EOF);
     function test_njs(r) {
         r.return(200, njs.version);
     }
 
-    function dns(r) {
-        var url = `http://\${r.args.domain}:$p0/loc`;
+    const p0 = $p0;
+    const p1 = $p1;
+
+    async function dns(r) {
+        var port = r.args.port == undefined || r.args.port == 'p0' ? p0 : p1;
+        var loc = r.args.loc == undefined ? 'loc' : r.args.loc;
+        var url = `http://\${r.args.domain}:\${port}/\${loc}`;
 
-        ngx.fetch(url)
-        .then(reply => reply.text())
-        .then(body => r.return(200, body))
-        .catch(e => r.return(501, e.message))
+        try {
+            let reply = await ngx.fetch(url);
+            let body = await reply.text();
+            r.return(200, body);
+
+        } catch (e) {
+            r.return(501, e.message);
+        }
     }
 
     function str(v) { return v ? v : ''};
@@ -109,7 +136,7 @@ my $p0 = port(8080);
      export default {njs: test_njs, dns, loc};
 EOF
 
-$t->try_run('no njs.fetch')->plan(3);
+$t->try_run('no njs.fetch')->plan(5);
 
 $t->run_daemon(\&dns_daemon, port(8981), $t);
 $t->waitforfile($t->testdir . '/' . port(8981));
@@ -121,6 +148,34 @@ like(http_get('/dns?domain=many'), qr/ma
 like(http_get('/dns?domain=unknown'), qr/"unknown" could not be resolved/s,
 	'fetch dns unknown');
 
+TODO: {
+local $TODO = 'not yet' unless has_version('0.8.5');
+
+like(http_get('/dns?domain=aaa&port=p0&loc=host'), qr/8080:aaa:$p0$/s,
+	'fetch aaa:8080');
+like(http_get('/dns?domain=aaa&port=p1&loc=host'), qr/8081:aaa:$p1$/s,
+	'fetch aaa:8081');
+}
+
+###############################################################################
+
+sub has_version {
+	my $need = shift;
+
+	http_get('/njs') =~ /^([.0-9]+)$/m;
+
+	my @v = split(/\./, $1);
+	my ($n, $v);
+
+	for $n (split(/\./, $need)) {
+		$v = shift @v || 0;
+		return 0 if $n > $v;
+		return 1 if $v > $n;
+	}
+
+	return 1;
+}
+
 ###############################################################################
 
 sub reply_handler {


More information about the nginx-devel mailing list