Skip to content

Commit 9653a99

Browse files
Implements lua scripting improvements
* Updates gopher-lua dependency to fix [checkptr: unsafe pointer arithmetic](yuin/gopher-lua#254) * Adds context path_param projection as table * Adds request url_query projection as table * Adds request url_raw_query getter and setter * Adds request url_path getter and setter * Adds response status_code getter and setter * Implements header and url_query iteration * Headers and url query return nil on missing key * Passes indexed script params along with key-values * Uses proper log module * Makes 'print' builtin write into log * Uses lua's RaiseError for error handling * Returns less results instead of pushing lua.LNil * Updates documentation and tests See script_test.go for usage examples. Signed-off-by: Alexander Yastrebov <[email protected]>
1 parent da2ab78 commit 9653a99

12 files changed

+837
-405
lines changed

docs/reference/scripts.md

+56-14
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ current implementation supports [Lua 5.1](https://www.lua.org/manual/5.1/).
55

66
## Route filters
77

8-
The lua scripts can be added to a route description with the lua() filter,
8+
The lua scripts can be added to a route description with the `lua()` filter,
99
the first parameter for the filter is the script. This can be either a file
1010
name (ending with `.lua`) or inline code, e.g. as
1111

1212
* file `lua("/path/to/file.lua")` - if a file path is not absolute, the path
1313
is relative to skipper's working directory.
1414
* inline `lua("function request(c, p); print(c.request.url); end")`
1515

16-
Any other additional parameters for the filter must be `key=value` strings.
17-
These will be passed as table to the called functions as second parameter.
18-
**NOTE**: Any parameter starting with "lua-" should not be used to pass
16+
Any other additional parameters for the filter will be passed as
17+
a second table parameter to the called functions.
18+
> Any parameter starting with "lua-" should not be used to pass
1919
values for the script - those will be used for configuring the filter.
2020

2121
## Script requirements
@@ -26,12 +26,24 @@ in the route as table like
2626
```lua
2727
-- route looks like
2828
--
29-
-- any: * -> lua("./test.lua", "myparam=foo", "other=bar") -> <shunt>
29+
-- any: * -> lua("./test.lua", "myparam=foo", "other=bar", "justkey") -> <shunt>
3030
--
3131
function request(ctx, params)
32-
print(ctx.request.method .. " " .. ctx.request.url .. " -> " .. params.myparam)
32+
print(params[1]) -- myparam=foo
33+
print(params[2]) -- other=bar
34+
print(params[3]) -- justkey
35+
print(params[4]) -- nil
36+
print(params.myparam) -- foo
37+
print(params.other) -- bar
38+
print(params.justkey) -- (empty string)
39+
print(params.x) -- nil
3340
end
3441
```
42+
> Parameter table allows index access as well as key-value access
43+
44+
## print builtin
45+
46+
Lua `print` builtin function writes skipper info log messages.
3547

3648
## Available lua modules
3749

@@ -60,29 +72,35 @@ in the request and accessing it in the response will most likely fail and lead
6072
to hard debuggable errors. Use the `ctx.state_bag` to propagate values from
6173
`request` to `response` - and any other filter in the chain.
6274

63-
# Request
75+
# Request and response
6476

65-
The `request()` function is run for an incoming request.
77+
The `request()` function is run for an incoming request and `response()` for backend response.
6678

6779
## Headers
6880

69-
Request headers can be accessed by accessing the `ctx.request.header` map like
81+
Request headers can be accessed via `ctx.request.header` table like
7082
```lua
7183
ua = ctx.request.header["user-agent"]
7284
```
85+
and iterated like
86+
```lua
87+
for k, v in ctx.request.header() do
88+
print(k, "=", v);
89+
end
90+
```
91+
> Headers table is a [functable](http://lua-users.org/wiki/FuncTables) that returns [iterator](https://www.lua.org/pil/7.1.html)
7392
7493
Header names are normalized by the `net/http` go module
7594
[like usual](https://godoc.org/net/http#CanonicalHeaderKey). Setting a
76-
header is done by assigning to the headers map. Setting a header to `nil` or
95+
header is done by assigning to the headers table. Setting a header to `nil` or
7796
an empty string deletes the header - setting to `nil` is preferred.
7897

7998
```lua
8099
ctx.request.header["user-agent"] = "skipper.lua/0.0.1"
81100
ctx.request.header["Authorization"] = nil -- delete authorization header
82101
```
83102

84-
Response headers work the same way by accessing / assigning to
85-
`ctx.response.header` - this is of course only valid in the `response()` phase.
103+
Response headers `ctx.response.header` work the same way - this is of course only valid in the `response()` phase.
86104

87105
## Other request fields
88106

@@ -97,6 +115,13 @@ Response headers work the same way by accessing / assigning to
97115
* `proto` - (read only) something like "HTTP/1.1"
98116
* `method` - (read only) request method, e.g. "GET" or "POST"
99117
* `url` - (read/write) request URL as string
118+
* `url_path` - (read/write) request URL path as string
119+
* `url_query` - (read/write) request URL query parameter table, similar to headers
120+
* `url_raw_query` - (read/write) encoded request URL query values, without '?' as string
121+
122+
## Other response fields
123+
124+
* `status_code` - (read/write) response status code as number, e.g. 200
100125

101126
## Serving requests from lua
102127
Requests can be served with `ctx.serve(table)`, you must return after this
@@ -109,6 +134,13 @@ call. Possible keys for the table:
109134
See also [redirect](#redirect) and [internal server error](#internal-server-error)
110135
examples below
111136

137+
## Path parameters
138+
139+
Path parameters (if any) can be read via `ctx.path_param` table
140+
```
141+
Path("/api/:id") -> lua("function request(ctx, params); print(ctx.path_param.id); end") -> <shunt>
142+
```
143+
112144
## StateBag
113145

114146
The state bag can be used to pass values from one filter to another in the same
@@ -126,8 +158,8 @@ end
126158

127159
# Examples
128160

129-
Note: the examples serve as examples. If there is a go based plugin available,
130-
use that instead. The overhead of calling lua is 4-5 times slower than pure go.
161+
>The examples serve as examples. If there is a go based plugin available,
162+
use that instead. For overhead estimate see [benchmark](#Benchmark).
131163

132164
## OAuth2 token as basic auth password
133165
```lua
@@ -200,6 +232,16 @@ function request(ctx, params)
200232
end
201233
```
202234

235+
## set request header from params
236+
```lua
237+
function request(ctx, params)
238+
ctx.request.header[params[1]] = params[2]
239+
if params[1]:lower() == "host" then
240+
ctx.request.outgoing_host = params[2]
241+
end
242+
end
243+
```
244+
203245
# Benchmark
204246

205247
## redirectTo vs lua redirect

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ require (
3939
github.com/uber/jaeger-client-go v2.16.0+incompatible
4040
github.com/uber/jaeger-lib v2.0.0+incompatible
4141
github.com/yookoala/gofast v0.4.0
42-
github.com/yuin/gopher-lua v0.0.0-20190514113301-1cd887cd7036
42+
github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e
4343
go.uber.org/atomic v1.4.0 // indirect
4444
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
4545
golang.org/x/net v0.0.0-20190628185345-da137c7871d7

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ github.com/yookoala/gofast v0.4.0 h1:dLBjghcsbbZNOEHN8N1X/gh9S6srmJed4WQfG7DlKwo
184184
github.com/yookoala/gofast v0.4.0/go.mod h1:rfbkoKaQG1bnuTUZcmV3vAlnfpF4FTq8WbQJf2vcpg8=
185185
github.com/yuin/gopher-lua v0.0.0-20190514113301-1cd887cd7036 h1:1b6PAtenNyhsmo/NKXVe34h7JEZKva1YB/ne7K7mqKM=
186186
github.com/yuin/gopher-lua v0.0.0-20190514113301-1cd887cd7036/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
187+
github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e h1:oIpIX9VKxSCFrfjsKpluGbNPBGq9iNnT9crH781j9wY=
188+
github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
187189
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
188190
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
189191
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=

script/README.md

-234
This file was deleted.

0 commit comments

Comments
 (0)