Skip to content

Commit 2430526

Browse files
authored
Merge pull request #2 from carlopi/wasm_httplib_replacement
Exposing very hacky Wasm httplib replacement
2 parents 8c82995 + 526eafe commit 2430526

File tree

3 files changed

+107
-5
lines changed

3 files changed

+107
-5
lines changed

CMakeLists.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ set(TARGET_NAME webmacro)
66
# DuckDB's extension distribution supports vcpkg. As such, dependencies can be added in ./vcpkg.json and then
77
# used in cmake with find_package. Feel free to remove or replace with other dependencies.
88
# Note that it should also be removed from vcpkg.json to prevent needlessly installing it..
9-
find_package(OpenSSL REQUIRED)
9+
if(NOT EMSCRIPTEN)
10+
find_package(OpenSSL REQUIRED)
11+
endif()
1012

1113
set(EXTENSION_NAME ${TARGET_NAME}_extension)
1214
set(LOADABLE_EXTENSION_NAME ${TARGET_NAME}_loadable_extension)
@@ -24,8 +26,10 @@ endif()
2426
build_static_extension(${TARGET_NAME} ${EXTENSION_SOURCES})
2527
build_loadable_extension(${TARGET_NAME} " " ${EXTENSION_SOURCES})
2628

27-
target_link_libraries(${EXTENSION_NAME} OpenSSL::SSL OpenSSL::Crypto ${WIN_LIBS})
28-
target_link_libraries(${LOADABLE_EXTENSION_NAME} OpenSSL::SSL OpenSSL::Crypto ${WIN_LIBS})
29+
if(NOT EMSCRIPTEN)
30+
target_link_libraries(${EXTENSION_NAME} OpenSSL::SSL OpenSSL::Crypto ${WIN_LIBS})
31+
target_link_libraries(${LOADABLE_EXTENSION_NAME} OpenSSL::SSL OpenSSL::Crypto ${WIN_LIBS})
32+
endif()
2933

3034
install(
3135
TARGETS ${EXTENSION_NAME}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#include <emscripten.h>
2+
3+
namespace duckdb {
4+
5+
struct WasmResultInner {
6+
idx_t status;
7+
std::string reason;
8+
std::string body;
9+
};
10+
struct WasmResult {
11+
operator bool() { return true; }
12+
WasmResultInner *operator->() { return &_inner; }
13+
WasmResultInner _inner;
14+
};
15+
struct WasmClient {
16+
WasmResult Get(string path) {
17+
WasmResult res;
18+
19+
char *exe = NULL;
20+
exe = (char *)EM_ASM_PTR(
21+
{
22+
var url = (UTF8ToString($0));
23+
if (typeof XMLHttpRequest === "undefined") {
24+
return 0;
25+
}
26+
const xhr = new XMLHttpRequest();
27+
xhr.open("GET", url, false);
28+
xhr.responseType = "arraybuffer";
29+
xhr.send(null);
30+
if (xhr.status != 200)
31+
return 0;
32+
var uInt8Array = xhr.response;
33+
34+
var len = uInt8Array.byteLength;
35+
var fileOnWasmHeap = _malloc(len + 4);
36+
37+
var properArray = new Uint8Array(uInt8Array);
38+
39+
for (var iii = 0; iii < len; iii++) {
40+
Module.HEAPU8[iii + fileOnWasmHeap + 4] = properArray[iii];
41+
}
42+
var LEN123 = new Uint8Array(4);
43+
LEN123[0] = len % 256;
44+
len -= LEN123[0];
45+
len /= 256;
46+
LEN123[1] = len % 256;
47+
len -= LEN123[1];
48+
len /= 256;
49+
LEN123[2] = len % 256;
50+
len -= LEN123[2];
51+
len /= 256;
52+
LEN123[3] = len % 256;
53+
len -= LEN123[3];
54+
len /= 256;
55+
Module.HEAPU8.set(LEN123, fileOnWasmHeap);
56+
console.log(properArray);
57+
return fileOnWasmHeap;
58+
},
59+
path.c_str());
60+
61+
if (!exe) {
62+
res._inner.status = 404;
63+
res._inner.reason = "Something went quack in Wasm land!";
64+
} else {
65+
res._inner.status = 200;
66+
uint64_t LEN = 0;
67+
LEN *= 256;
68+
LEN += ((uint8_t *)exe)[3];
69+
LEN *= 256;
70+
LEN += ((uint8_t *)exe)[2];
71+
LEN *= 256;
72+
LEN += ((uint8_t *)exe)[1];
73+
LEN *= 256;
74+
LEN += ((uint8_t *)exe)[0];
75+
res._inner.body = string(exe + 4, LEN);
76+
free(exe);
77+
}
78+
79+
return res;
80+
}
81+
};
82+
83+
static std::pair<WasmClient, std::string>
84+
SetupHttpClient(const std::string &url) {
85+
WasmClient x;
86+
return std::make_pair(std::move(x), url);
87+
}
88+
89+
static void HandleHttpError(const WasmResult &res,
90+
const std::string &request_type) {}
91+
92+
} // namespace duckdb

src/webmacro_extension.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,18 @@
1010
#include <duckdb/parser/parsed_data/create_scalar_function_info.hpp>
1111
#include "duckdb/common/exception/http_exception.hpp"
1212

13+
#include "yyjson.hpp"
14+
15+
#ifdef EMSCRIPTEN
16+
#include "wasm_httplib_replacement.hpp"
17+
#else
1318
#define CPPHTTPLIB_OPENSSL_SUPPORT
1419
#include "httplib.hpp"
15-
#include "yyjson.hpp"
20+
#endif
1621

1722
namespace duckdb {
1823

24+
#ifndef EMSCRIPTEN
1925
// Helper function to setup HTTP client
2026
static std::pair<duckdb_httplib_openssl::Client, std::string> SetupHttpClient(const std::string &url) {
2127
std::string scheme, domain, path;
@@ -59,7 +65,7 @@ static void HandleHttpError(const duckdb_httplib_openssl::Result &res, const std
5965
}
6066
throw std::runtime_error(err_message);
6167
}
62-
68+
#endif
6369

6470
static bool ContainsMacroDefinition(const std::string &content) {
6571
std::string upper_content = StringUtil::Upper(content);

0 commit comments

Comments
 (0)