mikyll opened a new issue, #12121:
URL: https://github.com/apache/apisix/issues/12121

   ### Current Behavior
   
   When calling `core.utils.resolve_var()` in header_filter phase (after 
access), it appears that `$status` variable is set to 0, if it was already 
resolved by a previous plugin, such as `proxy-rewrite`.
   
   Why does this happen? Is this a bug?
   
   ### Expected Behavior
   
   I'd expect to be able to resolve `$status` variable N times, with always the 
same result.
   
   ### Error Logs
   
   _No response_
   
   ### Steps to Reproduce
   
   ## Minimal Reproducible Example (APISIX Standalone)
   
   ### Files
   
   Consider the following setup:
   
   - file `compose.yaml`:
     
     ```yaml
     services:
       apisix:
         container_name: apisix-standalone
         image: apache/apisix:3.12.0-debian
         restart: no
         stdin_open: true
         tty: true
         volumes:
           - ./conf/config.yaml:/usr/local/apisix/conf/config.yaml
           - ./conf/apisix.yaml:/usr/local/apisix/conf/apisix.yaml
         ports:
           - "9080:9080/tcp"
           - "9443:9443/tcp"
         networks:
           apisix:
     
       httpbin:
         container_name: httpbin-standalone
         image: kennethreitz/httpbin:latest
         restart: no
         ports:
           - "3000:80/tcp"
         networks:
           apisix:
     
     networks:
       apisix:
         driver: bridge
     ```
   
   - file `conf/config.yaml`:
   
     ```yaml
     deployment:
       role: data_plane
       role_data_plane:
         config_provider: yaml
     
     #END
     ```
   
   - file `conf/apisix.yaml`:
   
     ```yaml
     upstreams:
       - id: httpbin_internal
         nodes:
           "httpbin-standalone:80": 1
         type: roundrobin
   
     routes:
       # Simple base route
       - id: base_internal
         uri: /anything
         upstream_id: httpbin_internal
     
       # Test 1: proxy-rewrite does NOT set "header: $status" -> does NOT call 
resolve_var("$status", ctx.var)
       - id: test1
         uri: /test1
         upstream_id: httpbin_internal
         plugins:
           proxy-rewrite:
             uri: /status/200
           serverless-pre-function:
             phase: header_filter
             functions:
               - |
                 return function(conf, ctx)
                   local core = require("apisix.core")
                   local status, err, n_resolved = 
core.utils.resolve_var("$status", ctx.var)
                   local hostname, err, n_resolved = 
core.utils.resolve_var("$hostname", ctx.var)
                   core.log.warn("status: " .. tostring(status) .. ", hostname: 
" .. tostring(hostname))
                   ngx.header["status"] = status
                   ngx.header["hostname"] = hostname
                 end
     
       # Test 2: proxy-rewrite DOES set "header: $status" -> DOES call 
resolve_var("$status", ctx.var)
       - id: test2
         uri: /test2
         upstream_id: httpbin_internal
         plugins:
           proxy-rewrite:
             uri: /status/200
             headers:
               set:
                 status: $status  # <- this
           serverless-pre-function:
             phase: header_filter
             functions:
               - |
                 return function(conf, ctx)
                   local core = require("apisix.core")
                   local status, err, n_resolved = 
core.utils.resolve_var("$status", ctx.var)
                   local hostname, err, n_resolved = 
core.utils.resolve_var("$hostname", ctx.var)
                   core.log.warn("status: " .. tostring(status) .. ", hostname: 
" .. tostring(hostname))
                   ngx.header["status"] = status
                   ngx.header["hostname"] = hostname
                 end
       # Test 3: proxy-rewrite DOES set both headers "status: $status" and 
"hostname: $hostname"-> DOES call resolve_var("$status", ctx.var) and 
resolve_var("$hostname", ctx.var)
       - id: test3
         uri: /test3
         upstream_id: httpbin_internal
         plugins:
           proxy-rewrite:
             uri: /status/200
             headers:
               set:
                 status: $status      # <- this
                 hostname: $hostname  # <- this
           serverless-pre-function:
             phase: header_filter
             functions:
               - |
                 return function(conf, ctx)
                   local core = require("apisix.core")
                   local status, err, n_resolved = 
core.utils.resolve_var("$status", ctx.var)
                   local hostname, err, n_resolved = 
core.utils.resolve_var("$hostname", ctx.var)
                   core.log.warn("status: " .. tostring(status) .. ", hostname: 
" .. tostring(hostname))
                   ngx.header["status"] = status
                   ngx.header["hostname"] = hostname
                 end
     ```
   
   ### Run Docker Containers
   
   Run with:
   
   ```bash
   docker compose up
   ```
   
   ### Testing Requests
   
   #### Test 1
   
   Test requests with curl:
   
   ```bash
   curl -s -i localhost:9080/test1
   HTTP/1.1 200 OK
   ...
   status: 200
   hostname: 0be5febe953a
   ```
   
   `$status` has the correct value.
   
   #### Test 2
   
   ```bash
   curl -s -i localhost:9080/test2
   HTTP/1.1 200 OK
   ...
   status: 0
   hostname: 0be5febe953a
   ```
   
   `$status` is set to 0.
   
   #### Test 3
   
   ```bash
   curl -s -i localhost:9080/test3
   HTTP/1.1 200 OK
   ...
   status: 0
   hostname: 0be5febe953a
   ```
   
   `$status` is set to 0, but `$hostname` is the same.
   
   #### Result
   
   As we can notice, in both `/test2` and `/test3`, variable `$status` doesn't 
get resolved correctly.
   
   ### Environment
   
   - APISIX version (run `apisix version`): 3.12.0
   


-- 
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