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
7 changes: 2 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,10 @@ all: build-go-examples build-rust-examples

.PHONY: build-go-examples
build-go-examples:
@find ./src/test/go-examples -mindepth 1 -type f -name "main.go" \
| xargs -I {} bash -c 'dirname {}' \
| xargs -I {} bash -c 'cd {} && env GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o main.wasm ./main.go'

@./proxy-wasm-java-host/src/test/go-examples/build.sh

.PHONY: build-rust-examples
build-rust-examples:
@find ./src/test/rust-examples -mindepth 1 -type f -name "Cargo.toml" \
@find ./proxy-wasm-java-host/src/test/rust-examples -mindepth 1 -type f -name "Cargo.toml" \
| xargs -I {} bash -c 'dirname {}' \
| xargs -I {} bash -c 'cd {} && cargo build --target wasm32-wasip1 --release; cp ./target/wasm32-wasip1/release/*.wasm ./main.wasm'
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import com.dylibso.chicory.runtime.HostFunction;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

Expand All @@ -28,6 +30,37 @@ public static byte[] bytes(String value) {
return value.getBytes(StandardCharsets.UTF_8);
}

public static byte[] bytes(Date value) {
// encode using
// https://protobuf.dev/reference/protobuf/google.protobuf/#timestamp
var instant = value.toInstant();
var rfc3339String = instant.toString();
return bytes(rfc3339String);
}

public static byte[] bytes(Duration value) {
// encode using
// https://protobuf.dev/reference/protobuf/google.protobuf/#duration
return bytes(String.format("%d.%09d", value.getSeconds(), value.getNano()));
}

public static byte[] bytes(int value) {
// TODO: test to check byte order
return new byte[] {
(byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value
};
}

public static int int32(byte[] bytes) {
if (bytes == null || bytes.length != 4) {
throw new IllegalArgumentException("Byte array must be exactly 4 bytes long");
}
return ((bytes[0] & 0xFF) << 24)
| ((bytes[1] & 0xFF) << 16)
| ((bytes[2] & 0xFF) << 8)
| (bytes[3] & 0xFF);
}

public static String string(byte[] value) {
return new String(value, StandardCharsets.UTF_8);
}
Expand Down Expand Up @@ -143,4 +176,6 @@ public static byte[] replaceBytes(

return result;
}

static final int U32_LEN = 4;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package io.roastedroot.proxywasm;

import static io.roastedroot.proxywasm.Helpers.bytes;
import static io.roastedroot.proxywasm.Helpers.len;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

public interface ProxyMap {
Expand Down Expand Up @@ -33,4 +40,39 @@ static ProxyMap copyOf(Map<String, String> headers) {
String get(String key);

void remove(String key);

/**
* Encode the map into a byte array.
*/
default byte[] encode() {
try {
var baos = new ByteArrayOutputStream();
var o = new DataOutputStream(baos);
// Write header size (number of entries)
int mapSize = this.size();
o.writeInt(mapSize);

// write all the key / value sizes.
ArrayList<Map.Entry<byte[], byte[]>> entries = new ArrayList<>(this.size());
for (var entry : this.entries()) {
var encoded = Map.entry(bytes(entry.getKey()), bytes(entry.getValue()));
entries.add(encoded);
o.writeInt(len(encoded.getKey()));
o.writeInt(len(encoded.getValue()));
}

// write all the key / values
for (var entry : entries) {
o.write(entry.getKey());
o.write(0);
o.write(entry.getValue());
o.write(0);
}
o.close();
return baos.toByteArray();
} catch (IOException e) {
// this should never happen since we are not really doing IO
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Holds constants for the well-known properties defined by the Proxy-Wasm ABI.
*
* see: <a href="https://github.com/proxy-wasm/spec/tree/main/abi-versions/v0.1.0#well-known-properties">spec</a>
* seeL <a href="https://www.envoyproxy.io/docs/envoy/v1.33.0/intro/arch_overview/advanced/attributes">envoy docs</a>
*/
public final class WellKnownProperties {
private WellKnownProperties() {}
Expand All @@ -16,59 +17,92 @@ private WellKnownProperties() {}
public static final List<String> PLUGIN_VM_ID = List.of("plugin_vm_id");

// Downstream connection properties
public static final List<String> CONNECTION_ID = List.of("connection.id");
public static final List<String> SOURCE_ADDRESS = List.of("source.address");
public static final List<String> SOURCE_PORT = List.of("source.port");
public static final List<String> DESTINATION_ADDRESS = List.of("destination.address");
public static final List<String> DESTINATION_PORT = List.of("destination.port");
public static final List<String> CONNECTION_TLS_VERSION = List.of("connection.tls_version");
public static final List<String> CONNECTION_ID = List.of("connection", "id");
public static final List<String> SOURCE_ADDRESS = List.of("source", "address");
public static final List<String> SOURCE_PORT = List.of("source", "port");
public static final List<String> DESTINATION_ADDRESS = List.of("destination", "address");
public static final List<String> DESTINATION_PORT = List.of("destination", "port");
public static final List<String> CONNECTION_TLS_VERSION = List.of("connection", "tls_version");
public static final List<String> CONNECTION_REQUESTED_SERVER_NAME =
List.of("connection.requested_server_name");
public static final List<String> CONNECTION_MTLS = List.of("connection.mtls");
List.of("connection", "requested_server_name");
public static final List<String> CONNECTION_MTLS = List.of("connection", "mtls");
public static final List<String> CONNECTION_SUBJECT_LOCAL_CERTIFICATE =
List.of("connection.subject_local_certificate");
List.of("connection", "subject_local_certificate");
public static final List<String> CONNECTION_SUBJECT_PEER_CERTIFICATE =
List.of("connection.subject_peer_certificate");
List.of("connection", "subject_peer_certificate");
public static final List<String> CONNECTION_DNS_SAN_LOCAL_CERTIFICATE =
List.of("connection.dns_san_local_certificate");
List.of("connection", "dns_san_local_certificate");
public static final List<String> CONNECTION_DNS_SAN_PEER_CERTIFICATE =
List.of("connection.dns_san_peer_certificate");
List.of("connection", "dns_san_peer_certificate");
public static final List<String> CONNECTION_URI_SAN_LOCAL_CERTIFICATE =
List.of("connection.uri_san_local_certificate");
List.of("connection", "uri_san_local_certificate");
public static final List<String> CONNECTION_URI_SAN_PEER_CERTIFICATE =
List.of("connection.uri_san_peer_certificate");
List.of("connection", "uri_san_peer_certificate");
public static final List<String> CONNECTION_SHA256_PEER_CERTIFICATE_DIGEST =
List.of("connection.sha256_peer_certificate_digest");
List.of("connection", "sha256_peer_certificate_digest");

// Upstream connection properties
public static final List<String> UPSTREAM_ADDRESS = List.of("upstream.address");
public static final List<String> UPSTREAM_PORT = List.of("upstream.port");
public static final List<String> UPSTREAM_LOCAL_ADDRESS = List.of("upstream.local_address");
public static final List<String> UPSTREAM_LOCAL_PORT = List.of("upstream.local_port");
public static final List<String> UPSTREAM_TLS_VERSION = List.of("upstream.tls_version");
public static final List<String> UPSTREAM_ADDRESS = List.of("upstream", "address");
public static final List<String> UPSTREAM_PORT = List.of("upstream", "port");
public static final List<String> UPSTREAM_LOCAL_ADDRESS = List.of("upstream", "local_address");
public static final List<String> UPSTREAM_LOCAL_PORT = List.of("upstream", "local_port");
public static final List<String> UPSTREAM_TLS_VERSION = List.of("upstream", "tls_version");
public static final List<String> UPSTREAM_SUBJECT_LOCAL_CERTIFICATE =
List.of("upstream.subject_local_certificate");
List.of("upstream", "subject_local_certificate");
public static final List<String> UPSTREAM_SUBJECT_PEER_CERTIFICATE =
List.of("upstream.subject_peer_certificate");
List.of("upstream", "subject_peer_certificate");
public static final List<String> UPSTREAM_DNS_SAN_LOCAL_CERTIFICATE =
List.of("upstream.dns_san_local_certificate");
List.of("upstream", "dns_san_local_certificate");
public static final List<String> UPSTREAM_DNS_SAN_PEER_CERTIFICATE =
List.of("upstream.dns_san_peer_certificate");
List.of("upstream", "dns_san_peer_certificate");
public static final List<String> UPSTREAM_URI_SAN_LOCAL_CERTIFICATE =
List.of("upstream.uri_san_local_certificate");
List.of("upstream", "uri_san_local_certificate");
public static final List<String> UPSTREAM_URI_SAN_PEER_CERTIFICATE =
List.of("upstream.uri_san_peer_certificate");
List.of("upstream", "uri_san_peer_certificate");
public static final List<String> UPSTREAM_SHA256_PEER_CERTIFICATE_DIGEST =
List.of("upstream.sha256_peer_certificate_digest");
List.of("upstream", "sha256_peer_certificate_digest");
public static final List<String> UPSTREAM_TRANSPORT_FAILURE_REASON =
List.of("upstream", "transport_failure_reason");
public static final List<String> UPSTREAM_REQUEST_ATTEMPT_COUNT =
List.of("upstream", "request_attempt_count");
public static final List<String> UPSTREAM_CX_POOL_READY_DURATION =
List.of("upstream", "cx_pool_ready_duration");

// Metadata and filter state properties
public static final List<String> METADATA = List.of("metadata");
public static final List<String> FILTER_STATE = List.of("filter_state");
public static final List<String> UPSTREAM_FILTER_STATE = List.of("upstream_filter_state");

// HTTP request properties
public static final List<String> REQUEST_PROTOCOL = List.of("request.protocol");
public static final List<String> REQUEST_TIME = List.of("request.time");
public static final List<String> REQUEST_DURATION = List.of("request.duration");
public static final List<String> REQUEST_SIZE = List.of("request.size");
public static final List<String> REQUEST_TOTAL_SIZE = List.of("request.total_size");
public static final List<String> REQUEST_PROTOCOL = List.of("request", "protocol");
public static final List<String> REQUEST_TIME = List.of("request", "time");

public static final List<String> REQUEST_PATH = List.of("request", "path");
public static final List<String> REQUEST_URL_PATH = List.of("request", "url_path");
public static final List<String> REQUEST_HOST = List.of("request", "host");
public static final List<String> REQUEST_SCHEME = List.of("request", "scheme");
public static final List<String> REQUEST_METHOD = List.of("request", "method");
public static final List<String> REQUEST_HEADERS = List.of("request", "headers");
public static final List<String> REQUEST_REFERER = List.of("request", "referer");
public static final List<String> REQUEST_USERAGENT = List.of("request", "useragent");
public static final List<String> REQUEST_ID = List.of("request", "id");
public static final List<String> REQUEST_QUERY = List.of("request", "query");

// These properties are available once the request completes:
public static final List<String> REQUEST_DURATION = List.of("request", "duration");
public static final List<String> REQUEST_SIZE = List.of("request", "size");
public static final List<String> REQUEST_TOTAL_SIZE = List.of("request", "total_size");

// HTTP response properties
public static final List<String> RESPONSE_SIZE = List.of("response.size");
public static final List<String> RESPONSE_TOTAL_SIZE = List.of("response.total_size");
public static final List<String> RESPONSE_SIZE = List.of("response", "size");
public static final List<String> RESPONSE_TOTAL_SIZE = List.of("response", "total_size");

public static final List<String> RESPONSE_CODE = List.of("response", "code");
public static final List<String> RESPONSE_CODE_DETAILS = List.of("response", "code_details");
public static final List<String> RESPONSE_FLAGS = List.of("response", "flags");
public static final List<String> RESPONSE_GRPC_STATUS = List.of("response", "grpc_status");
public static final List<String> RESPONSE_HEADERS = List.of("response", "headers");
public static final List<String> RESPONSE_TRAILERS = List.of("response", "trailers");
public static final List<String> RESPONSE_BACKEND_LATENCY =
List.of("response", "backend_latency");
}
11 changes: 11 additions & 0 deletions proxy-wasm-java-host/src/test/go-examples/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh

docker run -it --rm \
-v `pwd`:/src \
--workdir /src \
-e GOOS=wasip1 \
-e GOARCH=wasm golang:1.24-alpine sh -c "
find . -mindepth 1 -type f -name 'main.go' \
| xargs -I {} sh -c 'dirname {}' \
| xargs -I {} sh -c 'cd {} && GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o main.wasm ./main.go'
"
Binary file not shown.
Binary file not shown.
Binary file modified proxy-wasm-java-host/src/test/go-examples/helloworld/main.wasm
Binary file not shown.
Binary file not shown.
Binary file modified proxy-wasm-java-host/src/test/go-examples/http_body/main.wasm
Binary file not shown.
Binary file not shown.
21 changes: 15 additions & 6 deletions proxy-wasm-java-host/src/test/go-examples/http_headers/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package main

import (
"fmt"
"strings"

"github.com/proxy-wasm/proxy-wasm-go-sdk/proxywasm"
Expand Down Expand Up @@ -49,14 +50,16 @@ type pluginContext struct {
// plugin configuration during OnPluginStart.
headerName string
headerValue string
counter int
}

// NewHttpContext implements types.PluginContext.
func (p *pluginContext) NewHttpContext(contextID uint32) types.HttpContext {
return &httpHeaders{
contextID: contextID,
headerName: p.headerName,
headerValue: p.headerValue,
contextID: contextID,
pluginContext: p,
headerName: p.headerName,
headerValue: p.headerValue,
}
}

Expand Down Expand Up @@ -96,9 +99,10 @@ type httpHeaders struct {
// Embed the default http context here,
// so that we don't need to reimplement all the methods.
types.DefaultHttpContext
contextID uint32
headerName string
headerValue string
contextID uint32
headerName string
headerValue string
pluginContext *pluginContext
}

// OnHttpRequestHeaders implements types.HttpContext.
Expand Down Expand Up @@ -128,6 +132,11 @@ func (ctx *httpHeaders) OnHttpResponseHeaders(_ int, _ bool) types.Action {
proxywasm.LogCriticalf("failed to set response constant header: %v", err)
}

ctx.pluginContext.counter++
if err := proxywasm.AddHttpResponseHeader("x-proxy-wasm-counter", fmt.Sprintf("%d", ctx.pluginContext.counter)); err != nil {
proxywasm.LogCriticalf("failed to set response counter header: %v", err)
}

// Add the header passed by arguments
if ctx.headerName != "" {
if err := proxywasm.AddHttpResponseHeader(ctx.headerName, ctx.headerValue); err != nil {
Expand Down
Binary file modified proxy-wasm-java-host/src/test/go-examples/http_headers/main.wasm
Binary file not shown.
Binary file modified proxy-wasm-java-host/src/test/go-examples/http_routing/main.wasm
Binary file not shown.
Binary file not shown.
Binary file modified proxy-wasm-java-host/src/test/go-examples/metrics/main.wasm
Binary file not shown.
Binary file not shown.
Binary file modified proxy-wasm-java-host/src/test/go-examples/network/main.wasm
Binary file not shown.
Binary file not shown.
Binary file modified proxy-wasm-java-host/src/test/go-examples/properties/main.wasm
Binary file not shown.
Binary file modified proxy-wasm-java-host/src/test/go-examples/shared_data/main.wasm
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public void onHttpResponseHeaders() throws StartException {
"key1", "value1",
"key2", "value2",
"x-proxy-wasm-go-sdk-example", "http_headers",
"x-proxy-wasm-counter", "1",
"x-wasm-header", "x-value"),
handler.getHttpResponseHeaders());

Expand All @@ -85,6 +86,7 @@ public void onHttpResponseHeaders() throws StartException {
"response header <-- key1: value1",
"adding header: x-wasm-header=x-value",
"response header <-- x-wasm-header: x-value",
"response header <-- x-proxy-wasm-counter: 1",
"response header <-- x-proxy-wasm-go-sdk-example: http_headers");
}
}
Expand Down
Loading