feat: add emscripten support and http resolver#197
Conversation
| # Debug build | ||
| debug: | ||
| cmake -S . -B $(DEBUG_BUILD_DIR) -G "Ninja" -DCMAKE_BUILD_TYPE=Debug $(CMAKE_OPTS) | ||
| cmake -S . -B $(DEBUG_BUILD_DIR) -G "Ninja" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON $(CMAKE_OPTS) |
There was a problem hiding this comment.
I need this for the clangd LSP to work. Please let me know if there is a better way.
There was a problem hiding this comment.
I use clangd as well, this is much appreciated!
| /// @details The callback is invoked synchronously whenever the SDK needs to | ||
| /// make an HTTP request (remote manifest fetch, OCSP, timestamp, etc.). | ||
| /// The callback receives a C2paHttpRequest and must fill in a C2paHttpResponse. | ||
| /// The response body must be allocated with malloc(); Rust will call free(). |
There was a problem hiding this comment.
| /// The response body must be allocated with malloc(); Rust will call free(). | |
| /// The response body must be allocated with malloc(); the underlying native library will call free(). |
| if (!is_valid()) { | ||
| throw C2paException("ContextBuilder is invalid (moved from)"); | ||
| } | ||
| C2paHttpResolver* resolver = c2pa_http_resolver_create(context, callback); |
There was a problem hiding this comment.
Shouldn't you check the callback pointer isn't null?
|
|
||
| The [`examples/emscripten_example.cpp`](examples/emscripten_example.cpp) file demonstrates using the c2pa C++ library compiled to WebAssembly via Emscripten. It includes reading manifests from files, streams, and using a custom HTTP resolver with `emscripten_fetch`. | ||
|
|
||
| Prerequisites: Install the [Emscripten SDK](https://emscripten.org/docs/getting_started/downloads.html) and activate it in your shell: |
There was a problem hiding this comment.
Is an exact match of an emscripten version needed?
| Context::ContextBuilder& Context::ContextBuilder::with_http_resolver( | ||
| void* context, C2paHttpResolverCallback callback) { | ||
| if (!is_valid()) { | ||
| throw C2paException("ContextBuilder is invalid (moved from)"); | ||
| } | ||
| C2paHttpResolver* resolver = c2pa_http_resolver_create(context, callback); | ||
| if (!resolver) { | ||
| throw C2paException("Failed to create HTTP resolver"); | ||
| } | ||
| if (c2pa_context_builder_set_http_resolver(context_builder, resolver) != 0) { | ||
| c2pa_free(resolver); | ||
| throw C2paException(); | ||
| } | ||
| return *this; | ||
| } | ||
|
|
There was a problem hiding this comment.
Hm, looking at this now something seems off. Why does the HTTP resolver need a context? If you are building a context, it doesn't make sense to pass in a context. I'm also not sure what an HTTP resolver would do with the context? This might need a change in c2pa-c.
| static std::vector<std::string> storage; | ||
| storage.clear(); |
There was a problem hiding this comment.
We should avoid globals here, can cause threading problems.
| resp->body_len = static_cast<size_t>(fetch->numBytes); | ||
| resp->body = static_cast<uint8_t*>(malloc(resp->body_len)); | ||
| memcpy(resp->body, fetch->data, resp->body_len); |
There was a problem hiding this comment.
We should make sure the response has a body, I'm not sure if that's always the case.
Follow up to feat: Allow emscripten users to define HTTP handler