From 3a127b61f0715674e2a2f57e3599e86111089966 Mon Sep 17 00:00:00 2001 From: Hiram Chirino Date: Mon, 17 Mar 2025 11:47:32 -0400 Subject: [PATCH] Implement gRPC ABI, add rust hello_world example and test. Signed-off-by: Hiram Chirino --- .gitignore | 3 + Makefile | 15 + .../java/io/roastedroot/proxywasm/ABI.java | 157 ++++++- .../roastedroot/proxywasm/ChainedHandler.java | 45 ++ .../io/roastedroot/proxywasm/Handler.java | 33 ++ .../examples/RustHelloWorldTest.java | 28 ++ src/test/rust-examples/hello_world/Cargo.lock | 418 ++++++++++++++++++ src/test/rust-examples/hello_world/Cargo.toml | 27 ++ src/test/rust-examples/hello_world/README.md | 5 + src/test/rust-examples/hello_world/main.wasm | Bin 0 -> 166993 bytes src/test/rust-examples/hello_world/src/lib.rs | 52 +++ 11 files changed, 767 insertions(+), 16 deletions(-) create mode 100644 src/test/java/io/roastedroot/proxywasm/examples/RustHelloWorldTest.java create mode 100644 src/test/rust-examples/hello_world/Cargo.lock create mode 100644 src/test/rust-examples/hello_world/Cargo.toml create mode 100644 src/test/rust-examples/hello_world/README.md create mode 100755 src/test/rust-examples/hello_world/main.wasm create mode 100644 src/test/rust-examples/hello_world/src/lib.rs diff --git a/.gitignore b/.gitignore index c72de14..4ad458a 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,6 @@ build/ ### Mac OS ### .DS_Store + +### Rust ### +target/ diff --git a/Makefile b/Makefile index 11be792..2e73f8c 100755 --- a/Makefile +++ b/Makefile @@ -3,9 +3,24 @@ # # $ make build-go-examples # +# To build the Rust examples, install rustup and cargo install the wasm target with run `rustup target add wasm32-wasip1` +# and then run: +# +# $ make build-rust-examples +# + +.PHONY: all +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' + + +.PHONY: build-rust-examples +build-rust-examples: + @find ./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' diff --git a/src/main/java/io/roastedroot/proxywasm/ABI.java b/src/main/java/io/roastedroot/proxywasm/ABI.java index cd8a762..5fff8a1 100644 --- a/src/main/java/io/roastedroot/proxywasm/ABI.java +++ b/src/main/java/io/roastedroot/proxywasm/ABI.java @@ -1107,10 +1107,24 @@ int proxyContinueStream(int arg) { return result.getValue(); } - // TODO: implement - // https://github.com/proxy-wasm/spec/tree/main/abi-versions/v0.2.1#proxy_close_stream - // TODO: implement - // https://github.com/proxy-wasm/spec/tree/main/abi-versions/v0.2.1#proxy_get_status + /** + * implements: https://github.com/proxy-wasm/spec/tree/main/abi-versions/v0.2.1#proxy_close_stream + */ + @WasmExport + int proxyCloseStream(int proxyStreamType) { + // TODO: implement + return WasmResult.UNIMPLEMENTED.getValue(); + } + + /** + * implements: https://github.com/proxy-wasm/spec/tree/main/abi-versions/v0.2.1#proxy_get_status + */ + @WasmExport + int proxyGetStatus( + int returnStatusCode, int returnStatusMessageData, int returnStatusMessageSize) { + // TODO: implement + return WasmResult.UNIMPLEMENTED.getValue(); + } // ////////////////////////////////////////////////////////////////////// // TCP streams @@ -1421,16 +1435,109 @@ void proxyOnHttpCallResponse(int arg0, int arg1, int arg2, int arg3, int arg4) { // gRPC calls // ////////////////////////////////////////////////////////////////////// - // TODO: implement - // https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_call - // TODO: implement - // https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_stream - // TODO: implement - // https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_send - // TODO: implement - // https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_cancel - // TODO: implement - // https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_close + /** + * implements https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_call + */ + @WasmExport + int proxyGrpcCall( + int upstreamNameData, + int upstreamNameSize, + int serviceNameData, + int serviceNameSize, + int methodNameData, + int methodNameSize, + int serialized_initial_metadataData, + int serialized_initial_metadataSize, + int messageData, + int messageSize, + int timeout, + int returnCalloutID) { + + try { + var upstreamName = string(readMemory(upstreamNameData, upstreamNameSize)); + var serviceName = string(readMemory(serviceNameData, serviceNameSize)); + var methodName = string(readMemory(methodNameData, methodNameSize)); + var initialMetadata = + decodeMap(serialized_initial_metadataData, serialized_initial_metadataSize); + var message = readMemory(messageData, messageSize); + + int callId = + handler.grpcCall( + upstreamName, + serviceName, + methodName, + initialMetadata, + message, + timeout); + putUint32(returnCalloutID, callId); + return callId; + } catch (WasmException e) { + return e.result().getValue(); + } + } + + /** + * implements https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_stream + */ + @WasmExport + int proxyGrpcStream( + int upstreamNameData, + int upstreamNameSize, + int serviceNameData, + int serviceNameSize, + int methodNameData, + int methodNameSize, + int serialized_initial_metadataData, + int serialized_initial_metadataSize, + int returnStreamId) { + + try { + var upstreamName = string(readMemory(upstreamNameData, upstreamNameSize)); + var serviceName = string(readMemory(serviceNameData, serviceNameSize)); + var methodName = string(readMemory(methodNameData, methodNameSize)); + var initialMetadata = + decodeMap(serialized_initial_metadataData, serialized_initial_metadataSize); + + int streamId = + handler.grpcStream(upstreamName, serviceName, methodName, initialMetadata); + putUint32(returnStreamId, streamId); + return streamId; + } catch (WasmException e) { + return e.result().getValue(); + } + } + + /** + * https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_send + */ + @WasmExport + int proxyGrpcSend(int streamId, int messageData, int messageSize, int endStream) { + try { + byte[] message = readMemory(messageData, messageSize); + WasmResult result = handler.grpcSend(streamId, message, endStream); + return result.getValue(); + } catch (WasmException e) { + return e.result().getValue(); + } + } + + /** + * https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_cancel + */ + @WasmExport + int proxyGrpcCancel(int callOrstreamId) { + WasmResult result = handler.grpcCancel(callOrstreamId); + return result.getValue(); + } + + /** + * https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_grpc_close + */ + @WasmExport + int proxyGrpcClose(int callOrstreamId) { + WasmResult result = handler.grpcClose(callOrstreamId); + return result.getValue(); + } /** * implements https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_on_grpc_receive_initial_metadata @@ -1720,8 +1827,26 @@ int proxyGetProperty(int keyPtr, int keySize, int returnValueData, int returnVal } } - // TODO: implement - // https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_set_property + /** + * https://github.com/proxy-wasm/spec/tree/main/abi-versions/vNEXT#proxy_set_property + */ + @WasmExport + int proxySetProperty(int pathDataPtr, int pathSize, int valueDataPtr, int valueSize) { + try { + // Get key from memory + String path = string(readMemory(pathDataPtr, pathSize)); + + // Get value from memory + String value = string(readMemory(valueDataPtr, valueSize)); + + // Set property value using handler + WasmResult result = handler.setProperty(path, value); + return result.getValue(); + + } catch (WasmException e) { + return e.result().getValue(); + } + } // ////////////////////////////////////////////////////////////////////// // Foreign function interface (FFI) diff --git a/src/main/java/io/roastedroot/proxywasm/ChainedHandler.java b/src/main/java/io/roastedroot/proxywasm/ChainedHandler.java index 23b13aa..255eef2 100644 --- a/src/main/java/io/roastedroot/proxywasm/ChainedHandler.java +++ b/src/main/java/io/roastedroot/proxywasm/ChainedHandler.java @@ -318,4 +318,49 @@ public byte[] dequeueSharedQueue(int queueId) throws WasmException { public WasmResult enqueueSharedQueue(int queueId, byte[] value) { return next().enqueueSharedQueue(queueId, value); } + + @Override + public LogLevel getLogLevel() throws WasmException { + return next().getLogLevel(); + } + + @Override + public WasmResult setProperty(String path, String value) { + return next().setProperty(path, value); + } + + @Override + public int grpcCall( + String upstreamName, + String serviceName, + String methodName, + ProxyMap initialMetadata, + byte[] message, + int timeout) + throws WasmException { + return next().grpcCall( + upstreamName, serviceName, methodName, initialMetadata, message, timeout); + } + + @Override + public int grpcStream( + String upstreamName, String serviceName, String methodName, ProxyMap initialMetadata) + throws WasmException { + return next().grpcStream(upstreamName, serviceName, methodName, initialMetadata); + } + + @Override + public WasmResult grpcSend(int streamId, byte[] message, int endStream) { + return next().grpcSend(streamId, message, endStream); + } + + @Override + public WasmResult grpcCancel(int callOrstreamId) { + return next().grpcCancel(callOrstreamId); + } + + @Override + public WasmResult grpcClose(int callOrstreamId) { + return next().grpcClose(callOrstreamId); + } } diff --git a/src/main/java/io/roastedroot/proxywasm/Handler.java b/src/main/java/io/roastedroot/proxywasm/Handler.java index e4160d7..73594db 100644 --- a/src/main/java/io/roastedroot/proxywasm/Handler.java +++ b/src/main/java/io/roastedroot/proxywasm/Handler.java @@ -49,6 +49,10 @@ default String getProperty(String key) throws WasmException { return null; } + default WasmResult setProperty(String path, String value) { + return WasmResult.UNIMPLEMENTED; + } + /** * Get the HTTP request body. * @@ -420,6 +424,35 @@ default long getMetric(int metricId) throws WasmException { throw new WasmException(WasmResult.UNIMPLEMENTED); } + default int grpcCall( + String upstreamName, + String serviceName, + String methodName, + ProxyMap initialMetadata, + byte[] message, + int timeout) + throws WasmException { + throw new WasmException(WasmResult.UNIMPLEMENTED); + } + + default int grpcStream( + String upstreamName, String serviceName, String methodName, ProxyMap initialMetadata) + throws WasmException { + throw new WasmException(WasmResult.UNIMPLEMENTED); + } + + default WasmResult grpcSend(int streamId, byte[] message, int endStream) { + return WasmResult.UNIMPLEMENTED; + } + + default WasmResult grpcCancel(int callOrstreamId) { + return WasmResult.UNIMPLEMENTED; + } + + default WasmResult grpcClose(int callOrstreamId) { + return WasmResult.UNIMPLEMENTED; + } + class SharedData { public byte[] data; public int cas; diff --git a/src/test/java/io/roastedroot/proxywasm/examples/RustHelloWorldTest.java b/src/test/java/io/roastedroot/proxywasm/examples/RustHelloWorldTest.java new file mode 100644 index 0000000..a2103cf --- /dev/null +++ b/src/test/java/io/roastedroot/proxywasm/examples/RustHelloWorldTest.java @@ -0,0 +1,28 @@ +package io.roastedroot.proxywasm.examples; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.dylibso.chicory.wasm.Parser; +import io.roastedroot.proxywasm.ProxyWasm; +import io.roastedroot.proxywasm.StartException; +import java.nio.file.Path; +import org.junit.jupiter.api.Test; + +/** + * Test loading https://github.com/proxy-wasm/proxy-wasm-rust-sdk/tree/c8b2335df66a569a6306c58e346dd0cf9dbc0f3a/examples/hello_world + */ +public class RustHelloWorldTest { + + @Test + public void pauseUntilEOS() throws StartException { + var handler = new MockHandler(); + var module = Parser.parse(Path.of("./src/test/rust-examples/hello_world/main.wasm")); + try (var host = ProxyWasm.builder().withPluginHandler(handler).build(module)) { + + handler.assertLogsEqual("Hello, World!"); + host.tick(); + + assertTrue(handler.loggedMessages().get(1).contains("your lucky number is")); + } + } +} diff --git a/src/test/rust-examples/hello_world/Cargo.lock b/src/test/rust-examples/hello_world/Cargo.lock new file mode 100644 index 0000000..9280868 --- /dev/null +++ b/src/test/rust-examples/hello_world/Cargo.lock @@ -0,0 +1,418 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "cc" +version = "1.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-link", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +dependencies = [ + "cfg-if", + "libc", + "wasi", + "windows-targets", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" + +[[package]] +name = "log" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" + +[[package]] +name = "proc-macro2" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proxy-wasm" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14a5a4df5a1ab77235e36a0a0f638687ee1586d21ee9774037693001e94d4e11" +dependencies = [ + "hashbrown", + "log", +] + +[[package]] +name = "proxy-wasm-example-hello-world" +version = "0.0.1" +dependencies = [ + "cfg-if", + "chrono", + "getrandom", + "log", + "proxy-wasm", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-link" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/src/test/rust-examples/hello_world/Cargo.toml b/src/test/rust-examples/hello_world/Cargo.toml new file mode 100644 index 0000000..5d43f75 --- /dev/null +++ b/src/test/rust-examples/hello_world/Cargo.toml @@ -0,0 +1,27 @@ +[package] +publish = false +name = "proxy-wasm-example-hello-world" +version = "0.0.1" +authors = ["Piotr Sikora "] +description = "Proxy-Wasm plugin example: Hello World" +license = "Apache-2.0" +edition = "2018" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +cfg-if = "1.0" +chrono = { version = "0.4", default-features = false, features = ["clock", "std"] } +log = "0.4" +proxy-wasm = "0.2.2" + +[target.'cfg(not(all(target_arch = "wasm32", target_os = "unknown")))'.dependencies] +getrandom = "0.3" + +[profile.release] +lto = true +opt-level = 3 +codegen-units = 1 +panic = "abort" +strip = "debuginfo" diff --git a/src/test/rust-examples/hello_world/README.md b/src/test/rust-examples/hello_world/README.md new file mode 100644 index 0000000..4dcc8fa --- /dev/null +++ b/src/test/rust-examples/hello_world/README.md @@ -0,0 +1,5 @@ +## Attribution + +This example originally came from: +https://github.com/proxy-wasm/proxy-wasm-rust-sdk/tree/c8b2335df66a569a6306c58e346dd0cf9dbc0f3a/examples/hello_world +``` diff --git a/src/test/rust-examples/hello_world/main.wasm b/src/test/rust-examples/hello_world/main.wasm new file mode 100755 index 0000000000000000000000000000000000000000..c2fec812e65a8108dc6f43355cc2a968bbd095fd GIT binary patch literal 166993 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

r96 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�lIR;a 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 Box { Box::new(HelloWorld) }); +}} + +struct HelloWorld; + +impl Context for HelloWorld {} + +impl RootContext for HelloWorld { + fn on_vm_start(&mut self, _: usize) -> bool { + info!("Hello, World!"); + self.set_tick_period(Duration::from_secs(5)); + true + } + + fn on_tick(&mut self) { + cfg_if! { + if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] { + let now: DateTime = self.get_current_time().into(); + info!("It's {}, there is no lucky number.", now); + + } else { + let now: DateTime = Utc::now(); + let mut buf = [0u8; 1]; + getrandom::fill(&mut buf).unwrap(); + info!("It's {}, your lucky number is {}.", now, buf[0]); + } + } + } +}