Skip to content

feat: add emscripten support and http resolver#197

Open
cdmurph32 wants to merge 1 commit intomainfrom
emscripten-example
Open

feat: add emscripten support and http resolver#197
cdmurph32 wants to merge 1 commit intomainfrom
emscripten-example

Conversation

@cdmurph32
Copy link
Copy Markdown
Contributor

  • Allow user to define an http resolver
  • Add an emscripten example.

Follow up to feat: Allow emscripten users to define HTTP handler

# 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)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need this for the clangd LSP to work. Please let me know if there is a better way.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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().
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// 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);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is an exact match of an emscripten version needed?

@tmathern tmathern requested a review from ok-nick April 2, 2026 20:21
Comment on lines +170 to +185
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;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +66 to +67
static std::vector<std::string> storage;
storage.clear();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid globals here, can cause threading problems.

Comment on lines +102 to +104
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);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make sure the response has a body, I'm not sure if that's always the case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants