-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathwasi_http.c
97 lines (79 loc) · 3.03 KB
/
wasi_http.c
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
#include <assert.h>
#include <string.h>
#include <mono-wasi/driver.h>
#include "req.h"
int handle_close(int handle) {
return http_close((ResponseHandle)handle);
}
int http_req_raw(const char* url, const char* method, const char* headers, const char* body, uint16_t *statusCode, ResponseHandle *handle) {
return req(url, url ? strlen(url) : 0,
method, method ? strlen(method) : 0,
headers, headers ? strlen(headers) : 0,
body, body ? strlen(body) : 0,
statusCode, handle);
}
int http_req(MonoString *url, MonoString *method, MonoString *headers, MonoString *body, int *statusCode, int *handle) {
char* url_utf8 = mono_wasm_string_get_utf8(url);
char* method_utf8 = mono_wasm_string_get_utf8(method);
char* headers_utf8 = mono_wasm_string_get_utf8(headers);
char* body_utf8 = mono_wasm_string_get_utf8(body);
uint16_t code;
HttpError result = http_req_raw(url_utf8, method_utf8, headers_utf8, body_utf8, &code, (ResponseHandle *)handle);
*statusCode = code;
free(url_utf8);
free(method_utf8);
free(headers_utf8);
free(body_utf8);
return result;
}
MonoString* http_read_body(int handle) {
// TODO: read content-length header here
char buffer[1024 * 1024];
size_t written;
HttpError err = bodyRead(
(ResponseHandle) handle,
&buffer[0],
1024 * 1024 - 1 /* save a space for the null terminator */,
&written);
if (err != 0) {
return NULL;
}
buffer[written] = 0;
return mono_wasm_string_from_js(&buffer[0]);
}
MonoString* http_read_headers_all(int handle) {
char buffer[1024 * 1024];
size_t written;
HttpError err = getAllHeaders(
(ResponseHandle) handle,
&buffer[0],
1024 * 1024 - 1 /* save a space for the null terminator */,
&written);
if (err != 0) {
return NULL;
}
buffer[written] = 0;
return mono_wasm_string_from_js(&buffer[0]);
}
void noop_settimeout(int timeout) {
// Not implemented
}
MonoMethod *threadpool_callback;
void wasi_queuecallback() {
if (!threadpool_callback) {
threadpool_callback = lookup_dotnet_method("System.Private.CoreLib.dll", "System.Threading", "ThreadPool", "Callback", -1);
assert(threadpool_callback);
}
MonoObject* exception;
MonoObject* res = mono_wasm_invoke_method(threadpool_callback, NULL, NULL, &exception);
assert(!exception);
}
void wasi_http_attach_internal_calls() {
// Workaround lack of threading
mono_add_internal_call("System.Threading.TimerQueue::SetTimeout", noop_settimeout);
mono_add_internal_call("System.Threading.ThreadPool::QueueCallback", wasi_queuecallback);
mono_add_internal_call("Wasi.Http.WasiHttpExperimental::Req", http_req);
mono_add_internal_call("Wasi.Http.WasiHttpExperimental::Close", handle_close);
mono_add_internal_call("Wasi.Http.WasiHttpExperimental::ReadBody", http_read_body);
mono_add_internal_call("Wasi.Http.WasiHttpExperimental::ReadAllHeaders", http_read_headers_all);
}