Skip to content

Commit 20d4dd7

Browse files
script: support multiple header values (#3013)
Introduce `add` and `values` methods to set and get multiple header values. Signed-off-by: Alexander Yastrebov <[email protected]>
1 parent 2982fd2 commit 20d4dd7

File tree

4 files changed

+214
-57
lines changed

4 files changed

+214
-57
lines changed

docs/reference/scripts.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,32 @@ ctx.request.header["Authorization"] = nil -- delete authorization header
137137
138138
Response headers `ctx.response.header` work the same way - this is of course only valid in the `response()` phase.
139139

140+
### Multiple header values
141+
142+
Request and response header tables provide access to a first value of a header.
143+
144+
To access multiple values use `add` and `values` methods:
145+
146+
```lua
147+
function request(ctx, params)
148+
ctx.request.header.add("X-Foo", "Bar")
149+
ctx.request.header.add("X-Foo", "Baz")
150+
151+
-- all X-Foo values
152+
for _, v in pairs(ctx.request.header.values("X-Foo")) do
153+
print(v)
154+
end
155+
156+
-- all values
157+
for k, _ in ctx.request.header() do
158+
for _, v in pairs(ctx.request.header.values(k)) do
159+
print(k, "=", v)
160+
end
161+
end
162+
end
163+
```
164+
165+
140166
## Other request fields
141167

142168
* `backend_url` - (read only) returns the backend url specified in the route

script/script.go

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,10 @@ func getRequestValue(f filters.FilterContext) func(*lua.LState) int {
465465
switch key {
466466
case "header":
467467
if header == nil {
468-
header = s.CreateTable(0, 0)
468+
header = s.CreateTable(0, 2)
469+
header.RawSetString("add", s.NewFunction(addRequestHeader(f)))
470+
header.RawSetString("values", s.NewFunction(requestHeaderValues(f)))
471+
469472
mt := s.CreateTable(0, 3)
470473
mt.RawSetString("__index", s.NewFunction(getRequestHeader(f)))
471474
mt.RawSetString("__newindex", s.NewFunction(setRequestHeader(f)))
@@ -556,7 +559,10 @@ func getResponseValue(f filters.FilterContext) func(*lua.LState) int {
556559
switch key {
557560
case "header":
558561
if header == nil {
559-
header = s.CreateTable(0, 0)
562+
header = s.CreateTable(0, 2)
563+
header.RawSetString("add", s.NewFunction(addResponseHeader(f)))
564+
header.RawSetString("values", s.NewFunction(responseHeaderValues(f)))
565+
560566
mt := s.CreateTable(0, 3)
561567
mt.RawSetString("__index", s.NewFunction(getResponseHeader(f)))
562568
mt.RawSetString("__newindex", s.NewFunction(setResponseHeader(f)))
@@ -677,6 +683,30 @@ func setRequestHeader(f filters.FilterContext) func(*lua.LState) int {
677683
}
678684
}
679685

686+
func addRequestHeader(f filters.FilterContext) func(*lua.LState) int {
687+
return func(s *lua.LState) int {
688+
value := s.ToString(-1)
689+
name := s.ToString(-2)
690+
if name != "" && value != "" {
691+
f.Request().Header.Add(name, value)
692+
}
693+
return 0
694+
}
695+
}
696+
697+
func requestHeaderValues(f filters.FilterContext) func(*lua.LState) int {
698+
return func(s *lua.LState) int {
699+
name := s.ToString(-1)
700+
values := f.Request().Header.Values(name)
701+
res := s.CreateTable(len(values), 0)
702+
for _, v := range values {
703+
res.Append(lua.LString(v))
704+
}
705+
s.Push(res)
706+
return 1
707+
}
708+
}
709+
680710
func iterateRequestHeader(f filters.FilterContext) func(*lua.LState) int {
681711
// https://www.lua.org/pil/7.2.html
682712
return func(s *lua.LState) int {
@@ -755,6 +785,30 @@ func setResponseHeader(f filters.FilterContext) func(*lua.LState) int {
755785
}
756786
}
757787

788+
func addResponseHeader(f filters.FilterContext) func(*lua.LState) int {
789+
return func(s *lua.LState) int {
790+
value := s.ToString(-1)
791+
name := s.ToString(-2)
792+
if name != "" && value != "" {
793+
f.Response().Header.Add(name, value)
794+
}
795+
return 0
796+
}
797+
}
798+
799+
func responseHeaderValues(f filters.FilterContext) func(*lua.LState) int {
800+
return func(s *lua.LState) int {
801+
name := s.ToString(-1)
802+
values := f.Response().Header.Values(name)
803+
res := s.CreateTable(len(values), 0)
804+
for _, v := range values {
805+
res.Append(lua.LString(v))
806+
}
807+
s.Push(res)
808+
return 1
809+
}
810+
}
811+
758812
func iterateResponseHeader(f filters.FilterContext) func(*lua.LState) int {
759813
return func(s *lua.LState) int {
760814
s.Push(s.NewFunction(nextHeader(f.Response().Header)))

0 commit comments

Comments
 (0)