diff --git a/pom.xml b/pom.xml
index c666436..ac12995 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,6 +74,7 @@
1.3.0
2.1.3
1.1.7
+ 2.18.2
@@ -104,6 +105,12 @@
${jimfs.version}
test
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson-core.version}
+ true
+
jakarta.json
jakarta.json-api
diff --git a/src/main/java/org/extism/sdk/chicory/HttpConfig.java b/src/main/java/org/extism/sdk/chicory/HttpConfig.java
index 82b6658..fdf8dec 100644
--- a/src/main/java/org/extism/sdk/chicory/HttpConfig.java
+++ b/src/main/java/org/extism/sdk/chicory/HttpConfig.java
@@ -1,12 +1,16 @@
package org.extism.sdk.chicory;
+import java.util.Objects;
+
public class HttpConfig {
/**
* Use {@link JdkHttpClientAdapter} for the HTTP client adapter.
* Recommended on recent Java versions.
*/
public static HttpConfig defaultConfig() {
- return new HttpConfig().withClientAdapter(new JdkHttpClientAdapter()).withJsonCodec(new JakartaJsonCodec());
+ return HttpConfig.builder()
+ .withClientAdapter(new JdkHttpClientAdapter())
+ .withJsonCodec(new JacksonJsonCodec()).build();
}
/**
@@ -14,19 +18,45 @@ public static HttpConfig defaultConfig() {
* Recommended for Android.
*/
public static HttpConfig urlConnectionConfig() {
- return new HttpConfig().withClientAdapter(new HttpUrlConnectionClientAdapter()).withJsonCodec(new JakartaJsonCodec());
+ return HttpConfig.builder()
+ .withClientAdapter(new HttpUrlConnectionClientAdapter())
+ .withJsonCodec(new JakartaJsonCodec()).build();
+ }
+
+ public static Builder builder() {
+ return new Builder();
}
+ public static class Builder {
+ HttpJsonCodec httpJsonCodec;
+ HttpClientAdapter httpClientAdapter;
+
+ private Builder() {}
+
+ public Builder withJsonCodec(HttpJsonCodec httpJsonCodec) {
+ this.httpJsonCodec = httpJsonCodec;
+ return this;
+ }
+
+ public Builder withClientAdapter(HttpClientAdapter httpClientAdapter) {
+ this.httpClientAdapter = httpClientAdapter;
+ return this;
+ }
+
+ public HttpConfig build() {
+ Objects.requireNonNull(httpJsonCodec, "httpJsonCodec is required");
+ Objects.requireNonNull(httpClientAdapter, "httpClientAdapter is required");
+ return new HttpConfig(httpJsonCodec, httpClientAdapter);
+ }
+ }
+
+
HttpJsonCodec httpJsonCodec;
HttpClientAdapter httpClientAdapter;
- public HttpConfig withJsonCodec(HttpJsonCodec httpJsonCodec) {
+ public HttpConfig(HttpJsonCodec httpJsonCodec, HttpClientAdapter httpClientAdapter) {
this.httpJsonCodec = httpJsonCodec;
- return this;
- }
-
- public HttpConfig withClientAdapter(HttpClientAdapter httpClientAdapter) {
this.httpClientAdapter = httpClientAdapter;
- return this;
}
+
}
diff --git a/src/main/java/org/extism/sdk/chicory/JacksonJsonCodec.java b/src/main/java/org/extism/sdk/chicory/JacksonJsonCodec.java
new file mode 100644
index 0000000..96584dc
--- /dev/null
+++ b/src/main/java/org/extism/sdk/chicory/JacksonJsonCodec.java
@@ -0,0 +1,70 @@
+package org.extism.sdk.chicory;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class JacksonJsonCodec implements HttpJsonCodec {
+
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ @Override
+ public RequestMetadata decodeMetadata(byte[] data) {
+
+ JsonNode request = null;
+ try {
+ request = objectMapper.readTree(data);
+ } catch (IOException e) {
+ throw new ExtismException(e);
+ }
+
+ var method = request.get("method").asText();
+ var uri = URI.create(request.get("url").asText());
+ var headers = request.get("headers");
+
+ Map headersMap = new HashMap<>();
+ var fields = headers.fields();
+ while (fields.hasNext()) {
+ var entry = fields.next();
+ headersMap.put(entry.getKey(), entry.getValue().asText());
+ }
+
+ return new RequestMetadata() {
+ @Override
+ public String method() {
+ return method;
+ }
+
+ @Override
+ public URI uri() {
+ return uri;
+ }
+
+ @Override
+ public Map headers() {
+ return headersMap;
+ }
+ };
+ }
+
+ public byte[] encodeHeaders(Map> headers) {
+ // FIXME duplicated headers are effectively overwriting duplicate values!
+ var objectNode = objectMapper.createObjectNode();
+ for (var entry : headers.entrySet()) {
+ for (var v : entry.getValue()) {
+ objectNode.put(entry.getKey(), v);
+ }
+ }
+ try {
+ return objectMapper.writeValueAsBytes(objectNode);
+ } catch (JsonProcessingException e) {
+ throw new ExtismException(e);
+ }
+ }
+}
diff --git a/src/test/java/org/extism/sdk/chicory/HostEnvTest.java b/src/test/java/org/extism/sdk/chicory/HostEnvTest.java
index 7999bf4..557913b 100644
--- a/src/test/java/org/extism/sdk/chicory/HostEnvTest.java
+++ b/src/test/java/org/extism/sdk/chicory/HostEnvTest.java
@@ -11,7 +11,7 @@ public void testShowcase() {
var logger = new SystemLogger();
var config = Map.of("key", "value");
- var hostEnv = new HostEnv(new Kernel(), config, new String[0], new HttpConfig(), logger);
+ var hostEnv = new HostEnv(new Kernel(), config, new String[0], HttpConfig.defaultConfig(), logger);
assertEquals(hostEnv.config().get("key"), "value");