hachi029 commented on PR #13232:
URL: https://github.com/apache/apisix/pull/13232#issuecomment-4295761677

   > > Does this fix apply to HTTP/2 in cases where the second HTTP request 
starts before the first one ends, causing the two requests to share the same 
ctx.tracing?
   > 
   > 
https://github.com/apache/apisix/pull/13232/changes#diff-1b0efc84c955bbecaf03cb73a6b7c72f8cac0b1045c1d069fc01fa390d2c31daR109-R114
   > 
   > i've added the test case here to address your issue. after doing some 
digging, i found that in http2 requests, ctx.tracing won't be shared across 
different requests since each request would init a new one. hence could u 
elaborate more on your issue or if there is any reproduction steps?
   
   
   
   > > Does this fix apply to HTTP/2 in cases where the second HTTP request 
starts before the first one ends, causing the two requests to share the same 
ctx.tracing?
   > 
   > 
https://github.com/apache/apisix/pull/13232/changes#diff-1b0efc84c955bbecaf03cb73a6b7c72f8cac0b1045c1d069fc01fa390d2c31daR109-R114
   > 
   > i've added the test case here to address your issue. after doing some 
digging, i found that in http2 requests, ctx.tracing won't be shared across 
different requests since each request would init a new one. hence could u 
elaborate more on your issue or if there is any reproduction steps?
   
   We recently encountered an similar issue in our online environment involving 
ngx.ctx during the SSL phase and request processing phases. Here is an example 
to demonstrate the problem:
   nginx.conf:
   
   ```nginx
   
      ssl_certificate_by_lua_block {
           ngx.ctx.tracing={}
           ngx.log(ngx.WARN, "id: ", tostring(ngx.ctx.tracing))
       }
       log_by_lua_block {
           ngx.log(ngx.WARN, "data: ", table.concat(ngx.ctx.tracing, ", "), ", 
id:", tostring(ngx.ctx.tracing))
           ngx.ctx.tracing=nil
           ngx.log(ngx.WARN, "nil?(after set to nil): ", ngx.ctx.tracing==nil)
           ngx.log(ngx.WARN, "data(after set to nil): ", 
table.concat(ngx.ctx.tracing, ", "))
       }
       location /slow {
           content_by_lua_block {
               ngx.log(ngx.WARN, "id(slow): ", tostring(ngx.ctx.tracing))
               table.insert(ngx.ctx.tracing, "slow_1")    
               ngx.sleep(1)
               table.insert(ngx.ctx.tracing, "slow_2")    
               ngx.say("slow")
           }
       }
       location /fast {
           content_by_lua_block {
               ngx.log(ngx.WARN, "id(fast): ", tostring(ngx.ctx.tracing))
               table.insert(ngx.ctx.tracing, "fast_1")    
               ngx.say("fast")
           }
       }
   
   ```
   Run the command bellow to process two requests concurrently within the same 
connection:
   ```
   curl -Z -k https://127.0.0.1:8443/slow  https://127.0.0.1:8443/fast
   ```
   Error Log Output:(Prefix timestamps and metadata removed)
   ```
   ssl_certificate_by_lua(nginx.conf:119):3: id: table: 0x7ff77b5a1060, 
context: ssl_certificate_by_lua*, client: 127.0.0.1, server: 0.0.0.0:8443
   content_by_lua(nginx.conf:131):2: id(slow): table: 0x7ff77b5a1060, client: 
127.0.0.1, server: localhost, request: "GET /slow HTTP/2.0", host: 
"127.0.0.1:8443"
   content_by_lua(nginx.conf:141):2: id(fast): table: 0x7ff77b5a1060, client: 
127.0.0.1, server: localhost, request: "GET /fast HTTP/2.0", host: 
"127.0.0.1:8443"
   log_by_lua(nginx.conf:123):2: data: slow_1, fast_1, id:table: 0x7ff77b5a1060 
while logging request, client: 127.0.0.1, server: localhost, request: "GET 
/fast HTTP/2.0", host: "127.0.0.1:8443"
   log_by_lua(nginx.conf:123):4: nil?(after set to nil): false while logging 
request, client: 127.0.0.1, server: localhost, request: "GET /fast HTTP/2.0", 
host: "127.0.0.1:8443"
   log_by_lua(nginx.conf:123):5: data(after set to nil): slow_1, fast_1 while 
logging request, client: 127.0.0.1, server: localhost, request: "GET /fast 
HTTP/2.0", host: "127.0.0.1:8443"
   log_by_lua(nginx.conf:123):2: data: slow_1, fast_1, slow_2, id:table: 
0x7ff77b5a1060 while logging request, client: 127.0.0.1, server: localhost, 
request: "GET /slow HTTP/2.0", host: "127.0.0.1:8443"
   log_by_lua(nginx.conf:123):4: nil?(after set to nil): false while logging 
request, client: 127.0.0.1, server: localhost, request: "GET /slow HTTP/2.0", 
host: "127.0.0.1:8443"
   log_by_lua(nginx.conf:123):5: data(after set to nil): slow_1, fast_1, slow_2 
while logging request, client: 127.0.0.1, server: localhost, request: "GET 
/slow HTTP/2.0", host: "127.0.0.1:8443"
   ```
   
   Key Observations from the Logs:
   
   - ngx.ctx.tracing is shared across different requests on the same 
connection, leading to data interference between requests.
   - Setting ngx.ctx.tracing = nil does not achieve the expected result; the 
value persists.
   
   Based on the implementation relate to ngx.ctx 
[get_ctx_table](https://github.com/openresty/lua-resty-core/blob/master/lib/resty/core/ctx.lua#L67),
 the ngx.ctx accessed during the SSL phase acts as the metatable for the 
ngx.ctx accessed during the request processing phase.
   
   In the example above:
   
   - The value retrieved from ngx.ctx.tracing is always the one initialized 
during the SSL phase.
   -  Setting ngx.ctx.tracing to nil in the request phase does nothing because 
the request-level ngx.ctx table does not actually contain the tracing key 
itself. When access it again, Lua continues to look up the key along the 
metatable and finding the value stored in the SSL-phase ngx.ctx.
   
   In this specific issue, the PR fixes the crash, the tracing data still 
interference across concurrent requests.
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to