From d9fab64ff36ee1082ec19eb0d395425e1d3870a1 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Sat, 14 Dec 2024 11:15:33 +0100 Subject: [PATCH 1/6] http: stub pdk host functions Signed-off-by: Edoardo Vacchi --- src/main/java/org/extism/chicory/sdk/HostEnv.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/extism/chicory/sdk/HostEnv.java b/src/main/java/org/extism/chicory/sdk/HostEnv.java index 5e65a98..adbfb5e 100644 --- a/src/main/java/org/extism/chicory/sdk/HostEnv.java +++ b/src/main/java/org/extism/chicory/sdk/HostEnv.java @@ -49,7 +49,15 @@ public HostFunction[] toHostFunctions() { kernel.toHostFunctions(), log.toHostFunctions(), var.toHostFunctions(), - config.toHostFunctions()); + config.toHostFunctions(), + new HostFunction[] { + new HostFunction("extism:host/env", "http_request", List.of(ValueType.I64, ValueType.I64), List.of(ValueType.I64), (Instance instance, long... in)->{ + throw new IllegalArgumentException("not yet implemented: http_request"); + }), + new HostFunction("extism:host/env", "http_status_code", List.of(), List.of(ValueType.I32), (Instance instance, long... in)->{ + throw new IllegalArgumentException("not yet implemented: http_status_code"); + }), + }); } private HostFunction[] concat(HostFunction[]... hfs) { From 16d05bd202218feae223cb32b3f70f5636fcdea6 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Wed, 18 Dec 2024 17:46:50 +0100 Subject: [PATCH 2/6] wip: add http client, json Signed-off-by: Edoardo Vacchi --- pom.xml | 7 + .../org/extism/chicory/sdk/ChicoryModule.java | 1 - .../java/org/extism/chicory/sdk/HostEnv.java | 160 ++++++++++++++++-- 3 files changed, 155 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index ff7783e..c35f4a0 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,7 @@ 3.2.1 3.2.7 1.3.0 + 2.1.3 @@ -102,6 +103,12 @@ ${jimfs.version} test + + jakarta.json + jakarta.json-api + ${jakarta.json-api.version} + true + diff --git a/src/main/java/org/extism/chicory/sdk/ChicoryModule.java b/src/main/java/org/extism/chicory/sdk/ChicoryModule.java index 2f2f1ff..b1a7e1b 100644 --- a/src/main/java/org/extism/chicory/sdk/ChicoryModule.java +++ b/src/main/java/org/extism/chicory/sdk/ChicoryModule.java @@ -1,6 +1,5 @@ package org.extism.chicory.sdk; -import com.dylibso.chicory.experimental.aot.AotMachine; import com.dylibso.chicory.runtime.Instance; import com.dylibso.chicory.wasm.Parser; import com.dylibso.chicory.wasm.WasmModule; diff --git a/src/main/java/org/extism/chicory/sdk/HostEnv.java b/src/main/java/org/extism/chicory/sdk/HostEnv.java index adbfb5e..df8b486 100644 --- a/src/main/java/org/extism/chicory/sdk/HostEnv.java +++ b/src/main/java/org/extism/chicory/sdk/HostEnv.java @@ -5,7 +5,18 @@ import com.dylibso.chicory.runtime.Instance; import com.dylibso.chicory.wasm.types.Value; import com.dylibso.chicory.wasm.types.ValueType; - +import jakarta.json.Json; +import jakarta.json.JsonReader; +import jakarta.json.JsonString; +import jakarta.json.JsonValue; +import jakarta.json.stream.JsonParser; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; @@ -22,6 +33,7 @@ public class HostEnv { private final Log log; private final Var var; private final Config config; + private final Http http; public HostEnv(Kernel kernel, Map config, Logger logger) { this.kernel = kernel; @@ -30,6 +42,7 @@ public HostEnv(Kernel kernel, Map config, Logger logger) { this.config = new Config(config); this.var = new Var(); this.log = new Log(); + this.http = new Http(); } public Log log() { @@ -50,14 +63,7 @@ public HostFunction[] toHostFunctions() { log.toHostFunctions(), var.toHostFunctions(), config.toHostFunctions(), - new HostFunction[] { - new HostFunction("extism:host/env", "http_request", List.of(ValueType.I64, ValueType.I64), List.of(ValueType.I64), (Instance instance, long... in)->{ - throw new IllegalArgumentException("not yet implemented: http_request"); - }), - new HostFunction("extism:host/env", "http_status_code", List.of(), List.of(ValueType.I32), (Instance instance, long... in)->{ - throw new IllegalArgumentException("not yet implemented: http_status_code"); - }), - }); + http.toHostFunctions()); } private HostFunction[] concat(HostFunction[]... hfs) { @@ -116,7 +122,8 @@ long writeString(String s) { } public class Log { - private Log(){} + private Log() { + } public void log(LogLevel level, String message) { logger.log(level.toChicoryLogLevel(), message, null); @@ -164,9 +171,10 @@ HostFunction[] toHostFunctions() { } public class Var { - private final Map vars = new ConcurrentHashMap<>(); + private final Map vars = new ConcurrentHashMap<>(); - private Var() {} + private Var() { + } public byte[] get(String key) { return vars.get(key); @@ -254,7 +262,135 @@ HostFunction[] toHostFunctions() { } + public class Http { + HttpClient httpClient; + HttpResponse lastResponse; + + public HttpClient httpClient() { + if (httpClient == null) { + httpClient = HttpClient.newHttpClient(); + } + return httpClient; + } + + private long[] request(Instance instance, long... args) { + var result = new long[1]; + + // FIXME: + // // deny all requests by default + // hostMatches := false + // for _, allowedHost := range plugin.AllowedHosts { + // if allowedHost == url.Hostname() { + // hostMatches = true + // break + // } + // + // pattern := glob.MustCompile(allowedHost) + // if pattern.Match(url.Hostname()) { + // hostMatches = true + // break + // } + // } + // + // if !hostMatches { + // panic(fmt.Errorf("HTTP request to '%v' is not allowed", request.Url)) + // } + + var requestOffset = args[0]; + var bodyOffset = args[1]; + + var requestJson = memory().readBytes(requestOffset); + kernel.free.apply(requestOffset); + + HttpRequest.BodyPublisher bodyPublisher; + if (bodyOffset == 0) { + bodyPublisher = HttpRequest.BodyPublishers.noBody(); + } else { + var requestBody = memory().readBytes(bodyOffset); + kernel.free.apply(bodyOffset); + bodyPublisher = HttpRequest.BodyPublishers.ofByteArray(requestBody); + } + var request = Json.createReader(new ByteArrayInputStream(requestJson)) + .readObject(); + + var method = request.getJsonString("method").getString(); + var uri = URI.create(request.getJsonString("url").getString()); + var headers = request.getJsonObject("headers"); + + var reqBuilder = HttpRequest.newBuilder().uri(uri); + for (var kv : headers.entrySet()) { + reqBuilder.header(kv.getKey(), kv.getValue().toString()); + } + + reqBuilder.method(method, bodyPublisher); + var req = reqBuilder.build(); + + try { + this.lastResponse = + httpClient().send(req, HttpResponse.BodyHandlers.ofByteArray()); + byte[] body = lastResponse.body(); + if (body.length == 0) { + result[0] = 0; + } else { + result[0] = memory().writeBytes(lastResponse.body()); + } + } catch (IOException | InterruptedException e) { + // FIXME gracefully handle the interruption + throw new ExtismException(e); + } + return result; + } + public long[] statusCode(Instance instance, long... args) { + return new long[]{lastResponse == null ? 0 : lastResponse.statusCode()}; + } + + + private long[] headers(Instance instance, long[] longs) { + var result = new long[1]; + if (lastResponse == null) { + return result; + } + + // FIXME duplicated headers are effectively overwriting duplicate values! + var objBuilder = Json.createObjectBuilder(); + for (var entry : lastResponse.headers().map().entrySet()) { + for (var v : entry.getValue()) { + objBuilder.add(entry.getKey(), v); + } + } + + var bytes = objBuilder.build().toString().getBytes(StandardCharsets.UTF_8); + result[0] = memory().writeBytes(bytes); + return result; + } + + + public HostFunction[] toHostFunctions() { + return new HostFunction[]{ + new HostFunction( + Kernel.IMPORT_MODULE_NAME, + "http_request", + List.of(ValueType.I64, ValueType.I64), + List.of(ValueType.I64), + this::request), + new HostFunction( + Kernel.IMPORT_MODULE_NAME, + "http_status_code", + List.of(), + List.of(ValueType.I32), + this::statusCode), + new HostFunction( + Kernel.IMPORT_MODULE_NAME, + "http_headers", + List.of(), + List.of(ValueType.I32), + this::headers), + + }; + } + + } } From 59c226b620ba97cec5611a8d83c3fc1027ce5a72 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Fri, 20 Dec 2024 10:59:33 +0100 Subject: [PATCH 3/6] http fix Signed-off-by: Edoardo Vacchi --- .../java/org/extism/chicory/sdk/HostEnv.java | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/extism/chicory/sdk/HostEnv.java b/src/main/java/org/extism/chicory/sdk/HostEnv.java index df8b486..175c739 100644 --- a/src/main/java/org/extism/chicory/sdk/HostEnv.java +++ b/src/main/java/org/extism/chicory/sdk/HostEnv.java @@ -3,13 +3,8 @@ import com.dylibso.chicory.log.Logger; import com.dylibso.chicory.runtime.HostFunction; import com.dylibso.chicory.runtime.Instance; -import com.dylibso.chicory.wasm.types.Value; import com.dylibso.chicory.wasm.types.ValueType; import jakarta.json.Json; -import jakarta.json.JsonReader; -import jakarta.json.JsonString; -import jakarta.json.JsonValue; -import jakarta.json.stream.JsonParser; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -23,8 +18,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import static com.dylibso.chicory.wasm.types.Value.i64; - public class HostEnv { private final Kernel kernel; @@ -57,6 +50,10 @@ public Config config() { return config; } + public Http http() { + return http; + } + public HostFunction[] toHostFunctions() { return concat( kernel.toHostFunctions(), @@ -273,7 +270,7 @@ public HttpClient httpClient() { return httpClient; } - private long[] request(Instance instance, long... args) { + long[] request(Instance instance, long... args) { var result = new long[1]; // FIXME: @@ -318,12 +315,11 @@ private long[] request(Instance instance, long... args) { var headers = request.getJsonObject("headers"); var reqBuilder = HttpRequest.newBuilder().uri(uri); - for (var kv : headers.entrySet()) { - reqBuilder.header(kv.getKey(), kv.getValue().toString()); + for (var key : headers.keySet()) { + reqBuilder.header(key, headers.getString(key)); } - reqBuilder.method(method, bodyPublisher); - var req = reqBuilder.build(); + var req = reqBuilder.method(method, bodyPublisher).build(); try { this.lastResponse = @@ -342,12 +338,12 @@ private long[] request(Instance instance, long... args) { return result; } - public long[] statusCode(Instance instance, long... args) { + long[] statusCode(Instance instance, long... args) { return new long[]{lastResponse == null ? 0 : lastResponse.statusCode()}; } - private long[] headers(Instance instance, long[] longs) { + long[] headers(Instance instance, long[] longs) { var result = new long[1]; if (lastResponse == null) { return result; @@ -385,7 +381,7 @@ public HostFunction[] toHostFunctions() { Kernel.IMPORT_MODULE_NAME, "http_headers", List.of(), - List.of(ValueType.I32), + List.of(ValueType.I64), this::headers), }; From 37d7f40176e742a3227639ca8f64894a6655c04f Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Tue, 24 Dec 2024 12:04:13 +0100 Subject: [PATCH 4/6] add allowed hosts, begin writing tests Signed-off-by: Edoardo Vacchi --- .../java/org/extism/chicory/sdk/HostEnv.java | 66 ++++++++++++------- .../java/org/extism/chicory/sdk/Linker.java | 5 +- .../java/org/extism/chicory/sdk/Manifest.java | 13 ++++ .../org/extism/chicory/sdk/HostEnvTest.java | 5 +- 4 files changed, 65 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/extism/chicory/sdk/HostEnv.java b/src/main/java/org/extism/chicory/sdk/HostEnv.java index 175c739..bc23b9e 100644 --- a/src/main/java/org/extism/chicory/sdk/HostEnv.java +++ b/src/main/java/org/extism/chicory/sdk/HostEnv.java @@ -28,14 +28,14 @@ public class HostEnv { private final Config config; private final Http http; - public HostEnv(Kernel kernel, Map config, Logger logger) { + public HostEnv(Kernel kernel, Map config, String[] allowedHosts, Logger logger) { this.kernel = kernel; this.memory = new Memory(); this.logger = logger; this.config = new Config(config); this.var = new Var(); this.log = new Log(); - this.http = new Http(); + this.http = new Http(allowedHosts); } public Log log() { @@ -260,9 +260,17 @@ HostFunction[] toHostFunctions() { } public class Http { + private final HostPattern[] hostPatterns; HttpClient httpClient; HttpResponse lastResponse; + public Http(String[] allowedHosts) { + this.hostPatterns = new HostPattern[allowedHosts.length]; + for (int i = 0; i < allowedHosts.length; i++) { + this.hostPatterns[i] = new HostPattern(allowedHosts[i]); + } + } + public HttpClient httpClient() { if (httpClient == null) { httpClient = HttpClient.newHttpClient(); @@ -273,26 +281,6 @@ public HttpClient httpClient() { long[] request(Instance instance, long... args) { var result = new long[1]; - // FIXME: - // // deny all requests by default - // hostMatches := false - // for _, allowedHost := range plugin.AllowedHosts { - // if allowedHost == url.Hostname() { - // hostMatches = true - // break - // } - // - // pattern := glob.MustCompile(allowedHost) - // if pattern.Match(url.Hostname()) { - // hostMatches = true - // break - // } - // } - // - // if !hostMatches { - // panic(fmt.Errorf("HTTP request to '%v' is not allowed", request.Url)) - // } - var requestOffset = args[0]; var bodyOffset = args[1]; @@ -314,6 +302,11 @@ long[] request(Instance instance, long... args) { var uri = URI.create(request.getJsonString("url").getString()); var headers = request.getJsonObject("headers"); + var host = uri.getHost(); + if (Arrays.stream(hostPatterns).anyMatch(p -> !p.matches(host))) { + throw new ExtismException(String.format("HTTP request to '%s' is not allowed", host)); + } + var reqBuilder = HttpRequest.newBuilder().uri(uri); for (var key : headers.keySet()) { reqBuilder.header(key, headers.getString(key)); @@ -386,7 +379,36 @@ public HostFunction[] toHostFunctions() { }; } + } + private static class HostPattern { + private final String pattern; + private final boolean exact; + + public HostPattern(String pattern) { + if (pattern.indexOf('*', 1) != -1) { + throw new ExtismException("Illegal pattern " + pattern); + } + int wildcard = pattern.indexOf('*'); + if (wildcard < 0) { + this.exact = true; + this.pattern = pattern; + } else if (wildcard == 0) { + this.exact = false; + this.pattern = pattern.substring(1); + } else { + throw new ExtismException("Illegal pattern " + pattern); + } + } + + public boolean matches(String host) { + if (exact) { + return host.equals(pattern); + } else { + return host.endsWith(pattern); + } + } } + } diff --git a/src/main/java/org/extism/chicory/sdk/Linker.java b/src/main/java/org/extism/chicory/sdk/Linker.java index 8c464aa..544ed09 100644 --- a/src/main/java/org/extism/chicory/sdk/Linker.java +++ b/src/main/java/org/extism/chicory/sdk/Linker.java @@ -36,21 +36,24 @@ Plugin link() { var dg = new DependencyGraph(logger); Map config; + String[] allowedHosts; WasiOptions wasiOptions; CachedAotMachineFactory aotMachineFactory; if (manifest.options == null) { config = Map.of(); + allowedHosts = new String[0]; wasiOptions = null; aotMachineFactory = null; } else { dg.setOptions(manifest.options); config = manifest.options.config; + allowedHosts = manifest.options.allowedHosts; wasiOptions = manifest.options.wasiOptions; aotMachineFactory = manifest.options.aot? new CachedAotMachineFactory() : null; } // Register the HostEnv exports. - var hostEnv = new HostEnv(new Kernel(aotMachineFactory), config, logger); + var hostEnv = new HostEnv(new Kernel(aotMachineFactory), config, allowedHosts, logger); dg.registerFunctions(hostEnv.toHostFunctions()); // Register the WASI host functions. diff --git a/src/main/java/org/extism/chicory/sdk/Manifest.java b/src/main/java/org/extism/chicory/sdk/Manifest.java index ba0d363..0c54f1f 100644 --- a/src/main/java/org/extism/chicory/sdk/Manifest.java +++ b/src/main/java/org/extism/chicory/sdk/Manifest.java @@ -2,6 +2,7 @@ import com.dylibso.chicory.wasi.WasiOptions; +import java.nio.file.Path; import java.util.EnumSet; import java.util.List; import java.util.Map; @@ -17,6 +18,7 @@ public static class Options { EnumSet validationFlags = EnumSet.noneOf(Validation.class); Map config; WasiOptions wasiOptions; + String[] allowedHosts; public Options withAoT() { this.aot = true; @@ -33,6 +35,17 @@ public Options withValidation(Validation... vs) { return this; } + public Options withAllowedHosts(String... allowedHosts) { + for (String allowedHost : allowedHosts) { + // Wildcards are only allowed at starting position and may occur only once. + if (allowedHost.indexOf('*') > 0 || allowedHost.indexOf('*', 1) != -1) { + throw new ExtismException("Illegal pattern " + allowedHost); + } + } + this.allowedHosts = allowedHosts; + return this; + } + public Options withWasi(WasiOptions wasiOptions) { this.wasiOptions = wasiOptions; return this; diff --git a/src/test/java/org/extism/chicory/sdk/HostEnvTest.java b/src/test/java/org/extism/chicory/sdk/HostEnvTest.java index e12b382..1f0a0f7 100644 --- a/src/test/java/org/extism/chicory/sdk/HostEnvTest.java +++ b/src/test/java/org/extism/chicory/sdk/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, logger); + var hostEnv = new HostEnv(new Kernel(), config, new String[0], logger); assertEquals(hostEnv.config().get("key"), "value"); @@ -24,5 +24,8 @@ public void testShowcase() { int size = 100; long ptr = hostEnv.memory().alloc(size); assertEquals(hostEnv.memory().length(ptr), size); + + + hostEnv.http().request() } } From d9216bf30657b1797695600480e07dd064c3e180 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Tue, 24 Dec 2024 12:31:15 +0100 Subject: [PATCH 5/6] add simple test case Signed-off-by: Edoardo Vacchi --- pom.xml | 7 ++- .../java/org/extism/chicory/sdk/HostEnv.java | 44 +++++++++++++------ .../org/extism/chicory/sdk/HostEnvTest.java | 26 ++++++++++- 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index c35f4a0..c98639d 100644 --- a/pom.xml +++ b/pom.xml @@ -109,7 +109,12 @@ ${jakarta.json-api.version} true - + + org.eclipse.parsson + jakarta.json + 1.1.7 + test + diff --git a/src/main/java/org/extism/chicory/sdk/HostEnv.java b/src/main/java/org/extism/chicory/sdk/HostEnv.java index bc23b9e..34c02dd 100644 --- a/src/main/java/org/extism/chicory/sdk/HostEnv.java +++ b/src/main/java/org/extism/chicory/sdk/HostEnv.java @@ -5,6 +5,7 @@ import com.dylibso.chicory.runtime.Instance; import com.dylibso.chicory.wasm.types.ValueType; import jakarta.json.Json; +import jakarta.json.JsonObject; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -14,6 +15,7 @@ import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -287,14 +289,14 @@ long[] request(Instance instance, long... args) { var requestJson = memory().readBytes(requestOffset); kernel.free.apply(requestOffset); - HttpRequest.BodyPublisher bodyPublisher; + byte[] requestBody; if (bodyOffset == 0) { - bodyPublisher = HttpRequest.BodyPublishers.noBody(); + requestBody = new byte[0]; } else { - var requestBody = memory().readBytes(bodyOffset); + requestBody = memory().readBytes(bodyOffset); kernel.free.apply(bodyOffset); - bodyPublisher = HttpRequest.BodyPublishers.ofByteArray(requestBody); } + var request = Json.createReader(new ByteArrayInputStream(requestJson)) .readObject(); @@ -302,6 +304,29 @@ long[] request(Instance instance, long... args) { var uri = URI.create(request.getJsonString("url").getString()); var headers = request.getJsonObject("headers"); + Map headersMap = new HashMap<>(); + for (var key : headers.keySet()) { + headersMap.put(key, headers.getString(key)); + } + + byte[] body = request(method, uri, headersMap, requestBody); + if (body.length == 0) { + result[0] = 0; + } else { + result[0] = memory().writeBytes(body); + } + + return result; + } + + byte[] request(String method, URI uri, Map headers, byte[] requestBody) { + HttpRequest.BodyPublisher bodyPublisher; + if (requestBody.length == 0) { + bodyPublisher = HttpRequest.BodyPublishers.noBody(); + } else { + bodyPublisher = HttpRequest.BodyPublishers.ofByteArray(requestBody); + } + var host = uri.getHost(); if (Arrays.stream(hostPatterns).anyMatch(p -> !p.matches(host))) { throw new ExtismException(String.format("HTTP request to '%s' is not allowed", host)); @@ -309,7 +334,7 @@ long[] request(Instance instance, long... args) { var reqBuilder = HttpRequest.newBuilder().uri(uri); for (var key : headers.keySet()) { - reqBuilder.header(key, headers.getString(key)); + reqBuilder.header(key, headers.get(key)); } var req = reqBuilder.method(method, bodyPublisher).build(); @@ -317,18 +342,11 @@ long[] request(Instance instance, long... args) { try { this.lastResponse = httpClient().send(req, HttpResponse.BodyHandlers.ofByteArray()); - byte[] body = lastResponse.body(); - if (body.length == 0) { - result[0] = 0; - } else { - result[0] = memory().writeBytes(lastResponse.body()); - } + return lastResponse.body(); } catch (IOException | InterruptedException e) { // FIXME gracefully handle the interruption throw new ExtismException(e); } - - return result; } long[] statusCode(Instance instance, long... args) { diff --git a/src/test/java/org/extism/chicory/sdk/HostEnvTest.java b/src/test/java/org/extism/chicory/sdk/HostEnvTest.java index 1f0a0f7..27e1511 100644 --- a/src/test/java/org/extism/chicory/sdk/HostEnvTest.java +++ b/src/test/java/org/extism/chicory/sdk/HostEnvTest.java @@ -1,8 +1,12 @@ package org.extism.chicory.sdk; import com.dylibso.chicory.log.SystemLogger; +import jakarta.json.Json; +import jakarta.json.JsonObject; import junit.framework.TestCase; +import java.io.ByteArrayInputStream; +import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Map; @@ -24,8 +28,28 @@ public void testShowcase() { int size = 100; long ptr = hostEnv.memory().alloc(size); assertEquals(hostEnv.memory().length(ptr), size); + } + + public void testHttp() { + var logger = new SystemLogger(); + var hostEnv = new HostEnv(new Kernel(), Map.of(), new String[0], logger); + + byte[] response = hostEnv.http().request( + "GET", + URI.create("http://httpbin.org/headers"), + Map.of("X-Custom-Header", "hello"), + new byte[0]); + JsonObject responseObject = Json.createReader(new ByteArrayInputStream(response)).readObject(); + assertEquals("hello", responseObject.getJsonObject("headers").getString("X-Custom-Header")); + + byte[] response2 = hostEnv.http().request( + "POST", + URI.create("http://httpbin.org/post"), + Map.of(), + "hello".getBytes(StandardCharsets.UTF_8)); - hostEnv.http().request() + JsonObject responseObject2 = Json.createReader(new ByteArrayInputStream(response2)).readObject(); + assertEquals("hello", responseObject2.getString("data")); } } From 7d01b61cb33f72e3e94614509adde4e2583d7525 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Tue, 24 Dec 2024 15:29:04 +0100 Subject: [PATCH 6/6] fix maven version Signed-off-by: Edoardo Vacchi --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c98639d..0baa0f6 100644 --- a/pom.xml +++ b/pom.xml @@ -73,6 +73,7 @@ 3.2.7 1.3.0 2.1.3 + 1.1.7 @@ -112,7 +113,7 @@ org.eclipse.parsson jakarta.json - 1.1.7 + ${jakarta.json.version} test