Skip to content

Commit 5812f2b

Browse files
authored
feat: support assemblyscript SDK (#19)
1 parent f1e9bf5 commit 5812f2b

22 files changed

+287
-41
lines changed

.github/workflows/test.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ jobs:
1616
- name: Check out code
1717
uses: actions/checkout@v2
1818

19+
- name: Set up Node.js
20+
uses: actions/setup-node@v1
21+
with:
22+
node-version: 10.0.0
23+
1924
- name: Get dependencies
2025
run: |
2126
sudo apt install -y cpanminus build-essential libncurses5-dev libreadline-dev libssl-dev perl luarocks

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ wasmtime-*-c-api
44
wasmtime-*-c-api.tar.xz
55
wasmtime-c-api
66
*.wasm
7+
*.wasm.map
8+
*.wat
79

810
t/servroot
11+
node_modules/

Makefile

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ install:
66
$(INSTALL) -m 664 lib/resty/*.lua $(OPENRESTY_PREFIX)/lualib/resty/
77
cp -r ./wasmtime-c-api $(OPENRESTY_PREFIX)/
88

9-
.PHONY: build.testdata
10-
build.testdata:
11-
@find ./t/testdata -type f -name "main.go" | grep ${name} | xargs -Ip tinygo build -o p.wasm -scheduler=none -target=wasi p
12-
139
.PHONY: build.all.testdata
1410
build.all.testdata:
1511
@find ./t/testdata -type f -name "main.go" | xargs -Ip tinygo build -o p.wasm -scheduler=none -target=wasi p
12+
@cd ./t/testdata/assemblyscript && npm install && npm run asbuild

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ not set, the WASM VM won't be enabled.
3636

3737
### load
3838

39-
`syntax: plugin, err = proxy_wasm.load(path)`
39+
`syntax: plugin, err = proxy_wasm.load(name, path)`
4040

4141
Load a `.wasm` file from the filesystem and return a WASM plugin.
4242

4343
```lua
44-
local plugin, err = proxy_wasm.load("t/testdata/plugin_lifecycle/main.go.wasm")
44+
local plugin, err = proxy_wasm.load("plugin","t/testdata/plugin_lifecycle/main.go.wasm")
4545
```
4646

4747
### on_configure
@@ -51,7 +51,7 @@ local plugin, err = proxy_wasm.load("t/testdata/plugin_lifecycle/main.go.wasm")
5151
Create a plugin ctx with the given plugin and conf.
5252

5353
```lua
54-
local plugin, err = proxy_wasm.load("t/testdata/plugin_lifecycle/main.go.wasm")
54+
local plugin, err = proxy_wasm.load("plugin","t/testdata/plugin_lifecycle/main.go.wasm")
5555
if not plugin then
5656
ngx.log(ngx.ERR, "failed to load wasm ", err)
5757
return
@@ -70,7 +70,7 @@ end
7070
Run the HTTP request headers filter in the plugin of the given plugin ctx.
7171

7272
```lua
73-
local plugin, err = proxy_wasm.load("t/testdata/plugin_lifecycle/main.go.wasm")
73+
local plugin, err = proxy_wasm.load("plugin","t/testdata/plugin_lifecycle/main.go.wasm")
7474
if not plugin then
7575
ngx.log(ngx.ERR, "failed to load wasm ", err)
7676
return

lib/resty/proxy-wasm.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ typedef struct {
1616
u_char *data;
1717
} ngx_str_t;
1818
typedef long ngx_int_t;
19-
void *ngx_http_wasm_load_plugin(const char *code, size_t size);
19+
void *ngx_http_wasm_load_plugin(const char *name, size_t name_len, const char *code, size_t size);
2020
void ngx_http_wasm_unload_plugin(void *plugin);
2121
void *ngx_http_wasm_on_configure(void *plugin, const char *conf, size_t size);
2222
void ngx_http_wasm_delete_plugin_ctx(void *hwp_ctx);
@@ -30,7 +30,7 @@ local _M = {}
3030
local HTTP_REQUEST_HEADERS = 1
3131

3232

33-
function _M.load(path)
33+
function _M.load(name, path)
3434
local f, err = io.open(path)
3535
if not f then
3636
return nil, err
@@ -42,7 +42,7 @@ function _M.load(path)
4242
return nil, err
4343
end
4444

45-
local plugin = C.ngx_http_wasm_load_plugin(data, #data)
45+
local plugin = C.ngx_http_wasm_load_plugin(name, #name, data, #data)
4646
if plugin == nil then
4747
return nil, "failed to load wasm plugin"
4848
end

src/http/ngx_http_wasm_api.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,32 @@ ngx_http_wasm_copy_to_wasm(ngx_log_t *log, const u_char *data, int32_t len,
7979
}
8080

8181

82+
int32_t
83+
proxy_get_property(int32_t path_data, int32_t path_size,
84+
int32_t res_data, int32_t res_size)
85+
{
86+
ngx_log_t *log;
87+
const u_char *p;
88+
89+
log = ngx_http_wasm_get_log();
90+
91+
p = ngx_wasm_vm.get_memory(log, path_data, path_size);
92+
if (p == NULL) {
93+
return PROXY_RESULT_INVALID_MEMORY_ACCESS;
94+
}
95+
96+
if (ngx_strncmp(p, "plugin_root_id", sizeof("plugin_root_id") - 1) == 0) {
97+
ngx_str_t *name;
98+
99+
name = ngx_http_wasm_get_plugin_name();
100+
return ngx_http_wasm_copy_to_wasm(log, name->data, name->len,
101+
res_data, res_size);
102+
}
103+
104+
return PROXY_RESULT_OK;
105+
}
106+
107+
82108
int32_t
83109
proxy_log(int32_t log_level, int32_t addr, int32_t size)
84110
{

src/http/ngx_http_wasm_api.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@
4343
int32_t p3 = args[2].of.i32; \
4444
int32_t res = NAME(p1, p2, p3);
4545

46+
#define DEFINE_WASM_API_ARG_I32_I32_I32_I32 \
47+
int32_t, int32_t, int32_t, int32_t
48+
49+
#define DEFINE_WASM_API_ARG_CHECK_I32_I32_I32_I32(NAME) \
50+
int32_t p1 = args[0].of.i32; \
51+
int32_t p2 = args[1].of.i32; \
52+
int32_t p3 = args[2].of.i32; \
53+
int32_t p4 = args[3].of.i32; \
54+
int32_t res = NAME(p1, p2, p3, p4);
55+
4656
#define DEFINE_WASM_API_ARG_I32_I32_I32_I32_I32 \
4757
int32_t, int32_t, int32_t, int32_t, int32_t
4858

@@ -78,6 +88,8 @@
7888
1, {WASM_I32}
7989
#define DEFINE_WASM_NAME_ARG_I32_I32_I32 \
8090
3, {WASM_I32, WASM_I32, WASM_I32}
91+
#define DEFINE_WASM_NAME_ARG_I32_I32_I32_I32 \
92+
4, {WASM_I32, WASM_I32, WASM_I32, WASM_I32}
8193
#define DEFINE_WASM_NAME_ARG_I32_I32_I32_I32_I32 \
8294
5, {WASM_I32, WASM_I32, WASM_I32, WASM_I32, WASM_I32}
8395
#define DEFINE_WASM_NAME_ARG_I32_I32_I32_I32_I32_I32_I32_I32 \
@@ -98,6 +110,9 @@ DEFINE_WASM_API(proxy_set_effective_context,
98110
DEFINE_WASM_API(proxy_log,
99111
DEFINE_WASM_API_ARG_I32_I32_I32,
100112
DEFINE_WASM_API_ARG_CHECK_I32_I32_I32(proxy_log))
113+
DEFINE_WASM_API(proxy_get_property,
114+
DEFINE_WASM_API_ARG_I32_I32_I32_I32,
115+
DEFINE_WASM_API_ARG_CHECK_I32_I32_I32_I32(proxy_get_property))
101116
DEFINE_WASM_API(proxy_get_buffer_bytes,
102117
DEFINE_WASM_API_ARG_I32_I32_I32_I32_I32,
103118
DEFINE_WASM_API_ARG_CHECK_I32_I32_I32_I32_I32(proxy_get_buffer_bytes))
@@ -110,6 +125,7 @@ DEFINE_WASM_API(proxy_send_http_response,
110125
static ngx_wasm_host_api_t host_apis[] = {
111126
DEFINE_WASM_NAME(proxy_set_effective_context, DEFINE_WASM_NAME_ARG_I32)
112127
DEFINE_WASM_NAME(proxy_log, DEFINE_WASM_NAME_ARG_I32_I32_I32)
128+
DEFINE_WASM_NAME(proxy_get_property, DEFINE_WASM_NAME_ARG_I32_I32_I32_I32)
113129
DEFINE_WASM_NAME(proxy_get_buffer_bytes, DEFINE_WASM_NAME_ARG_I32_I32_I32_I32_I32)
114130
DEFINE_WASM_NAME_ALIAS(proxy_send_http_response,
115131
DEFINE_WASM_NAME_ARG_I32_I32_I32_I32_I32_I32_I32_I32,

src/http/ngx_http_wasm_ctx.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77

88

99
typedef struct {
10-
void *plugin;
11-
uint32_t cur_ctx_id;
12-
ngx_queue_t occupied;
13-
ngx_queue_t free;
14-
unsigned done:1;
10+
void *plugin;
11+
uint32_t cur_ctx_id;
12+
ngx_str_t name;
13+
ngx_http_wasm_state_t *state;
14+
ngx_queue_t occupied;
15+
ngx_queue_t free;
16+
unsigned done:1;
1517
} ngx_http_wasm_plugin_t;
1618

1719

src/http/ngx_http_wasm_module.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ ngx_http_wasm_init(ngx_conf_t *cf)
162162

163163

164164
void *
165-
ngx_http_wasm_load_plugin(const char *bytecode, size_t size)
165+
ngx_http_wasm_load_plugin(const char *name, size_t name_len,
166+
const char *bytecode, size_t size)
166167
{
167168
void *plugin;
168169
ngx_int_t rc;
@@ -185,13 +186,22 @@ ngx_http_wasm_load_plugin(const char *bytecode, size_t size)
185186
goto free_plugin;
186187
}
187188

188-
hw_plugin = ngx_calloc(sizeof(ngx_http_wasm_plugin_t), ngx_cycle->log);
189+
hw_plugin = ngx_calloc(sizeof(ngx_http_wasm_plugin_t) + name_len +
190+
sizeof(ngx_http_wasm_state_t), ngx_cycle->log);
189191
if (hw_plugin == NULL) {
190192
goto free_plugin;
191193
}
192194

193195
hw_plugin->cur_ctx_id = 0;
194196
hw_plugin->plugin = plugin;
197+
198+
hw_plugin->name.len = name_len;
199+
hw_plugin->name.data = (u_char *) (hw_plugin + 1);
200+
ngx_memcpy(hw_plugin->name.data, name, name_len);
201+
202+
hw_plugin->state = (ngx_http_wasm_state_t *) (hw_plugin->name.data + name_len + 1);
203+
hw_plugin->state->plugin_name = &hw_plugin->name;
204+
195205
ngx_queue_init(&hw_plugin->occupied);
196206
ngx_queue_init(&hw_plugin->free);
197207
return hw_plugin;
@@ -327,6 +337,8 @@ ngx_http_wasm_on_configure(ngx_http_wasm_plugin_t *hw_plugin, const char *conf,
327337
ngx_queue_init(&hwp_ctx->free);
328338
}
329339

340+
ngx_http_wasm_set_state(hw_plugin->state);
341+
330342
rc = ngx_wasm_vm.call(plugin, &proxy_on_context_create, false,
331343
NGX_WASM_PARAM_I32_I32, ctx_id, 0);
332344
if (rc != NGX_OK) {
@@ -349,6 +361,7 @@ ngx_http_wasm_on_configure(ngx_http_wasm_plugin_t *hw_plugin, const char *conf,
349361
goto free_hwp_ctx;
350362
}
351363
hwp_ctx->state->r = NULL;
364+
hwp_ctx->state->plugin_name = &hwp_ctx->hw_plugin->name;
352365

353366
state_conf = (u_char *) (hwp_ctx->state + 1);
354367
/* copy conf so we can access it anytime */

src/http/ngx_http_wasm_state.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,14 @@ ngx_http_wasm_get_log(void)
4242

4343
return ngx_cycle->log;
4444
}
45+
46+
47+
ngx_str_t *
48+
ngx_http_wasm_get_plugin_name(void)
49+
{
50+
if (cur_state == NULL) {
51+
return NULL;
52+
}
53+
54+
return cur_state->plugin_name;
55+
}

src/http/ngx_http_wasm_state.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@
77

88

99
typedef struct {
10-
ngx_str_t conf;
11-
ngx_http_request_t *r;
10+
ngx_str_t conf;
11+
ngx_http_request_t *r;
12+
ngx_str_t *plugin_name;
1213
} ngx_http_wasm_state_t;
1314

1415

1516
void ngx_http_wasm_set_state(ngx_http_wasm_state_t *state);
1617
const ngx_str_t *ngx_http_wasm_get_conf(void);
1718
ngx_http_request_t *ngx_http_wasm_get_req(void);
1819
ngx_log_t *ngx_http_wasm_get_log(void);
20+
ngx_str_t *ngx_http_wasm_get_plugin_name(void);
1921

2022

2123
#endif // NGX_HTTP_WASM_STATE_H

src/vm/wasmtime.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,13 @@ ngx_wasm_wasmtime_load(const char *bytecode, size_t size)
152152
error = wasmtime_linker_instantiate(linker, context, module, &plugin->instance, &trap);
153153
if (error != NULL) {
154154
ngx_wasm_wasmtime_report_error(ngx_cycle->log, "failed to new instance: ", error, NULL);
155-
goto free_linker;
155+
goto free_plugin;
156156
}
157157

158158
ok = wasmtime_instance_export_get(context, &plugin->instance, "memory", strlen("memory"), &item);
159159
if (!ok || item.kind != WASMTIME_EXTERN_MEMORY) {
160160
ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "the wasm plugin doesn't export memory");
161-
goto free_linker;
161+
goto free_plugin;
162162
}
163163
plugin->memory = item.of.memory;
164164

@@ -172,6 +172,9 @@ ngx_wasm_wasmtime_load(const char *bytecode, size_t size)
172172

173173
return plugin;
174174

175+
free_plugin:
176+
ngx_free(plugin);
177+
175178
free_linker:
176179
wasmtime_linker_delete(linker);
177180

@@ -313,7 +316,8 @@ ngx_wasm_wasmtime_malloc(ngx_log_t *log, int32_t size)
313316
bool found;
314317

315318
found = wasmtime_instance_export_get(cur_plugin->context, &cur_plugin->instance,
316-
"proxy_on_memory_allocate", 24, &func);
319+
"malloc", 6, &func);
320+
//"proxy_on_memory_allocate", 24, &func);
317321
if (!found) {
318322
found = wasmtime_instance_export_get(cur_plugin->context, &cur_plugin->instance,
319323
"malloc", 6, &func);

t/assemblyscript.t

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use t::WASM 'no_plan';
2+
3+
run_tests();
4+
5+
__DATA__
6+
7+
=== TEST 1: fault injection
8+
--- config
9+
location /t {
10+
content_by_lua_block {
11+
local wasm = require("resty.proxy-wasm")
12+
local plugin = assert(wasm.load("FaultInjection",
13+
"t/testdata/assemblyscript/build/untouched.wasm"))
14+
local ctx = assert(wasm.on_configure(plugin, 'body'))
15+
assert(wasm.on_http_request_headers(ctx))
16+
}
17+
}
18+
--- error_code: 403
19+
--- response_body chomp
20+
body

t/http_lifecycle.t

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ __DATA__
99
location /t {
1010
content_by_lua_block {
1111
local wasm = require("resty.proxy-wasm")
12-
local plugin = assert(wasm.load("t/testdata/http_lifecycle/main.go.wasm"))
12+
local plugin = assert(wasm.load("plugin", "t/testdata/http_lifecycle/main.go.wasm"))
1313
local ctx = assert(wasm.on_configure(plugin, '{"body":512}'))
1414
assert(wasm.on_http_request_headers(ctx))
1515
assert(wasm.on_http_request_headers(ctx))
@@ -28,7 +28,7 @@ free http context 2
2828
location /t {
2929
content_by_lua_block {
3030
local wasm = require("resty.proxy-wasm")
31-
local plugin = assert(wasm.load("t/testdata/http_lifecycle/main.go.wasm"))
31+
local plugin = assert(wasm.load("plugin", "t/testdata/http_lifecycle/main.go.wasm"))
3232
do
3333
local ctx = assert(wasm.on_configure(plugin, '{"body":512}'))
3434
assert(wasm.on_http_request_headers(ctx))
@@ -48,7 +48,7 @@ free plugin context 1
4848
--- http_config
4949
init_by_lua_block {
5050
local wasm = require("resty.proxy-wasm")
51-
local plugin = assert(wasm.load("t/testdata/http_lifecycle/main.go.wasm"))
51+
local plugin = assert(wasm.load("plugin", "t/testdata/http_lifecycle/main.go.wasm"))
5252
package.loaded.ctx = assert(wasm.on_configure(plugin, '{"body":512}'))
5353
}
5454
--- config
@@ -97,7 +97,7 @@ qr/free http context (1|11)$/
9797
location /t {
9898
content_by_lua_block {
9999
local wasm = require("resty.proxy-wasm")
100-
local plugin = assert(wasm.load("t/testdata/http_lifecycle/main.go.wasm"))
100+
local plugin = assert(wasm.load("plugin", "t/testdata/http_lifecycle/main.go.wasm"))
101101
local ctx1 = assert(wasm.on_configure(plugin, '{"body":512}'))
102102
local ctx2 = assert(wasm.on_configure(plugin, '{"body":256}'))
103103
assert(wasm.on_http_request_headers(ctx1))
@@ -117,8 +117,8 @@ run http ctx 4 with conf {"body":256},
117117
location /t {
118118
content_by_lua_block {
119119
local wasm = require("resty.proxy-wasm")
120-
local plugin1 = assert(wasm.load("t/testdata/http_lifecycle/main.go.wasm"))
121-
local plugin2 = assert(wasm.load("t/testdata/http_lifecycle/main.go.wasm"))
120+
local plugin1 = assert(wasm.load("plugin", "t/testdata/http_lifecycle/main.go.wasm"))
121+
local plugin2 = assert(wasm.load("plugin", "t/testdata/http_lifecycle/main.go.wasm"))
122122
local ctx1 = assert(wasm.on_configure(plugin1, '{"body":512}'))
123123
local ctx2 = assert(wasm.on_configure(plugin2, '{"body":256}'))
124124
assert(wasm.on_http_request_headers(ctx1))

t/http_send_response.t

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ __DATA__
99
location /t {
1010
content_by_lua_block {
1111
local wasm = require("resty.proxy-wasm")
12-
local plugin = assert(wasm.load("t/testdata/http_send_response/main.go.wasm"))
12+
local plugin = assert(wasm.load("plugin", "t/testdata/http_send_response/main.go.wasm"))
1313
local ctx = assert(wasm.on_configure(plugin, '403_body'))
1414
assert(wasm.on_http_request_headers(ctx))
1515
}
@@ -25,7 +25,7 @@ should not pass
2525
location /t {
2626
content_by_lua_block {
2727
local wasm = require("resty.proxy-wasm")
28-
local plugin = assert(wasm.load("t/testdata/http_send_response/main.go.wasm"))
28+
local plugin = assert(wasm.load("plugin", "t/testdata/http_send_response/main.go.wasm"))
2929
local ctx = assert(wasm.on_configure(plugin, '502'))
3030
assert(wasm.on_http_request_headers(ctx))
3131
}

0 commit comments

Comments
 (0)