-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathwasm.go
322 lines (288 loc) · 11.8 KB
/
wasm.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
package handler
// CtxNext is the result of FuncHandleRequest. For compatability with
// WebAssembly Core Specification 1.0, two uint32 values are combined into a
// single uint64 in the following order:
//
// - ctx: opaque 32-bits the guest defines and the host propagates to
// FuncHandleResponse. A typical use is correlation of request state.
// - next: one to proceed to the next handler on the host. zero to skip any
// next handler. Guests skip when they wrote a response or decided not to.
//
// When the guest decides to proceed to the next handler, it can return
// `ctxNext=1` which is the same as `next=1` without any request context. If it
// wants the host to propagate request context, it shifts that into the upper
// 32-bits of ctxNext like so:
//
// ctxNext = uint64(reqCtx) << 32
// if next {
// ctxNext |= 1
// }
//
// # Examples
//
// - 0<<32|0 (0): don't proceed to the next handler.
// - 0<<32|1 (1): proceed to the next handler without context state.
// - 16<<32|1 (68719476737): proceed to the next handler and call
// FuncHandleResponse with 16.
// - 16<<32|16 (68719476736): the value 16 is ignored because
// FuncHandleResponse won't be called.
type CtxNext uint64
// BufLimit is the possibly zero maximum length of a result value to write in
// bytes. If the actual value is larger than this, nothing is written to
// memory.
type BufLimit = uint32
// CountLen describes a possible empty sequence of NUL-terminated strings. For
// compatability with WebAssembly Core Specification 1.0, two uint32 values are
// combined into a single uint64 in the following order:
//
// - count: zero if the sequence is empty, or the count of strings.
// - len: possibly zero length of the sequence, including NUL-terminators.
//
// If the uint64 result is zero, the sequence is empty. Otherwise, you need to
// split the results like so.
//
// - count: `uint32(countLen >> 32)`
// - len: `uint32(countLen)`
//
// # Examples
//
// - "": 0<<32|0 or simply zero.
// - "Accept\0": 1<<32|7
// - "Content-Type\0Content-Length\0": 2<<32|28
type CountLen = uint64
// EOFLen is the result of FuncReadBody which allows callers to know if the
// bytes returned are the end of the stream. For compatability with WebAssembly
// Core Specification 1.0, two uint32 values are combined into a single uint64
// in the following order:
//
// - eof: the body is exhausted.
// - len: possibly zero length of bytes read from the body.
//
// Here's how to split the results:
//
// - eof: `uint32(eofLen >> 32)`
// - len: `uint32(eofLen)`
//
// # Examples
//
// - 1<<32|0 (4294967296): EOF and no bytes were read
// - 0<<32|16 (16): 16 bytes were read and there may be more available.
//
// Note: `EOF` is not an error, so process `len` bytes returned regardless.
type EOFLen = uint64
type BodyKind uint32
const (
// BodyKindRequest represents an operation on an HTTP request body.
//
// # Notes on FuncReadBody
//
// FeatureBufferResponse is required to read the request body without
// consuming it. To enable it, call FuncEnableFeatures before FuncNext.
// Otherwise, a downstream handler may panic attempting to read a request
// body already read upstream.
//
// # Notes on FuncWriteBody
//
// The first call to FuncWriteBody in FuncHandleRequest overwrites any request
// body.
BodyKindRequest BodyKind = 0
// BodyKindResponse represents an operation on an HTTP request body.
//
// # Notes on FuncReadBody
//
// FeatureBufferResponse is required to read the response body produced by
// FuncNext. To enable it, call FuncEnableFeatures beforehand. Otherwise,
// a handler may panic calling FuncReadBody with BodyKindResponse.
//
// # Notes on FuncWriteBody
//
// The first call to FuncWriteBody in FuncHandleRequest or after FuncNext
// overwrites any response body.
BodyKindResponse BodyKind = 1
)
type HeaderKind uint32
const (
// HeaderKindRequest represents an operation on HTTP request headers.
HeaderKindRequest HeaderKind = 0
// HeaderKindResponse represents an operation on HTTP response headers.
HeaderKindResponse HeaderKind = 1
// HeaderKindRequestTrailers represents an operation on HTTP request
// trailers (trailing headers). This requires FeatureTrailers.
//
// To enable FeatureTrailers, call FuncEnableFeatures prior to FuncNext.
// Doing otherwise, may result in a panic.
HeaderKindRequestTrailers HeaderKind = 2
// HeaderKindResponseTrailers represents an operation on HTTP response
// trailers (trailing headers). This requires FeatureTrailers.
//
// To enable FeatureTrailers, call FuncEnableFeatures prior to FuncNext.
// Doing otherwise, may result in a panic.
HeaderKindResponseTrailers HeaderKind = 3
)
const (
// HostModule is the WebAssembly module name of the ABI this middleware
// implements.
//
// Note: This is lower-hyphen case while functions are lower_underscore to
// follow conventions of wit-bindgen, which retains the case format of the
// interface filename as the module name, but converts function and
// parameter names to lower_underscore format.
//
// See https://github.com/http-wasm/http-wasm-abi/blob/main/http_handler/http_handler.wit.md
HostModule = "http_handler"
// FuncEnableFeatures tries to enable the given features and returns the
// Features bitflag supported by the host. To have any affect, this must be
// called prior to returning from FuncHandleRequest.
//
// This may be called prior to FuncHandleRequest, for example inside a
// start function. Doing so reduces overhead per-call and also allows the
// guest to fail early on unsupported.
//
// If called during FuncHandleRequest, any new features are enabled for the
// scope of the current request. This allows fine-grained access to
// expensive features such as FeatureBufferResponse.
//
// TODO: document on http-wasm-abi
FuncEnableFeatures = "enable_features"
// FuncGetConfig writes configuration from the host to memory if it exists
// and isn't larger than BufLimit. The result is its length in bytes.
//
// Note: Configuration is determined by the guest and is not necessarily
// UTF-8 encoded.
//
// TODO: document on http-wasm-abi
FuncGetConfig = "get_config"
// FuncLogEnabled returns 1 if the api.LogLevel is enabled. This value may
// be cached at request granularity.
//
// This function is used to avoid unnecessary overhead generating log
// messages that the host would discard due to its level being below this.
//
// TODO: document on http-wasm-abi
FuncLogEnabled = "log_enabled"
// FuncLog logs a message to the host's logs at the given api.LogLevel.
//
// See https://github.com/http-wasm/http-wasm-abi/blob/main/http_handler/http_handler.wit.md#log
FuncLog = "log"
// FuncHandleRequest is the entrypoint guest export called by the host when
// processing a request.
//
// To proceed to the next handler, the guest returns CtxNext `next=1`. The
// simplest result is uint64(1). Guests who need request correlation can
// also set the CtxNext "ctx" field. This will be propagated by the host as
// the `reqCtx` parameter of FuncHandleResponse.
//
// To skip any next handler, the guest returns CtxNext `next=0`, or simply
// uint64(0). In this case, FuncHandleResponse will not be called.
FuncHandleRequest = "handle_request"
// FuncHandleResponse is called by the host after processing the next
// handler when the guest returns CtxNext `next=1` from FuncHandleRequest.
//
// The `reqCtx` parameter is a possibly zero CtxNext "ctx" field the host
// the host propagated from FuncHandleRequest. This allows request
// correlation for guests who need it.
//
// The `isError` parameter is one if there was a host error producing a
// response. This allows guests to clean up any resources.
//
// By default, whether the next handler flushes the response prior to
// returning is implementation-specific. If your handler needs to inspect
// or manipulate the downstream response, enable FeatureBufferResponse via
// FuncEnableFeatures prior to returning from FuncHandleRequest.
// TODO: update
FuncHandleResponse = "handle_response"
// FuncGetMethod writes the method to memory if it isn't larger than
// BufLimit. The result is its length in bytes. Ex. "GET"
//
// TODO: document on http-wasm-abi
FuncGetMethod = "get_method"
// FuncSetMethod overwrites the method with one read from memory.
//
// TODO: document on http-wasm-abi
FuncSetMethod = "set_method"
// FuncGetURI writes the URI to memory if it isn't larger than BufLimit.
// The result is its length in bytes. Ex. "/v1.0/hi?name=panda"
//
// Note: The URI may include query parameters.
//
// TODO: update document on http-wasm-abi
// See https://github.com/http-wasm/http-wasm-abi/blob/main/http_handler/http_handler.wit.md#get_uri
FuncGetURI = "get_uri"
// FuncSetURI overwrites the URI with one read from memory.
//
// Note: The URI may include query parameters.
//
// TODO: update document on http-wasm-abi
// See https://github.com/http-wasm/http-wasm-abi/blob/main/http_handler/http_handler.wit.md#set_uri
FuncSetURI = "set_uri"
// FuncGetProtocolVersion writes the HTTP protocol version to memory if it
// isn't larger than BufLimit. The result is its length in bytes.
// Ex. "HTTP/1.1"
//
// See https://www.rfc-editor.org/rfc/rfc9110#name-protocol-version
// TODO: document on http-wasm-abi
FuncGetProtocolVersion = "get_protocol_version"
// FuncGetHeaderNames writes all names for the given HeaderKind,
// NUL-terminated, to memory if the encoded length isn't larger than
// BufLimit. CountLen is returned regardless of whether memory was written.
//
// TODO: document on http-wasm-abi
FuncGetHeaderNames = "get_header_names"
// FuncGetHeaderValues writes all values of the given HeaderKind and name,
// NUL-terminated, to memory if the encoded length isn't larger than
// BufLimit. CountLen is returned regardless of whether memory was written.
//
// TODO: document on http-wasm-abi
FuncGetHeaderValues = "get_header_values"
// FuncSetHeaderValue overwrites all values of the given HeaderKind and name
// with the input.
//
// TODO: document on http-wasm-abi
FuncSetHeaderValue = "set_header_value"
// FuncAddHeaderValue adds a single value for the given HeaderKind and
// name.
//
// TODO: document on http-wasm-abi
FuncAddHeaderValue = "add_header_value"
// FuncRemoveHeader removes any values for the given HeaderKind and name.
//
// TODO: document on http-wasm-abi
FuncRemoveHeader = "remove_header"
// FuncReadBody reads up to BufLimit bytes remaining in the BodyKind body
// into memory at offset `buf`. A zero BufLimit will panic.
//
// The result is EOFLen, indicating the count of bytes read and whether
// there may be more available.
//
// Unlike `get_XXX` functions, this function is stateful, so repeated calls
// reads what's remaining in the stream, as opposed to starting from zero.
// Callers do not have to exhaust the stream until `EOF`.
//
// TODO: document on http-wasm-abi
FuncReadBody = "read_body"
// FuncWriteBody reads `buf_len` bytes at memory offset `buf` and writes
// them to the pending BodyKind body.
//
// Unlike `set_XXX` functions, this function is stateful, so repeated calls
// write to the current stream.
//
// TODO: document on http-wasm-abi
FuncWriteBody = "write_body"
// FuncAwaitResponse TODO
FuncAwaitResponse = "await_response"
// FuncGetStatusCode returns the status code produced by FuncNext. This
// requires FeatureBufferResponse.
//
// To enable FeatureBufferResponse, FuncEnableFeatures prior to FuncNext.
// Doing otherwise, or calling before FuncNext will panic.
//
// TODO: document on http-wasm-abi
FuncGetStatusCode = "get_status_code"
// FuncSetStatusCode overrides the status code. The default is 200.
//
// To use this function after FuncNext, set FeatureBufferResponse via
// FuncEnableFeatures. Otherwise, this can be called when FuncNext wasn't.
//
// TODO: document on http-wasm-abi
FuncSetStatusCode = "set_status_code"
)