Skip to content
Merged
Show file tree
Hide file tree
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
50 changes: 50 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.extism.sdk</groupId>
<artifactId>chicory-sdk</artifactId>
<version>999-SNAPSHOT</version>
</parent>

<artifactId>chicory-sdk-core</artifactId>

<dependencies>
<dependency>
<groupId>com.dylibso.chicory</groupId>
<artifactId>runtime</artifactId>
<version>${chicory.version}</version>
</dependency>
<dependency>
<groupId>com.dylibso.chicory</groupId>
<artifactId>wasi</artifactId>
<version>${chicory.version}</version>
</dependency>
<dependency>
<groupId>com.dylibso.chicory</groupId>
<artifactId>compiler</artifactId>
<version>1.4.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.extism.sdk</groupId>
<artifactId>http-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.jimfs</groupId>
<artifactId>jimfs</artifactId>
<version>${jimfs.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.extism.sdk.chicory;

public class ExtismConfigurationException extends ExtismException {

public ExtismConfigurationException(String message) {
super(message);
}

public ExtismConfigurationException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@
import com.dylibso.chicory.runtime.Instance;
import com.dylibso.chicory.wasm.types.FunctionType;
import com.dylibso.chicory.wasm.types.ValType;
import org.extism.sdk.chicory.http.ExtismHttpException;
import org.extism.sdk.chicory.http.HttpClientAdapter;
import org.extism.sdk.chicory.http.HttpConfig;
import org.extism.sdk.chicory.http.HttpJsonCodec;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

public class HostEnv {

Expand All @@ -31,7 +34,7 @@ public HostEnv(Kernel kernel, ConfigProvider config, String[] allowedHosts, Http
this.config = new Config(config);
this.var = new Var();
this.log = new Log();
this.http = new Http(allowedHosts, httpConfig);
this.http = httpConfig == null ? null : new Http(allowedHosts, httpConfig);
}

public Log log() {
Expand All @@ -47,6 +50,12 @@ public Config config() {
}

public Http http() {
if (http == null) {
throw new ExtismConfigurationException(
"Http has not been configured properly. " +
"Verify you have added a dependency to the JSON deserializer (default: Jackson Databind) " +
"and the correct HttpConfig implementation.");
}
return http;
}

Expand All @@ -56,7 +65,7 @@ public HostFunction[] toHostFunctions() {
log.toHostFunctions(),
var.toHostFunctions(),
config.toHostFunctions(),
http.toHostFunctions());
http == null ? new HostFunction[0] : http.toHostFunctions());
}

private HostFunction[] concat(HostFunction[]... hfs) {
Expand Down Expand Up @@ -274,11 +283,12 @@ HostFunction[] toHostFunctions() {

}


public class Http {

private final HostPattern[] hostPatterns;
Lazy<HttpJsonCodec> jsonCodec;
Lazy<HttpClientAdapter> clientAdapter;
HttpJsonCodec jsonCodec;
HttpClientAdapter clientAdapter;

public Http(String[] allowedHosts, HttpConfig httpConfig) {
if (allowedHosts == null) {
Expand All @@ -288,16 +298,8 @@ public Http(String[] allowedHosts, HttpConfig httpConfig) {
for (int i = 0; i < allowedHosts.length; i++) {
this.hostPatterns[i] = new HostPattern(allowedHosts[i]);
}
this.jsonCodec = new Lazy<>(httpConfig.httpJsonCodec);
this.clientAdapter = new Lazy<>(httpConfig.httpClientAdapter);
}

public HttpJsonCodec jsonCodec() {
return jsonCodec.get();
}

public HttpClientAdapter clientAdapter() {
return clientAdapter.get();
this.jsonCodec = httpConfig.httpJsonCodec().get();
this.clientAdapter = httpConfig.httpClientAdapter().get();
}

long[] request(Instance instance, long... args) {
Expand All @@ -317,7 +319,7 @@ long[] request(Instance instance, long... args) {
kernel.free.apply(bodyOffset);
}

var requestMetadata = jsonCodec().decodeMetadata(requestJson);
var requestMetadata = jsonCodec.decodeMetadata(requestJson);

byte[] body = request(
requestMetadata.method(),
Expand All @@ -334,7 +336,7 @@ long[] request(Instance instance, long... args) {
return result;
}

byte[] request(String method, URI uri, Map<String, String> headers, byte[] requestBody) {
public byte[] request(String method, URI uri, Map<String, String> headers, byte[] requestBody) {
var host = uri.getHost();
if (host == null || host.isBlank()) {
throw new ExtismHttpException("HTTP request host is invalid for URI: " + uri);
Expand All @@ -343,24 +345,24 @@ byte[] request(String method, URI uri, Map<String, String> headers, byte[] reque
throw new ExtismHttpException(String.format("HTTP request to '%s' is not allowed", host));
}

return clientAdapter().request(method, uri, headers, requestBody);
return clientAdapter.request(method, uri, headers, requestBody);
}

long[] statusCode(Instance instance, long... args) {
return new long[]{statusCode()};
}

int statusCode() {
return clientAdapter().statusCode();
public int statusCode() {
return clientAdapter.statusCode();
}

long[] headers(Instance instance, long[] longs) {
var result = new long[1];
var headers = clientAdapter().headers();
var headers = clientAdapter.headers();
if (headers == null) {
return result;
}
var bytes = jsonCodec().encodeHeaders(Map.of());
var bytes = jsonCodec.encodeHeaders(Map.of());
result[0] = memory().writeBytes(bytes);
return result;
}
Expand Down Expand Up @@ -415,28 +417,4 @@ public boolean matches(String host) {
}
}

private static final class Lazy<T> {

final Supplier<T> supplier;
T t;

public Lazy(Supplier<T> supplier) {
this.supplier = supplier;
}

public T get() {
if (t == null) {
try {
t = supplier.get();
} catch (NoClassDefFoundError error) {
throw new ConfigurationException(
"Http has not been configured properly. "
+ "Verify you have added a dependency to the JSON deserializer (default: Jackson Databind) "
+ "and you have have configure the HTTP client properly (default: java.net.http.HttpClient)", error);
}
}
return t;
}
}

}
16 changes: 16 additions & 0 deletions core/src/main/java/org/extism/sdk/chicory/HttpClientAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.extism.sdk.chicory;

import java.net.URI;
import java.util.List;
import java.util.Map;

/**
* @deprecated instead use <code>org.extism.sdk.chicory.http.HttpClientAdapter</code>
* in <code>org.extism.sdk:http-api</code>
*/
@Deprecated(forRemoval = true)
public interface HttpClientAdapter {
byte[] request(String method, URI url, Map<String, String> headers, byte[] requestBody);
int statusCode();
Map<String, List<String>> headers();
}
69 changes: 69 additions & 0 deletions core/src/main/java/org/extism/sdk/chicory/HttpConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.extism.sdk.chicory;

import java.util.Objects;
import java.util.function.Supplier;

@Deprecated(forRemoval = true)
public class HttpConfig {
/**
* @deprecated instead use <code>org.extism.sdk.chicory.http.config.generic.GenericHttpConfig</code>
* in <code>org.extism.sdk:http-config-generic</code>
*/
@Deprecated(forRemoval = true)
public static HttpConfig defaultConfig() {
throw new UnsupportedOperationException(
"Deprecated for removal, instead use `org.extism.sdk.chicory.http.config.generic.GenericHttpConfig` " +
"in `org.extism.sdk:http-config-generic`");
}

/**
* @deprecated instead use <code>org.extism.sdk.chicory.http.config.android.AndroidHttpConfig</code>
* in <code>org.extism.sdk:http-config-android</code>
*/
@Deprecated(forRemoval = true)
public static HttpConfig urlConnectionConfig() {
throw new UnsupportedOperationException(
"Deprecated for removal, instead use `org.extism.sdk.chicory.http.config.android.AndroidHttpConfig` " +
"in `org.extism.sdk:http-config-android`");
}

@Deprecated(forRemoval = true)
public static Builder builder() {
throw new UnsupportedOperationException(
"Deprecated for removal, instead use `org.extism.sdk.chicory.http.HttpConfig.builder()` " +
"in `org.extism.sdk:http-api`");

}

@Deprecated(forRemoval = true)
public static class Builder {
Supplier<HttpJsonCodec> httpJsonCodec;
Supplier<HttpClientAdapter> httpClientAdapter;

private Builder() {}

public Builder withJsonCodec(Supplier<HttpJsonCodec> httpJsonCodecFactory) {
this.httpJsonCodec = httpJsonCodecFactory;
return this;
}

public Builder withClientAdapter(Supplier<HttpClientAdapter> httpClientAdapterFactory) {
this.httpClientAdapter = httpClientAdapterFactory;
return this;
}

public HttpConfig build() {
Objects.requireNonNull(httpJsonCodec, "httpJsonCodec is required");
Objects.requireNonNull(httpClientAdapter, "httpClientAdapter is required");
return new HttpConfig(httpJsonCodec, httpClientAdapter);
}
}

@Deprecated(forRemoval = true)
public HttpConfig(Supplier<HttpJsonCodec> httpJsonCodec, Supplier<HttpClientAdapter> httpClientAdapter) {
throw new UnsupportedOperationException(
"Deprecated for removal, instead use `org.extism.sdk.chicory.http.config.generic.GenericHttpConfig` " +
"in `org.extism.sdk:http-config-generic`");
}

}
22 changes: 22 additions & 0 deletions core/src/main/java/org/extism/sdk/chicory/HttpJsonCodec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.extism.sdk.chicory;

import java.net.URI;
import java.util.List;
import java.util.Map;

/**
* @deprecated instead use <code>org.extism.sdk.chicory.http.HttpJsonCodec</code>
* in <code>org.extism.sdk:http-api</code>
*/
@Deprecated(forRemoval = true)
public interface HttpJsonCodec {
@Deprecated(forRemoval = true)
interface RequestMetadata {
String method();
URI uri();
Map<String, String> headers();
}

RequestMetadata decodeMetadata(byte[] data);
byte[] encodeHeaders(Map<String, List<String>> headers);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.extism.sdk.chicory;

import java.net.URI;
import java.util.Map;

/**
* @deprecated instead use <code>org.extism.sdk.chicory.http.client.urlconnection.HttpUrlConnectionClientAdapter</code>
* in <code>org.extism.sdk:http-client-urlconnection</code>
*/
@Deprecated(forRemoval = true)
public class HttpUrlConnectionClientAdapter implements HttpClientAdapter {

public HttpUrlConnectionClientAdapter() {
throw new UnsupportedOperationException(
"Deprecated for removal, instead use `org.extism.sdk.chicory.http.client.urlconnection.HttpUrlConnectionClientAdapter` " +
"in `org.extism.sdk:http-client-urlconnection`");
}

public byte[] request(String method, URI uri, Map<String, String> headers, byte[] requestBody) {
throw new UnsupportedOperationException(
"Deprecated for removal, instead use `org.extism.sdk.chicory.http.client.urlconnection.HttpUrlConnectionClientAdapter` " +
"in `org.extism.sdk:http-client-urlconnection`");
}

public int statusCode() {
throw new UnsupportedOperationException(
"Deprecated for removal, instead use `org.extism.sdk.chicory.http.client.urlconnection.HttpUrlConnectionClientAdapter` " +
"in `org.extism.sdk:http-client-urlconnection`");
}

public Map<String, java.util.List<String>> headers() {
throw new UnsupportedOperationException(
"Deprecated for removal, instead use `org.extism.sdk.chicory.http.client.urlconnection.HttpUrlConnectionClientAdapter` " +
"in `org.extism.sdk:http-client-urlconnection`");
}

}
Loading