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]