httpproxy_wasm.mx raw
1 //go:build wasm
2 //:build wasm
3
4 package httpproxy
5
6 import (
7 "git.smesh.lol/smesh/web/common/jsbridge/callback"
8 "unsafe"
9 )
10
11 // === Consumer-side ===
12
13 //:wasmimport bridge httpproxy_request
14 func wasmRequest(reqID int32, urlPtr *byte, urlLen int32, urlCap int32, priority int32)
15
16 //:wasmimport bridge httpproxy_request_cancel
17 func wasmRequestCancel(reqID int32)
18
19 type fetchHandler struct {
20 onOK func(string, string)
21 onFail func(int32, string)
22 }
23
24 var pendingFetches = map[int32]fetchHandler{}
25
26 func Request(reqID int32, url string, priority int32,
27 onOK func(blobURL, contentType string),
28 onFail func(status int32, errMsg string)) {
29 pendingFetches[reqID] = fetchHandler{onOK: onOK, onFail: onFail}
30 wasmRequest(reqID, unsafe.StringData(url), int32(len(url)), int32(len(url)), priority)
31 }
32
33 func RequestCancel(reqID int32) {
34 delete(pendingFetches, reqID)
35 wasmRequestCancel(reqID)
36 }
37
38 // __httpproxy_result_ok is the wasm export the supervisor calls when a
39 // fetch succeeds. blobURL and contentType are the result strings.
40 //
41 //:wasmexport __httpproxy_result_ok
42 func httpproxyResultOK(reqID int32, blobPtr *byte, blobLen int32, ctPtr *byte, ctLen int32) {
43 h, ok := pendingFetches[reqID]
44 if !ok {
45 return
46 }
47 delete(pendingFetches, reqID)
48 blobURL := ""
49 if blobLen > 0 {
50 blobURL = unsafe.String(blobPtr, blobLen)
51 }
52 contentType := ""
53 if ctLen > 0 {
54 contentType = unsafe.String(ctPtr, ctLen)
55 }
56 h.onOK(blobURL, contentType)
57 }
58
59 // __httpproxy_result_fail is the wasm export the supervisor calls when a
60 // fetch fails. status is the upstream HTTP status (0 if no response).
61 //
62 //:wasmexport __httpproxy_result_fail
63 func httpproxyResultFail(reqID int32, status int32, errPtr *byte, errLen int32) {
64 h, ok := pendingFetches[reqID]
65 if !ok {
66 return
67 }
68 delete(pendingFetches, reqID)
69 errMsg := ""
70 if errLen > 0 {
71 errMsg = unsafe.String(errPtr, errLen)
72 }
73 h.onFail(status, errMsg)
74 }
75
76 // === Worker-internal ===
77
78 //:wasmimport bridge httpproxy_on_message
79 func wasmOnMessage(cbID int32)
80
81 //:wasmimport bridge httpproxy_post
82 func wasmPost(ptr *byte, length int32, cap int32)
83
84 //:wasmimport bridge httpproxy_fetch
85 func wasmFetch(reqID int32, urlPtr *byte, urlLen int32, urlCap int32)
86
87 //:wasmimport bridge httpproxy_cancel
88 func wasmCancel(reqID int32)
89
90 //:wasmimport bridge httpproxy_revoke_blob
91 func wasmRevokeBlob(ptr *byte, length int32, cap int32)
92
93 func OnMessage(fn func(msg string)) {
94 wasmOnMessage(callback.RegisterS(fn))
95 }
96
97 func Post(msg string) {
98 wasmPost(unsafe.StringData(msg), int32(len(msg)), int32(len(msg)))
99 }
100
101 func Fetch(reqID int32, url string) {
102 wasmFetch(reqID, unsafe.StringData(url), int32(len(url)), int32(len(url)))
103 }
104
105 func Cancel(reqID int32) {
106 wasmCancel(reqID)
107 }
108
109 func RevokeBlob(url string) {
110 wasmRevokeBlob(unsafe.StringData(url), int32(len(url)), int32(len(url)))
111 }
112