Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 143 additions & 1 deletion lib/src/http_wasm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,149 @@ class HTTPWasmClient : public HTTPClient {

return res;
}
unique_ptr<HTTPResponse> Put(PutRequestInfo &info) override { return nullptr; }
unique_ptr<HTTPResponse> Put(PutRequestInfo &info) override {
unique_ptr<HTTPResponse> res;

string path = host_port + info.url;
path = info.url;

int n = 0;
for (auto h : info.headers) {
n++;
}

char **z = (char **)(void *)malloc(n * 4 * 2);

int i = 0;
for (auto h : info.headers) {
z[i] = (char *)malloc(h.first.size() * 4 + 1);
memset(z[i], 0, h.first.size() * 4 + 1);
memcpy(z[i], h.first.c_str(), h.first.size());
i++;
z[i] = (char *)malloc(h.second.size() * 4 + 1);
memset(z[i], 0, h.second.size() * 4 + 1);
memcpy(z[i], h.second.c_str(), h.second.size());
i++;
}

const int buffer_length = info.buffer_in_len;
char *payload = (char *)malloc(buffer_length);
memcpy(payload, info.buffer_in, buffer_length);

// clang-format off
char *exe = NULL;
exe = (char *)EM_ASM_PTR(
{
var url = (UTF8ToString($0));
if (typeof XMLHttpRequest === "undefined") {
return 0;
}
const xhr = new XMLHttpRequest();
if (false && url.startsWith("http://")) {
url = "https://" + url.substr(7);
}
xhr.open(UTF8ToString($3), url, false);
xhr.responseType = "arraybuffer";

var i = 0;
var len = $1;
while (i < len*2) {
var ptr1 = HEAP32[($2)/4 + i ];
var ptr2 = HEAP32[($2)/4 + i + 1];

try {
var z = encodeURI(UTF8ToString(ptr1));
if (z === "Host") z = "X-Host-Override";
if (z === "User-Agent") z = "X-user-agent";
if (z === "Authorization") {
xhr.setRequestHeader(z, UTF8ToString(ptr2));
} else {

xhr.setRequestHeader(z, encodeURI(UTF8ToString(ptr2)));
}
} catch (error) {
console.warn("Error while performing XMLHttpRequest.setRequestHeader()", error);
}
i += 2;
}

//xhr.setRequestHeader("Content-Type", "application/octet-stream");
//xhr.setRequestHeader("Content-Type", "text/json");
try {
var post_payload = new Uint8Array($5);

for (var iii = 0; iii < $5; iii++) {
post_payload[iii] = Module.HEAPU8[iii + $4];
}
xhr.send(post_payload);
console.log(xhr.getResponseHeader("ETAG"));
} catch {
return 0;
}
if (xhr.status >= 400) return 0;
var uInt8Array = Uint8Array.from(Array.from(xhr.getResponseHeader("Etag")).map(letter => letter.charCodeAt(0)));

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);
return fileOnWasmHeap;
},
path.c_str(), n, z, "PUT", payload, buffer_length);
// clang-format on

free(payload);

i = 0;
for (auto h : info.headers) {
free(z[i]);
i++;
free(z[i]);
i++;
}
free(z);

if (!exe) {
res = make_uniq<HTTPResponse>(HTTPStatusCode::NotFound_404);
res->reason = "Please consult the browser console for details, might be potentially a CORS error";
} else {
res = duckdb::make_uniq<HTTPResponse>(HTTPStatusCode::OK_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->headers.Insert("ETag", string(exe + 4, LEN));

// info.buffer_out += string(exe + 4, LEN);

free(exe);
}

return res;
}
unique_ptr<HTTPResponse> Delete(DeleteRequestInfo &info) override { return nullptr; }

private:
Expand Down