diff --git a/CMakeLists.txt b/CMakeLists.txt index d81e041..56e7226 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,9 @@ set(TARGET_NAME webmacro) # DuckDB's extension distribution supports vcpkg. As such, dependencies can be added in ./vcpkg.json and then # used in cmake with find_package. Feel free to remove or replace with other dependencies. # Note that it should also be removed from vcpkg.json to prevent needlessly installing it.. -find_package(OpenSSL REQUIRED) +if(NOT EMSCRIPTEN) + find_package(OpenSSL REQUIRED) +endif() set(EXTENSION_NAME ${TARGET_NAME}_extension) set(LOADABLE_EXTENSION_NAME ${TARGET_NAME}_loadable_extension) @@ -24,8 +26,10 @@ endif() build_static_extension(${TARGET_NAME} ${EXTENSION_SOURCES}) build_loadable_extension(${TARGET_NAME} " " ${EXTENSION_SOURCES}) -target_link_libraries(${EXTENSION_NAME} OpenSSL::SSL OpenSSL::Crypto ${WIN_LIBS}) -target_link_libraries(${LOADABLE_EXTENSION_NAME} OpenSSL::SSL OpenSSL::Crypto ${WIN_LIBS}) +if(NOT EMSCRIPTEN) + target_link_libraries(${EXTENSION_NAME} OpenSSL::SSL OpenSSL::Crypto ${WIN_LIBS}) + target_link_libraries(${LOADABLE_EXTENSION_NAME} OpenSSL::SSL OpenSSL::Crypto ${WIN_LIBS}) +endif() install( TARGETS ${EXTENSION_NAME} diff --git a/src/include/wasm_httplib_replacement.hpp b/src/include/wasm_httplib_replacement.hpp new file mode 100644 index 0000000..48ccbab --- /dev/null +++ b/src/include/wasm_httplib_replacement.hpp @@ -0,0 +1,92 @@ +#include + +namespace duckdb { + +struct WasmResultInner { + idx_t status; + std::string reason; + std::string body; +}; +struct WasmResult { + operator bool() { return true; } + WasmResultInner *operator->() { return &_inner; } + WasmResultInner _inner; +}; +struct WasmClient { + WasmResult Get(string path) { + WasmResult res; + + char *exe = NULL; + exe = (char *)EM_ASM_PTR( + { + var url = (UTF8ToString($0)); + if (typeof XMLHttpRequest === "undefined") { + return 0; + } + const xhr = new XMLHttpRequest(); + xhr.open("GET", url, false); + xhr.responseType = "arraybuffer"; + xhr.send(null); + if (xhr.status != 200) + return 0; + var uInt8Array = xhr.response; + + var len = uInt8Array.byteLength; + var fileOnWasmHeap = _malloc(len + 4); + + var properArray = new Uint8Array(uInt8Array); + + for (var iii = 0; iii < len; iii++) { + Module.HEAPU8[iii + fileOnWasmHeap + 4] = properArray[iii]; + } + var LEN123 = new Uint8Array(4); + LEN123[0] = len % 256; + len -= LEN123[0]; + len /= 256; + LEN123[1] = len % 256; + len -= LEN123[1]; + len /= 256; + LEN123[2] = len % 256; + len -= LEN123[2]; + len /= 256; + LEN123[3] = len % 256; + len -= LEN123[3]; + len /= 256; + Module.HEAPU8.set(LEN123, fileOnWasmHeap); + console.log(properArray); + return fileOnWasmHeap; + }, + path.c_str()); + + if (!exe) { + res._inner.status = 404; + res._inner.reason = "Something went quack in Wasm land!"; + } else { + res._inner.status = 200; + uint64_t LEN = 0; + LEN *= 256; + LEN += ((uint8_t *)exe)[3]; + LEN *= 256; + LEN += ((uint8_t *)exe)[2]; + LEN *= 256; + LEN += ((uint8_t *)exe)[1]; + LEN *= 256; + LEN += ((uint8_t *)exe)[0]; + res._inner.body = string(exe + 4, LEN); + free(exe); + } + + return res; + } +}; + +static std::pair +SetupHttpClient(const std::string &url) { + WasmClient x; + return std::make_pair(std::move(x), url); +} + +static void HandleHttpError(const WasmResult &res, + const std::string &request_type) {} + +} // namespace duckdb diff --git a/src/webmacro_extension.cpp b/src/webmacro_extension.cpp index 6755fb0..0f60f4c 100644 --- a/src/webmacro_extension.cpp +++ b/src/webmacro_extension.cpp @@ -10,12 +10,18 @@ #include #include "duckdb/common/exception/http_exception.hpp" +#include "yyjson.hpp" + +#ifdef EMSCRIPTEN +#include "wasm_httplib_replacement.hpp" +#else #define CPPHTTPLIB_OPENSSL_SUPPORT #include "httplib.hpp" -#include "yyjson.hpp" +#endif namespace duckdb { +#ifndef EMSCRIPTEN // Helper function to setup HTTP client static std::pair SetupHttpClient(const std::string &url) { std::string scheme, domain, path; @@ -59,7 +65,7 @@ static void HandleHttpError(const duckdb_httplib_openssl::Result &res, const std } throw std::runtime_error(err_message); } - +#endif static bool ContainsMacroDefinition(const std::string &content) { std::string upper_content = StringUtil::Upper(content);