Skip to content

Commit f3c6bf9

Browse files
nilslicezshipko
andauthored
feat: implement extism_http_request (#7)
* chore: bring extism pdk header up to date * feat: partial working http_request * ci: add test for http example which should eventually pass * feat: use memory in HTTPResponse * chore: update method name, add comments to example * ci: try to download modules before compiling * ci: download mods from example directory * fix: add fastjson dep to go.mod Co-authored-by: zach <zachshipko@gmail.com>
1 parent c36923b commit f3c6bf9

File tree

11 files changed

+153
-24
lines changed

11 files changed

+153
-24
lines changed

.github/workflows/ci.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ jobs:
5656
5757
- name: Compile example
5858
run: |
59+
pushd example
60+
go mod download
61+
popd
62+
5963
make -B example
6064
6165
- name: Test example
@@ -66,3 +70,5 @@ jobs:
6670
echo $TEST | grep '"count": 4'
6771
echo $TEST | grep '"config": "1"'
6872
echo $TEST | grep '"a": "this is var a"'
73+
74+
extism call example/http.wasm --wasi http_get | grep '"userId": 1'

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
.PHONY: example
22
example:
33
tinygo build -o example/example.wasm -target wasi example/main.go
4+
tinygo build -o example/http.wasm -target wasi example/http.go
45

56
test:
6-
extism call example/example.wasm count_vowels --wasi --input "this is a test" --set-config '{"thing": "1234"}'
7+
extism call example/example.wasm count_vowels --wasi --input "this is a test" --set-config '{"thing": "1234"}'
8+
@echo ""
9+
extism call example/http.wasm http_get --wasi --log-level info

example/example.wasm

62.8 KB
Binary file not shown.

example/go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ module github.com/extism/go-pdk/example
33
go 1.19
44

55
require github.com/extism/go-pdk v0.0.0-20220910220145-f385a5f19d1d
6+
7+
require github.com/valyala/fastjson v1.6.3 // indirect
8+
9+
replace github.com/extism/go-pdk => ../

example/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
github.com/extism/go-pdk v0.0.0-20220910220145-f385a5f19d1d h1:nwr+atxLObICflh2BGTC7SKqln218aa+zKg9Yn9JMSM=
2-
github.com/extism/go-pdk v0.0.0-20220910220145-f385a5f19d1d/go.mod h1:rfOf4Z9uXtA4W3SYoPN34poctHYSo6ScSqcKoAswHjM=
1+
github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc=
2+
github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=

example/http.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package main
2+
3+
import (
4+
"github.com/extism/go-pdk"
5+
)
6+
7+
//export http_get
8+
func http_get() int32 {
9+
// create an HTTP Request (withuot relying on WASI), set headers as needed
10+
req := pdk.NewHTTPRequest("GET", "https://jsonplaceholder.typicode.com/todos/1")
11+
req.SetHeader("some-name", "some-value")
12+
req.SetHeader("another", "again")
13+
// send the request, get response back (can check status on response via res.Status())
14+
res := req.Send()
15+
16+
// zero-copy output to host
17+
pdk.OutputMemory(res.Memory())
18+
19+
return 0
20+
}
21+
22+
func main() {}

example/http.wasm

375 KB
Binary file not shown.

extism-pdk.h

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,62 @@
44

55
#define IMPORT(a, b) __attribute__((import_module(a), import_name(b)))
66

7+
typedef uint64_t ExtismPointer;
8+
79
IMPORT("env", "extism_input_length") extern uint64_t extism_input_length();
8-
IMPORT("env", "extism_length") extern uint64_t extism_length(uint64_t);
9-
IMPORT("env", "extism_alloc") extern uint64_t extism_alloc(uint64_t);
10-
IMPORT("env", "extism_free") extern void extism_free(uint64_t);
10+
IMPORT("env", "extism_length") extern uint64_t extism_length(ExtismPointer);
11+
IMPORT("env", "extism_alloc") extern ExtismPointer extism_alloc(uint64_t);
12+
IMPORT("env", "extism_free") extern void extism_free(ExtismPointer);
1113

1214
IMPORT("env", "extism_input_load_u8")
13-
extern uint8_t extism_input_load_u8(uint64_t);
15+
extern uint8_t extism_input_load_u8(ExtismPointer);
1416

1517
IMPORT("env", "extism_input_load_u64")
16-
extern uint64_t extism_input_load_u64(uint64_t);
18+
extern uint64_t extism_input_load_u64(ExtismPointer);
1719

1820
IMPORT("env", "extism_output_set")
19-
extern void extism_output_set(uint64_t, uint64_t);
21+
extern void extism_output_set(ExtismPointer, uint64_t);
2022

2123
IMPORT("env", "extism_error_set")
22-
extern void extism_error_set(uint64_t);
24+
extern void extism_error_set(ExtismPointer);
2325

2426
IMPORT("env", "extism_config_get")
25-
extern uint64_t extism_config_get(uint64_t);
27+
extern ExtismPointer extism_config_get(ExtismPointer);
2628

2729
IMPORT("env", "extism_var_get")
28-
extern uint64_t extism_var_get(uint64_t);
30+
extern ExtismPointer extism_var_get(ExtismPointer);
2931

3032
IMPORT("env", "extism_var_set")
31-
extern void extism_var_set(uint64_t, uint64_t);
33+
extern void extism_var_set(ExtismPointer, ExtismPointer);
3234

3335
IMPORT("env", "extism_store_u8")
34-
extern void extism_store_u8(uint64_t, uint8_t);
36+
extern void extism_store_u8(ExtismPointer, uint8_t);
3537

3638
IMPORT("env", "extism_load_u8")
37-
extern uint8_t extism_load_u8(uint64_t);
39+
extern uint8_t extism_load_u8(ExtismPointer);
3840

3941
IMPORT("env", "extism_store_u64")
40-
extern void extism_store_u64(uint64_t, uint64_t);
42+
extern void extism_store_u64(ExtismPointer, uint64_t);
4143

4244
IMPORT("env", "extism_load_u64")
43-
extern uint64_t extism_load_u64(uint64_t);
45+
extern uint64_t extism_load_u64(ExtismPointer);
4446

4547
IMPORT("env", "extism_http_request")
46-
extern uint64_t extism_http_request(uint64_t, uint64_t);
48+
extern ExtismPointer extism_http_request(ExtismPointer, ExtismPointer);
49+
50+
IMPORT("env", "extism_http_status_code")
51+
extern int32_t extism_http_status_code();
4752

4853
IMPORT("env", "extism_log_info")
49-
extern void extism_log_info(uint64_t);
54+
extern void extism_log_info(ExtismPointer);
5055
IMPORT("env", "extism_log_debug")
51-
extern void extism_log_debug(uint64_t);
56+
extern void extism_log_debug(ExtismPointer);
5257
IMPORT("env", "extism_log_warn")
53-
extern void extism_log_warn(uint64_t);
58+
extern void extism_log_warn(ExtismPointer);
5459
IMPORT("env", "extism_log_error")
55-
extern void extism_log_error(uint64_t);
60+
extern void extism_log_error(ExtismPointer);
5661

57-
static void extism_load(uint64_t offs, uint8_t *buffer, uint64_t length) {
62+
static void extism_load(ExtismPointer offs, uint8_t *buffer, uint64_t length) {
5863
uint64_t n;
5964
uint64_t left = 0;
6065

@@ -88,7 +93,7 @@ static void extism_load_input(uint8_t *buffer, uint64_t length) {
8893
}
8994
}
9095

91-
static void extism_store(uint64_t offs, const uint8_t *buffer,
96+
static void extism_store(ExtismPointer offs, const uint8_t *buffer,
9297
uint64_t length) {
9398
uint64_t n;
9499
uint64_t left = 0;

extism_pdk.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package pdk
22

33
import (
44
"encoding/binary"
5+
"strings"
6+
7+
"github.com/valyala/fastjson"
58
)
69

710
/*
@@ -116,6 +119,10 @@ func Output(data []byte) {
116119
C.extism_output_set(offset, clength)
117120
}
118121

122+
func OutputString(s string) {
123+
Output([]byte(s))
124+
}
125+
119126
func GetConfig(key string) (string, bool) {
120127
mem := AllocateBytes([]byte(key))
121128

@@ -182,6 +189,84 @@ func RemoveVar(key string) {
182189
)
183190
}
184191

192+
type HTTPRequest struct {
193+
url string
194+
header map[string]string
195+
method string
196+
body []byte
197+
}
198+
199+
type HTTPResponse struct {
200+
memory Memory
201+
status uint16
202+
}
203+
204+
func (r HTTPResponse) Memory() Memory {
205+
return r.memory
206+
}
207+
208+
func (r HTTPResponse) Body() []byte {
209+
buf := make([]byte, r.memory.length)
210+
r.memory.Load(buf)
211+
return buf
212+
}
213+
214+
func (r HTTPResponse) Status() uint16 {
215+
return r.status
216+
}
217+
218+
func NewHTTPRequest(method string, url string) *HTTPRequest {
219+
return &HTTPRequest{url: url, header: nil, method: strings.ToUpper(method), body: nil}
220+
}
221+
222+
func (r *HTTPRequest) SetHeader(key string, value string) *HTTPRequest {
223+
if r.header == nil {
224+
r.header = map[string]string{}
225+
}
226+
r.header[key] = value
227+
return r
228+
}
229+
230+
func (r *HTTPRequest) SetBody(body []byte) *HTTPRequest {
231+
r.body = body
232+
return r
233+
}
234+
235+
func (r *HTTPRequest) Send() HTTPResponse {
236+
arena := &fastjson.Arena{}
237+
json := arena.NewObject()
238+
headers := arena.NewObject()
239+
if r.header != nil {
240+
for k, v := range r.header {
241+
headers.Set(k, arena.NewString(v))
242+
}
243+
244+
json.Set("header", headers)
245+
}
246+
json.Set("url", arena.NewString(r.url))
247+
json.Set("method", arena.NewString(r.method))
248+
249+
var buf []byte
250+
enc := json.MarshalTo(buf)
251+
252+
req := AllocateBytes(enc)
253+
defer req.Free()
254+
data := AllocateBytes(r.body)
255+
defer data.Free()
256+
257+
offset := C.extism_http_request(C.uint64_t(req.offset), data.offset)
258+
length := uint64(C.extism_length(offset))
259+
status := uint16(C.extism_http_status_code())
260+
261+
memory := Memory{offset, length}
262+
defer memory.Free()
263+
264+
return HTTPResponse{
265+
memory,
266+
status,
267+
}
268+
}
269+
185270
func (m *Memory) Load(buffer []byte) {
186271
load(m.offset, buffer)
187272
}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
module github.com/extism/go-pdk
22

33
go 1.19
4+
5+
require github.com/valyala/fastjson v1.6.3

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc=
2+
github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=

0 commit comments

Comments
 (0)