openresty / openresty/lua-nginx-module

Reading ngx.var.http_host prevents updating the Host header

Open
#1,301 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
11.8k
Forks
2.1k
Avg merge
6h 1m
Merged PRs (30d)
6

Description

Not sure if this is a bug, but the behavior is very strange. When the Host header is read using ngx.var.http_host, setting the Host header later with ngx.req.set_header doesn't seem to be updating it.

Test for reproducing (thanks to @mikz):

use Test::Nginx::Socket::Lua 'no_plan';

run_tests();

__DATA__

=== TEST 1: passing test
--- config
location = /t {
  proxy_pass http://localhost:$TEST_NGINX_SERVER_PORT/upstream;
  proxy_set_header Host $http_host;
  access_by_lua_block {
    local headers = ngx.req.get_headers()

    ngx.log(ngx.STDERR, 'ngx.req.get_headers().host: ', headers.host)
    ngx.req.set_header('Host', 'foobar')
  }
}

location = /upstream {
  content_by_lua_block {
    ngx.say('Host: ', ngx.var.host)
  }
}

--- request
GET /t
--- more_headers
Host: original
--- error_code: 200
--- response_body
Host: foobar



=== TEST 2: failing test
--- config
location = /t {
  proxy_pass http://localhost:$TEST_NGINX_SERVER_PORT/upstream;
  proxy_set_header Host $http_host;
  access_by_lua_block {
    local headers = ngx.req.get_headers()

    local _ = ngx.var.http_host

    ngx.log(ngx.STDERR, 'ngx.req.get_headers().host: ', headers.host)
    ngx.req.set_header('Host', 'foobar')
  }
}

location = /upstream {
  content_by_lua_block {
    ngx.say('Host: ', ngx.var.host)
  }
}

--- request
GET /t
--- more_headers
Host: original
--- error_code: 200
--- response_body
Host: foobar

The only difference between the two is the local _ = ngx.var.http_host line in the failing test. In the failing test the subrequest receives the Host: original instead of Host: foobar.

OpenResty version:

$ openresty -V 
nginx version: openresty/1.13.6.1
built by clang 9.0.0 (clang-900.0.38)
built with OpenSSL 1.0.2l  25 May 2017 (running with OpenSSL 1.0.2o  27 Mar 2018)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/openresty/nginx --with-cc-opt='-O2 -I/usr/local/opt/openssl/include/ -I/usr/local/opt/pcre/include/' --add-module=../ngx_devel_kit-0.3.0 --add-module=../iconv-nginx-module-0.14 --add-module=../echo-nginx-module-0.61 --add-module=../xss-nginx-module-0.05 --add-module=../ngx_coolkit-0.2rc3 --add-module=../set-misc-nginx-module-0.31 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.07 --add-module=../srcache-nginx-module-0.31 --add-module=../ngx_lua-0.10.11 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.18 --add-module=../redis2-nginx-module-0.14 --add-module=../redis-nginx-module-0.3.7 --add-module=../rds-json-nginx-module-0.15 --add-module=../rds-csv-nginx-module-0.08 --add-module=../ngx_stream_lua-0.0.3 --with-ld-opt='-Wl,-rpath,/usr/local/openresty/luajit/lib -L/usr/local/opt/openssl/lib/ -L/usr/local/opt/pcre/lib/' --with-ipv6 --with-http_ssl_module --with-http_realip_module --with-http_gunzip_module --with-http_stub_status_module --with-stream --with-stream_ssl_module

Please let me know if there is any additional information I can provide.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the inline Test::Nginx::Socket::Lua reproduction and compare TEST 1 with TEST 2. Trace the ngx.var.http_host access and ngx.req.set_header entry points to determine why the later Host update is not forwarded, then make both cases report Host: foobar.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, lua
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.