Showing preview only (264K chars total). Download the full file or copy to clipboard to get everything.
Repository: proxy-wasm/proxy-wasm-rust-sdk
Branch: main
Commit: b997631e87d9
Files: 80
Total size: 243.7 KB
Directory structure:
gitextract_d2hvdrgx/
├── .actrc
├── .bazelrc
├── .bazelversion
├── .bcr/
│ ├── metadata.template.json
│ ├── presubmit.yml
│ └── source.template.json
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── publish-to-bcr.yml
│ └── rust.yml
├── .gitignore
├── BUILD
├── CHANGELOG.md
├── CODEOWNERS
├── CONTRIBUTING.md
├── Cargo.toml
├── DEVELOPMENT.md
├── LICENSE
├── MODULE.bazel
├── README.md
├── WORKSPACE
├── WORKSPACE.bzlmod
├── bazel/
│ ├── BUILD
│ ├── cargo/
│ │ ├── BUILD
│ │ └── remote/
│ │ ├── BUILD.allocator-api2-0.2.21.bazel
│ │ ├── BUILD.bazel
│ │ ├── BUILD.equivalent-1.0.2.bazel
│ │ ├── BUILD.foldhash-0.2.0.bazel
│ │ ├── BUILD.hashbrown-0.16.0.bazel
│ │ ├── BUILD.log-0.4.27.bazel
│ │ ├── alias_rules.bzl
│ │ ├── crates.bzl
│ │ └── defs.bzl
│ ├── dependencies_bazel.bzl
│ ├── dependencies_compat.bzl
│ ├── dependencies_crates.bzl
│ ├── extensions.bzl
│ └── repositories.bzl
├── build.rs
├── examples/
│ ├── envoy_filter_metadata/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ ├── grpc_auth_random/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ ├── hello_world/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ ├── http_auth_random/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ ├── http_body/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ ├── http_config/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ └── http_headers/
│ ├── Cargo.toml
│ ├── README.md
│ ├── docker-compose.yaml
│ ├── envoy.yaml
│ └── src/
│ └── lib.rs
└── src/
├── allocator.rs
├── dispatcher.rs
├── hostcalls.rs
├── lib.rs
├── logger.rs
├── traits.rs
└── types.rs
================================================
FILE CONTENTS
================================================
================================================
FILE: .actrc
================================================
-P ubuntu-24.04=catthehacker/ubuntu:act-24.04
================================================
FILE: .bazelrc
================================================
# Force Bazel to use --target=wasm32-wasip1
build --platforms=@rules_rust//rust/platform:wasi
================================================
FILE: .bazelversion
================================================
8.5.1
================================================
FILE: .bcr/metadata.template.json
================================================
{
"homepage": "https://github.com/proxy-wasm/proxy-wasm-rust-sdk",
"maintainers": [
{
"github": "PiotrSikora",
"github_user_id": 190297,
"name": "Piotr Sikora"
}
],
"repository": [
"github:proxy-wasm/proxy-wasm-rust-sdk"
],
"versions": [],
"yanked_versions": {}
}
================================================
FILE: .bcr/presubmit.yml
================================================
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
matrix:
platform:
- debian11
- ubuntu2004
- ubuntu2004_arm64
- macos
- macos_arm64
bazel: [7.x, 8.x, 9.x]
tasks:
verify_targets:
name: Verify build targets
platform: ${{ platform }}
bazel: ${{ bazel }}
build_targets:
- "@proxy-wasm-rust-sdk//:proxy_wasm"
================================================
FILE: .bcr/source.template.json
================================================
{
"integrity": "",
"strip_prefix": "proxy-wasm-rust-sdk-{VERSION}",
"url": "https://github.com/{OWNER}/{REPO}/archive/refs/tags/v{VERSION}.tar.gz"
}
================================================
FILE: .github/dependabot.yml
================================================
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
version: 2
updates:
- package-ecosystem: bazel
directory: /
schedule:
interval: weekly
- package-ecosystem: cargo
directories:
- /
- examples/envoy_filter_metadata
- examples/grpc_auth_random
- examples/hello_world
- examples/http_auth_random
- examples/http_body
- examples/http_config
- examples/http_headers
schedule:
interval: weekly
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
================================================
FILE: .github/workflows/publish-to-bcr.yml
================================================
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Publish to BCR
on:
# Automatically trigger when a version tag is pushed.
push:
tags:
- "v*.*.*"
# Allow manual dispatch from the GitHub UI for retries.
workflow_dispatch:
inputs:
tag_name:
description: "Git tag to publish (e.g. v0.2.5)"
required: true
type: string
jobs:
publish:
uses: bazel-contrib/publish-to-bcr/.github/workflows/publish.yaml@v1.1.0
with:
attest: false
open_pull_request: false
registry_fork: PiotrSikora/bazel-central-registry
tag_name: ${{ inputs.tag_name || github.ref_name }}
permissions:
attestations: write
contents: write
id-token: write
secrets:
publish_token: ${{ secrets.BCR_PUBLISH_TOKEN }}
================================================
FILE: .github/workflows/rust.yml
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Rust
on:
pull_request:
branches:
- main
push:
branches:
- main
schedule:
- cron: '0 0 * * *'
jobs:
licenses:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: '^1.24'
- name: Cache
if: ${{ env.ACT }}
uses: actions/cache@v5
with:
path: |
~/go/pkg/mod
key: licenses-${{ hashFiles('.github/workflows/rust.yml') }}
- name: Install dependencies
run: |
go install github.com/google/addlicense@v1.2.0
export PATH=$PATH:$(go env GOPATH)/bin
- name: Check licenses
run: |
addlicense -check -ignore "bazel/cargo/remote/**" .
bazel:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: '^1.24'
- name: Cache
uses: actions/cache@v5
with:
path: |
~/.cache/bazel
~/.cache/bazelisk
~/.cargo/.crates.toml
~/.cargo/.crates2.json
~/.cargo/advisory-db
~/.cargo/bin
~/.cargo/registry
~/go/pkg/mod
key: bazel-${{ hashFiles('.github/workflows/rust.yml', 'BUILD', 'WORKSPACE', '.bazelrc', '.bazelversion', 'bazel/cargo/Cargo.Bazel.lock', 'bazel/dependencies.bzl', 'bazel/repositories.bzl') }}
- name: Install dependencies
run: |
go install github.com/bazelbuild/bazelisk@v1.28.1
go install github.com/bazelbuild/buildtools/buildifier@v0.0.0-20260121081817-bbf01ec6cb49
export PATH=$PATH:$(go env GOPATH)/bin
- name: Build (wasm32-unknown-unknown)
run: bazelisk --noworkspace_rc build --noenable_bzlmod --enable_workspace --platforms=@rules_rust//rust/platform:wasm //...
- name: Build (wasm32-unknown-unknown/bzlmod)
run: bazelisk --noworkspace_rc build --enable_bzlmod --noenable_workspace --platforms=@rules_rust//rust/platform:wasm //...
- name: Build (wasm32-wasip1)
run: bazelisk --noworkspace_rc build --noenable_bzlmod --enable_workspace --platforms=@rules_rust//rust/platform:wasi //...
- name: Build (wasm32-wasip1/bzlmod)
run: bazelisk --noworkspace_rc build --enable_bzlmod --noenable_workspace --platforms=@rules_rust//rust/platform:wasi //...
- name: Format (buildifier)
run: |
buildifier -mode=check -r .
- name: Format (rules_rust)
run: |
bazelisk --noworkspace_rc run --noenable_bzlmod --enable_workspace //bazel/cargo:crates_vendor
git diff --exit-code
- name: Format (MODULE.bazel.lock)
run: bazelisk mod deps --lockfile_mode=error
msrv:
runs-on: ubuntu-24.04
env:
RUSTFLAGS: -D warnings
steps:
- uses: actions/checkout@v6
- name: Cache
if: ${{ env.ACT }}
uses: actions/cache@v5
with:
path: |
~/.cargo/.crates.toml
~/.cargo/.crates2.json
~/.cargo/advisory-db
~/.cargo/bin
~/.cargo/registry
~/.rustup
**/target
key: msrv-${{ hashFiles('Cargo.toml') }}
- name: Install Rustup
if: ${{ env.ACT }}
run: |
curl -OL https://static.rust-lang.org/rustup/rustup-init.sh
chmod +x ./rustup-init.sh
./rustup-init.sh -y --default-toolchain 1.68.0
rm rustup-init.sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Update Rust
run: |
rustup toolchain install 1.68.0 --component clippy --component rustfmt
rustup default 1.68.0
rustup target add wasm32-unknown-unknown
rustup target add wasm32-wasi
- name: Build (wasm32-unknown-unknown)
run: cargo build --release --all-targets --target=wasm32-unknown-unknown
- name: Clippy (wasm32-unknown-unknown)
run: cargo clippy --release --all-targets --target=wasm32-unknown-unknown
- name: Build (wasm32-wasi)
run: cargo build --release --all-targets --target=wasm32-wasi
- name: Clippy (wasm32-wasi)
run: cargo clippy --release --all-targets --target=wasm32-wasi
- name: Test
run: cargo test
# Re-enable once our MSRV is Rust v1.71+.
# - name: Test (no leaks)
# run: cargo test --features mockalloc
- name: Format (rustfmt)
run: cargo fmt -- --check
- name: Format (manifest)
run: cargo verify-project
- name: Package (docs)
run: cargo doc --no-deps --target=wasm32-unknown-unknown
- name: Package (publish)
run: cargo publish --dry-run --target=wasm32-unknown-unknown
stable:
runs-on: ubuntu-24.04
env:
RUSTFLAGS: -D warnings
steps:
- uses: actions/checkout@v6
- name: Cache
if: ${{ env.ACT }}
uses: actions/cache@v5
with:
path: |
~/.cargo/.crates.toml
~/.cargo/.crates2.json
~/.cargo/advisory-db
~/.cargo/bin
~/.cargo/registry
~/.rustup
**/target
key: stable-${{ hashFiles('Cargo.toml') }}
- name: Install Rustup
if: ${{ env.ACT }}
run: |
curl -OL https://static.rust-lang.org/rustup/rustup-init.sh
chmod +x ./rustup-init.sh
./rustup-init.sh -y --default-toolchain stable
rm rustup-init.sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Update Rust
run: |
rustup toolchain install stable --component clippy --component rustfmt
rustup target add wasm32-unknown-unknown
rustup target add wasm32-wasip1
- name: Build (wasm32-unknown-unknown)
run: cargo build --release --all-targets --target=wasm32-unknown-unknown
- name: Clippy (wasm32-unknown-unknown)
run: cargo clippy --release --all-targets --target=wasm32-unknown-unknown
- name: Build (wasm32-wasip1)
run: cargo build --release --all-targets --target=wasm32-wasip1
- name: Clippy (wasm32-wasip1)
run: cargo clippy --release --all-targets --target=wasm32-wasip1
- name: Test
run: cargo test
- name: Test (no leaks)
run: cargo test --features mockalloc
- name: Format (rustfmt)
run: cargo fmt -- --check
- name: Format (manifest)
run: cargo verify-project
- name: Package (docs)
run: cargo doc --no-deps --target=wasm32-unknown-unknown
- name: Package (publish)
run: cargo publish --dry-run --target=wasm32-unknown-unknown
nightly:
runs-on: ubuntu-24.04
env:
RUSTFLAGS: -D warnings
steps:
- uses: actions/checkout@v6
- name: Cache
if: ${{ env.ACT }}
uses: actions/cache@v5
with:
path: |
~/.cargo/.crates.toml
~/.cargo/.crates2.json
~/.cargo/advisory-db
~/.cargo/bin
~/.cargo/registry
~/.rustup
**/target
key: nightly-${{ hashFiles('Cargo.toml') }}
- name: Install Rustup
if: ${{ env.ACT }}
run: |
curl -OL https://static.rust-lang.org/rustup/rustup-init.sh
chmod +x ./rustup-init.sh
./rustup-init.sh -y --default-toolchain nightly
rm rustup-init.sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Update Rust
run: |
rustup toolchain install nightly --component clippy --component rustfmt
rustup default nightly
rustup target add wasm32-unknown-unknown
rustup target add wasm32-wasip1
- name: Build (wasm32-unknown-unknown)
run: cargo build --release --all-targets --target=wasm32-unknown-unknown
- name: Clippy (wasm32-unknown-unknown)
run: cargo clippy --release --all-targets --target=wasm32-unknown-unknown
- name: Build (wasm32-wasip1)
run: cargo build --release --all-targets --target=wasm32-wasip1
- name: Clippy (wasm32-wasip1)
run: cargo clippy --release --all-targets --target=wasm32-wasip1
- name: Test
run: cargo test
- name: Test (no leaks)
run: cargo test --features mockalloc
- name: Bench
run: cargo bench
- name: Format (rustfmt)
run: cargo fmt -- --check
- name: Format (manifest)
run: cargo verify-project
- name: Package (docs)
run: cargo doc --no-deps --target=wasm32-unknown-unknown
- name: Package (publish)
run: cargo publish --dry-run --target=wasm32-unknown-unknown
outdated:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- name: Cache
uses: actions/cache@v5
with:
path: |
~/.cargo/.crates.toml
~/.cargo/.crates2.json
~/.cargo/advisory-db
~/.cargo/bin
~/.cargo/registry
~/.rustup
key: outdated-${{ hashFiles('.github/workflows/rust.yml', 'Cargo.toml') }}
- name: Install Rustup
if: ${{ env.ACT }}
run: |
curl -OL https://static.rust-lang.org/rustup/rustup-init.sh
chmod +x ./rustup-init.sh
./rustup-init.sh -y
rm rustup-init.sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cargo install cargo-outdated --version 0.17.0
- name: Run cargo outdated (main)
run: |
cargo outdated --root-deps-only --exit-code 1
- name: Run cargo outdated (examples)
run: |
for example in $(find examples -name Cargo.toml); do \
cd $(dirname $GITHUB_WORKSPACE/$example); \
cargo outdated --root-deps-only --exit-code 1; \
done
audit:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- name: Cache
uses: actions/cache@v5
with:
path: |
~/.cargo/.crates.toml
~/.cargo/.crates2.json
~/.cargo/advisory-db
~/.cargo/bin
~/.cargo/registry
~/.rustup
key: audit-${{ hashFiles('.github/workflows/rust.yml', 'Cargo.toml') }}
- name: Install Rustup
if: ${{ env.ACT }}
run: |
curl -OL https://static.rust-lang.org/rustup/rustup-init.sh
chmod +x ./rustup-init.sh
./rustup-init.sh -y
rm rustup-init.sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cargo install cargo-audit --version 0.22.0
- name: Run cargo audit (main)
run: |
cp -p bazel/cargo/Cargo.Bazel.lock Cargo.lock
cargo audit
- name: Run cargo audit (examples)
run: |
for example in $(find examples -name Cargo.toml); do \
cd $(dirname $GITHUB_WORKSPACE/$example); \
cargo audit; \
done
examples:
runs-on: ubuntu-24.04
strategy:
matrix:
example:
- 'hello_world'
- 'http_auth_random'
- 'http_body'
- 'http_config'
- 'http_headers'
- 'grpc_auth_random'
- 'envoy_filter_metadata'
defaults:
run:
working-directory: ./examples/${{ matrix.example }}
env:
RUSTFLAGS: -D warnings
steps:
- uses: actions/checkout@v6
- name: Cache
if: ${{ env.ACT }}
uses: actions/cache@v5
with:
path: |
~/.cargo/.crates.toml
~/.cargo/.crates2.json
~/.cargo/advisory-db
~/.cargo/bin
~/.cargo/registry
~/.rustup
**/target
key: example-${{ matrix.example }}-${{ hashFiles('Cargo.toml') }}
- name: Install Rustup
if: ${{ env.ACT }}
run: |
curl -OL https://static.rust-lang.org/rustup/rustup-init.sh
chmod +x ./rustup-init.sh
./rustup-init.sh -y
rm rustup-init.sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Update Rust
run: |
rustup toolchain install stable --component clippy --component rustfmt
rustup target add wasm32-wasip1
- name: Build (wasm32-wasip1)
run: cargo build --release --target=wasm32-wasip1
- name: Clippy (wasm32-wasip1)
run: cargo clippy --release --target=wasm32-wasip1
- name: Format (rustfmt)
run: cargo fmt -- --check
- name: Format (manifest)
run: cargo verify-project
- name: Validate Envoy config
run: |
docker run --rm \
-v $(pwd)/envoy.yaml:/envoy.yaml \
-v $(pwd)/target/wasm32-wasip1/release:/etc/envoy/proxy-wasm-plugins \
envoyproxy/envoy:v1.34-latest \
--mode validate \
-c envoy.yaml
reactors:
runs-on: ubuntu-24.04
strategy:
matrix:
example:
- 'hello_world'
- 'http_auth_random'
- 'http_body'
- 'http_config'
- 'http_headers'
- 'grpc_auth_random'
- 'envoy_filter_metadata'
defaults:
run:
working-directory: ./examples/${{ matrix.example }}
env:
RUSTFLAGS: -D warnings -Z wasi-exec-model=reactor
steps:
- uses: actions/checkout@v6
- name: Cache
if: ${{ env.ACT }}
uses: actions/cache@v5
with:
path: |
~/.cargo/.crates.toml
~/.cargo/.crates2.json
~/.cargo/advisory-db
~/.cargo/bin
~/.cargo/registry
~/.rustup
**/target
key: reactor-${{ matrix.example }}-${{ hashFiles('Cargo.toml') }}
- name: Install Rustup
if: ${{ env.ACT }}
run: |
curl -OL https://static.rust-lang.org/rustup/rustup-init.sh
chmod +x ./rustup-init.sh
./rustup-init.sh -y --default-toolchain nightly
rm rustup-init.sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Update Rust
run: |
rustup toolchain install nightly --component clippy --component rustfmt
rustup default nightly
rustup target add wasm32-wasip1
- name: Change crate type from library to binary
run: |
grep -v '^\[lib\]' Cargo.toml > Cargo.tmp
grep -v '^crate-type' Cargo.tmp > Cargo.toml
mv src/lib.rs src/main.rs
- name: Build (wasm32-wasip1)
run: cargo build --release --target=wasm32-wasip1
- name: Clippy (wasm32-wasip1)
run: cargo clippy --release --target=wasm32-wasip1
- name: Format (rustfmt)
run: cargo fmt -- --check
- name: Format (manifest)
run: cargo verify-project
- name: Rename .wasm to match expected filename
run: |
cd target/wasm32-wasip1/release
for file in $(ls -1 *.wasm); do \
mv $file $(echo $file | sed 's/-/_/g'); \
done
- name: Validate Envoy config
run: |
docker run --rm \
-v $(pwd)/envoy.yaml:/envoy.yaml \
-v $(pwd)/target/wasm32-wasip1/release:/etc/envoy/proxy-wasm-plugins \
envoyproxy/envoy:v1.34-latest \
--mode validate \
-c envoy.yaml
================================================
FILE: .gitignore
================================================
/bazel-*
target
Cargo.lock
================================================
FILE: BUILD
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@rules_rust//cargo:defs.bzl", "cargo_build_script")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_shared_library")
exports_files([
"Cargo.toml",
])
cargo_build_script(
name = "proxy_wasm_build_script",
srcs = ["build.rs"],
edition = "2018",
tags = ["manual"],
visibility = ["//visibility:private"],
)
rust_library(
name = "proxy_wasm",
srcs = glob(["src/*.rs"]),
edition = "2018",
visibility = ["//visibility:public"],
deps = [
":proxy_wasm_build_script",
"//bazel/cargo/remote:hashbrown",
"//bazel/cargo/remote:log",
],
)
rust_shared_library(
name = "http_auth_random",
srcs = ["examples/http_auth_random/src/lib.rs"],
edition = "2018",
rustc_flags = ["-Cstrip=debuginfo"],
visibility = ["//visibility:private"],
deps = [
":proxy_wasm",
"//bazel/cargo/remote:log",
],
)
================================================
FILE: CHANGELOG.md
================================================
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [0.2.4] - 2025-10-01
### Fixed
- Fixed a memory leak in `get_map` and `get_map_bytes` hostcalls.
This issue has been introduced in [0.2.3].
Thanks [@JaatadiaMulesoft](https://github.com/JaatadiaMulesoft)!
## [0.2.3] - 2025-06-04
### Changed
- An empty value (`Some("")` or `Some([])`) is now returned when retrieving
value of a HTTP header or trailer with an empty value. This is consistent
with the representation when retrieving a full HTTP header or trailer map.
Previously, a "no value" (`None`) was being returned, which made an empty
value indistinguishable from a non-existent HTTP header or trailer.
Thanks [@prembhaskal](https://github.com/prembhaskal)!
### Added
- Added support for foreign function callbacks.
Thanks [@casimiro](https://github.com/casimiro)!
- Added convenience functions to remove headers and trailers.
Thanks [@itsLucario](https://github.com/itsLucario)!
- Added convenience function to remove shared data.
## [0.2.2] - 2024-07-21
### Fixed
- Fixed support for nested gRPC callouts.
Thanks [@andytesti](https://github.com/andytesti)!
- Fixed panic on unknown `token_id` in `on_grpc_receive_initial_metadata`
and `on_grpc_receive_trailing_metadata`.
Thanks [@erikness-doordash](https://github.com/erikness-doordash)!
- Fixed panic on unexpected failures in `get_property`.
Thanks [@alexsnaps](https://github.com/alexsnaps)!
- Fixed panic on unexpected failures in `call_foreign_function`.
Reported by [@geNAZt](https://github.com/geNAZt).
### Added
- Added support for sending error responses with gRPC status codes.
Thanks [@juanmolle](https://github.com/juanmolle)!
## [0.2.1] - 2022-11-22
### Fixed
- Fixed panic on unknown `token_id` in `on_grpc_close`.
Thanks [@Protryon](https://github.com/Protryon)!
### Changed
- Changed MSRV to v1.61.0.
### Removed
- Removed `wee-alloc` feature, because that crate is no longer maintained
and it leaks memory.
## [0.2.0] - 2022-04-08
### Fixed
- Fixed performance degradation with `wasm32-wasi` target in Rust v1.56.0
or newer by adding `proxy_wasm::main` macro that should be used instead
of custom `_start`, `_initialize` and/or `main` exports.
### Changed
- Updated ABI to Proxy-Wasm ABI v0.2.1.
### Added
- Added support for calling foreign functions.
Thanks [@Gsantomaggio](https://github.com/Gsantomaggio)!
## [0.1.4] - 2021-07-01
### Added
- Added support for gRPC callouts.
Thanks [@Shikugawa](https://github.com/Shikugawa)!
## [0.1.3] - 2020-12-04
### Fixed
- Fixed support for nested HTTP callouts.
Thanks [@SvetlinZarev](https://github.com/SvetlinZarev)!
### Changed
- Changed `wee-alloc` to an optional feature.
Thanks [@yuval-k](https://github.com/yuval-k)!
### Added
- Added support for building for `wasm32-wasi` target.
- Added support for metrics.
- Added support for `RootContext` to create child contexts for streams.
Thanks [@dgn](https://github.com/dgn)!
- Added support for setting network buffers.
## [0.1.2] - 2020-08-05
### Changed
- Updated `MapType` values to match updated Proxy-Wasm ABI v0.1.0.
Thanks [@yskopets](https://github.com/yskopets)!
## [0.1.1] - 2020-08-05
### Added
- Added support for building with Bazel.
- Added support for setting HTTP bodies.
Thanks [@gbrail](https://github.com/gbrail)!
## [0.1.0] - 2020-02-29
### Added
- Initial release.
[0.2.4]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/compare/v0.2.3...v0.2.4
[0.2.3]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/compare/v0.2.2...v0.2.3
[0.2.2]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/compare/v0.2.1...v0.2.2
[0.2.1]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/compare/v0.1.4...v0.2.0
[0.1.4]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/compare/v0.1.3...v0.1.4
[0.1.3]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/compare/v0.1.2...v0.1.3
[0.1.2]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/compare/v0.1.1...v0.1.2
[0.1.1]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/releases/tag/v0.1.0
================================================
FILE: CODEOWNERS
================================================
* @PiotrSikora
================================================
FILE: CONTRIBUTING.md
================================================
# How to Contribute
We'd love to accept your patches and contributions to this project. There are
just a few small guidelines you need to follow.
## Contributor License Agreement
Contributions to this project must be accompanied by a Contributor License
Agreement. You (or your employer) retain the copyright to your contribution;
this simply gives us permission to use and redistribute your contributions as
part of the project. Head over to <https://cla.developers.google.com/> to see
your current agreements on file or to sign a new one.
You generally only need to submit a CLA once, so if you've already submitted one
(even if it was for a different project), you probably don't need to do it
again.
## Code reviews
All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.
## Community Guidelines
This project follows [Google's Open Source Community
Guidelines](https://opensource.google/conduct/).
================================================
FILE: Cargo.toml
================================================
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
name = "proxy-wasm"
version = "0.2.5-dev"
authors = ["Piotr Sikora <piotrsikora@google.com>"]
rust-version = "1.68"
description = "WebAssembly for Proxies"
readme = "README.md"
license = "Apache-2.0"
repository = "https://github.com/proxy-wasm/proxy-wasm-rust-sdk"
edition = "2018"
build = "build.rs"
[dependencies]
hashbrown = "0.16"
log = "0.4"
mockalloc = { version = "0.1", optional = true }
[profile.release]
lto = true
opt-level = 3
codegen-units = 1
panic = "abort"
strip = "debuginfo"
[profile.test]
inherits = "release"
debug = true
[profile.bench]
inherits = "release"
debug = true
================================================
FILE: DEVELOPMENT.md
================================================
# Development
## Testing
GitHub Actions can be executed locally using the [`act`] tool.
All tests can be executed using:
act
Individual tests can be executed using `-j` and `--matrix` parameters, e.g.:
act -j bazel
act -j stable
act -j nightly
act -j examples --matrix example:http_auth_random
By default, all jobs are cached in `~/.cache/actcache`. This can be disabled
using the `--no-cache-server` parameter.
## Updating Bazel dependencies
When adding or updating Cargo dependencies, the existing Bazel `BUILD` files
must be regenerated using the [`bazelisk`] tool:
```sh
bazelisk run --noenable_bzlmod --enable_workspace //bazel/cargo:crates_vendor -- --repin all
```
[`act`]: https://github.com/nektos/act
[`bazelisk`]: https://github.com/bazelbuild/bazelisk
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: MODULE.bazel
================================================
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
module(
name = "proxy-wasm-rust-sdk",
version = "0.2.5-dev",
repo_name = "proxy_wasm_rust_sdk",
)
# Regular dependencies (sorted alphabetically).
bazel_dep(name = "bazel_features", version = "1.38.0")
bazel_dep(name = "bazel_skylib", version = "1.8.2")
bazel_dep(name = "rules_cc", version = "0.2.14")
bazel_dep(name = "rules_rust", version = "0.68.1")
# Configure Rust toolchain.
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain(
edition = "2018",
versions = ["1.91.1"],
)
use_repo(rust, "rust_toolchains")
register_toolchains(
"@rust_toolchains//:all",
# Dummy C/C++ toolchains for Wasm targets.
"@rules_rust//rust/private/dummy_cc_toolchain:dummy_cc_wasm32_toolchain",
"@rules_rust//rust/private/dummy_cc_toolchain:dummy_cc_wasm64_toolchain",
)
# Cargo dependencies.
crates_deps = use_extension("//bazel:extensions.bzl", "crates_deps")
use_repo(
crates_deps,
"crates_vendor",
"crates_vendor__hashbrown-0.16.0",
"crates_vendor__log-0.4.27",
)
================================================
FILE: README.md
================================================
# WebAssembly for Proxies (Rust SDK)
[![Build Status][build-badge]][build-link]
[![Crate][crate-badge]][crate-link]
[![Documentation][docs-badge]][docs-link]
[![Apache 2.0 License][license-badge]][license-link]
[build-badge]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/workflows/Rust/badge.svg?branch=main
[build-link]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/actions?query=workflow%3ARust+branch%3Amain
[crate-badge]: https://img.shields.io/crates/v/proxy-wasm.svg
[crate-link]: https://crates.io/crates/proxy-wasm
[docs-badge]: https://docs.rs/proxy-wasm/badge.svg
[docs-link]: https://docs.rs/proxy-wasm
[license-badge]: https://img.shields.io/github/license/proxy-wasm/proxy-wasm-rust-sdk
[license-link]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/blob/main/LICENSE
## Examples
- [Hello World](./examples/hello_world/)
- [HTTP Auth (random)](./examples/http_auth_random/)
- [HTTP Headers](./examples/http_headers/)
- [HTTP Response body](./examples/http_body/)
- [HTTP Configuration](./examples/http_config/)
- [gRPC Auth (random)](./examples/grpc_auth_random/)
- [Envoy filter metadata](./examples/envoy_filter_metadata/)
## Articles & blog posts from the community
- [Extending Envoy with WASM and Rust](https://antweiss.com/blog/extending-envoy-with-wasm-and-rust/)
- [Writing Envoy filters in Rust with WebAssembly](https://content.red-badger.com/resources/extending-istio-with-rust-and-webassembly)
## Contributing changes
See [CONTRIBUTING.md](./CONTRIBUTING.md) and [DEVELOPMENT.md](./DEVELOPMENT.md) files.
================================================
FILE: WORKSPACE
================================================
workspace(name = "proxy_wasm_rust_sdk")
load("@proxy_wasm_rust_sdk//bazel:repositories.bzl", "proxy_wasm_rust_sdk_repositories")
proxy_wasm_rust_sdk_repositories()
load("@proxy_wasm_rust_sdk//bazel:dependencies_bazel.bzl", "proxy_wasm_rust_sdk_dependencies_bazel")
proxy_wasm_rust_sdk_dependencies_bazel()
load("@proxy_wasm_rust_sdk//bazel:dependencies_compat.bzl", "proxy_wasm_rust_sdk_dependencies_compat")
proxy_wasm_rust_sdk_dependencies_compat()
load("@proxy_wasm_rust_sdk//bazel:dependencies_crates.bzl", "proxy_wasm_rust_sdk_dependencies_crates")
proxy_wasm_rust_sdk_dependencies_crates()
================================================
FILE: WORKSPACE.bzlmod
================================================
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
================================================
FILE: bazel/BUILD
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
================================================
FILE: bazel/cargo/BUILD
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@rules_rust//crate_universe:defs.bzl", "crates_vendor")
exports_files([
"Cargo.Bazel.lock",
])
crates_vendor(
name = "crates_vendor",
cargo_lockfile = "//bazel/cargo:Cargo.Bazel.lock",
manifests = ["//:Cargo.toml"],
mode = "remote",
tags = ["manual"],
vendor_path = "//bazel/cargo/remote",
)
================================================
FILE: bazel/cargo/remote/BUILD.allocator-api2-0.2.21.bazel
================================================
###############################################################################
# @generated
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
# regenerate this file, run the following:
#
# bazel run @//bazel/cargo:crates_vendor
###############################################################################
load("@rules_rust//cargo:defs.bzl", "cargo_toml_env_vars")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
cargo_toml_env_vars(
name = "cargo_toml_env_vars",
src = "Cargo.toml",
)
rust_library(
name = "allocator_api2",
srcs = glob(
include = ["**/*.rs"],
allow_empty = True,
),
compile_data = glob(
include = ["**"],
allow_empty = True,
exclude = [
"**/* *",
".tmp_git_root/**/*",
"BUILD",
"BUILD.bazel",
"WORKSPACE",
"WORKSPACE.bazel",
],
),
crate_features = [
"alloc",
],
crate_root = "src/lib.rs",
edition = "2018",
rustc_env_files = [
":cargo_toml_env_vars",
],
rustc_flags = [
"--cap-lints=allow",
],
tags = [
"cargo-bazel",
"crate-name=allocator-api2",
"manual",
"noclippy",
"norustfmt",
],
target_compatible_with = select({
"@rules_rust//rust/platform:aarch64-apple-darwin": [],
"@rules_rust//rust/platform:aarch64-apple-ios": [],
"@rules_rust//rust/platform:aarch64-apple-ios-sim": [],
"@rules_rust//rust/platform:aarch64-linux-android": [],
"@rules_rust//rust/platform:aarch64-pc-windows-msvc": [],
"@rules_rust//rust/platform:aarch64-unknown-fuchsia": [],
"@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [],
"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [],
"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [],
"@rules_rust//rust/platform:aarch64-unknown-uefi": [],
"@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [],
"@rules_rust//rust/platform:armv7-linux-androideabi": [],
"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [],
"@rules_rust//rust/platform:i686-apple-darwin": [],
"@rules_rust//rust/platform:i686-linux-android": [],
"@rules_rust//rust/platform:i686-pc-windows-msvc": [],
"@rules_rust//rust/platform:i686-unknown-freebsd": [],
"@rules_rust//rust/platform:i686-unknown-linux-gnu": [],
"@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [],
"@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [],
"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu": [],
"@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [],
"@rules_rust//rust/platform:s390x-unknown-linux-gnu": [],
"@rules_rust//rust/platform:thumbv7em-none-eabi": [],
"@rules_rust//rust/platform:thumbv8m.main-none-eabi": [],
"@rules_rust//rust/platform:wasm32-unknown-emscripten": [],
"@rules_rust//rust/platform:wasm32-unknown-unknown": [],
"@rules_rust//rust/platform:wasm32-wasip1": [],
"@rules_rust//rust/platform:wasm32-wasip1-threads": [],
"@rules_rust//rust/platform:wasm32-wasip2": [],
"@rules_rust//rust/platform:x86_64-apple-darwin": [],
"@rules_rust//rust/platform:x86_64-apple-ios": [],
"@rules_rust//rust/platform:x86_64-linux-android": [],
"@rules_rust//rust/platform:x86_64-pc-windows-msvc": [],
"@rules_rust//rust/platform:x86_64-unknown-freebsd": [],
"@rules_rust//rust/platform:x86_64-unknown-fuchsia": [],
"@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [],
"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [],
"@rules_rust//rust/platform:x86_64-unknown-none": [],
"@rules_rust//rust/platform:x86_64-unknown-uefi": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
version = "0.2.21",
)
================================================
FILE: bazel/cargo/remote/BUILD.bazel
================================================
###############################################################################
# @generated
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
# regenerate this file, run the following:
#
# bazel run @//bazel/cargo:crates_vendor
###############################################################################
package(default_visibility = ["//visibility:public"])
exports_files(
[
"cargo-bazel.json",
"crates.bzl",
"defs.bzl",
] + glob(
include = ["*.bazel"],
allow_empty = True,
),
)
filegroup(
name = "srcs",
srcs = glob(
include = [
"*.bazel",
"*.bzl",
],
allow_empty = True,
),
)
# Workspace Member Dependencies
alias(
name = "hashbrown-0.16.0",
actual = "@crates_vendor__hashbrown-0.16.0//:hashbrown",
tags = ["manual"],
)
alias(
name = "hashbrown",
actual = "@crates_vendor__hashbrown-0.16.0//:hashbrown",
tags = ["manual"],
)
alias(
name = "log-0.4.27",
actual = "@crates_vendor__log-0.4.27//:log",
tags = ["manual"],
)
alias(
name = "log",
actual = "@crates_vendor__log-0.4.27//:log",
tags = ["manual"],
)
alias(
name = "proxy-wasm-0.2.5-dev",
actual = "@crates_vendor__proxy-wasm-0.2.5-dev//:proxy_wasm",
tags = ["manual"],
)
alias(
name = "proxy-wasm",
actual = "@crates_vendor__proxy-wasm-0.2.5-dev//:proxy_wasm",
tags = ["manual"],
)
================================================
FILE: bazel/cargo/remote/BUILD.equivalent-1.0.2.bazel
================================================
###############################################################################
# @generated
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
# regenerate this file, run the following:
#
# bazel run @//bazel/cargo:crates_vendor
###############################################################################
load("@rules_rust//cargo:defs.bzl", "cargo_toml_env_vars")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
cargo_toml_env_vars(
name = "cargo_toml_env_vars",
src = "Cargo.toml",
)
rust_library(
name = "equivalent",
srcs = glob(
include = ["**/*.rs"],
allow_empty = True,
),
compile_data = glob(
include = ["**"],
allow_empty = True,
exclude = [
"**/* *",
".tmp_git_root/**/*",
"BUILD",
"BUILD.bazel",
"WORKSPACE",
"WORKSPACE.bazel",
],
),
crate_root = "src/lib.rs",
edition = "2015",
rustc_env_files = [
":cargo_toml_env_vars",
],
rustc_flags = [
"--cap-lints=allow",
],
tags = [
"cargo-bazel",
"crate-name=equivalent",
"manual",
"noclippy",
"norustfmt",
],
target_compatible_with = select({
"@rules_rust//rust/platform:aarch64-apple-darwin": [],
"@rules_rust//rust/platform:aarch64-apple-ios": [],
"@rules_rust//rust/platform:aarch64-apple-ios-sim": [],
"@rules_rust//rust/platform:aarch64-linux-android": [],
"@rules_rust//rust/platform:aarch64-pc-windows-msvc": [],
"@rules_rust//rust/platform:aarch64-unknown-fuchsia": [],
"@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [],
"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [],
"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [],
"@rules_rust//rust/platform:aarch64-unknown-uefi": [],
"@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [],
"@rules_rust//rust/platform:armv7-linux-androideabi": [],
"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [],
"@rules_rust//rust/platform:i686-apple-darwin": [],
"@rules_rust//rust/platform:i686-linux-android": [],
"@rules_rust//rust/platform:i686-pc-windows-msvc": [],
"@rules_rust//rust/platform:i686-unknown-freebsd": [],
"@rules_rust//rust/platform:i686-unknown-linux-gnu": [],
"@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [],
"@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [],
"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu": [],
"@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [],
"@rules_rust//rust/platform:s390x-unknown-linux-gnu": [],
"@rules_rust//rust/platform:thumbv7em-none-eabi": [],
"@rules_rust//rust/platform:thumbv8m.main-none-eabi": [],
"@rules_rust//rust/platform:wasm32-unknown-emscripten": [],
"@rules_rust//rust/platform:wasm32-unknown-unknown": [],
"@rules_rust//rust/platform:wasm32-wasip1": [],
"@rules_rust//rust/platform:wasm32-wasip1-threads": [],
"@rules_rust//rust/platform:wasm32-wasip2": [],
"@rules_rust//rust/platform:x86_64-apple-darwin": [],
"@rules_rust//rust/platform:x86_64-apple-ios": [],
"@rules_rust//rust/platform:x86_64-linux-android": [],
"@rules_rust//rust/platform:x86_64-pc-windows-msvc": [],
"@rules_rust//rust/platform:x86_64-unknown-freebsd": [],
"@rules_rust//rust/platform:x86_64-unknown-fuchsia": [],
"@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [],
"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [],
"@rules_rust//rust/platform:x86_64-unknown-none": [],
"@rules_rust//rust/platform:x86_64-unknown-uefi": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
version = "1.0.2",
)
================================================
FILE: bazel/cargo/remote/BUILD.foldhash-0.2.0.bazel
================================================
###############################################################################
# @generated
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
# regenerate this file, run the following:
#
# bazel run @//bazel/cargo:crates_vendor
###############################################################################
load("@rules_rust//cargo:defs.bzl", "cargo_toml_env_vars")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
cargo_toml_env_vars(
name = "cargo_toml_env_vars",
src = "Cargo.toml",
)
rust_library(
name = "foldhash",
srcs = glob(
include = ["**/*.rs"],
allow_empty = True,
),
compile_data = glob(
include = ["**"],
allow_empty = True,
exclude = [
"**/* *",
".tmp_git_root/**/*",
"BUILD",
"BUILD.bazel",
"WORKSPACE",
"WORKSPACE.bazel",
],
),
crate_root = "src/lib.rs",
edition = "2021",
rustc_env_files = [
":cargo_toml_env_vars",
],
rustc_flags = [
"--cap-lints=allow",
],
tags = [
"cargo-bazel",
"crate-name=foldhash",
"manual",
"noclippy",
"norustfmt",
],
target_compatible_with = select({
"@rules_rust//rust/platform:aarch64-apple-darwin": [],
"@rules_rust//rust/platform:aarch64-apple-ios": [],
"@rules_rust//rust/platform:aarch64-apple-ios-sim": [],
"@rules_rust//rust/platform:aarch64-linux-android": [],
"@rules_rust//rust/platform:aarch64-pc-windows-msvc": [],
"@rules_rust//rust/platform:aarch64-unknown-fuchsia": [],
"@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [],
"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [],
"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [],
"@rules_rust//rust/platform:aarch64-unknown-uefi": [],
"@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [],
"@rules_rust//rust/platform:armv7-linux-androideabi": [],
"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [],
"@rules_rust//rust/platform:i686-apple-darwin": [],
"@rules_rust//rust/platform:i686-linux-android": [],
"@rules_rust//rust/platform:i686-pc-windows-msvc": [],
"@rules_rust//rust/platform:i686-unknown-freebsd": [],
"@rules_rust//rust/platform:i686-unknown-linux-gnu": [],
"@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [],
"@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [],
"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu": [],
"@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [],
"@rules_rust//rust/platform:s390x-unknown-linux-gnu": [],
"@rules_rust//rust/platform:thumbv7em-none-eabi": [],
"@rules_rust//rust/platform:thumbv8m.main-none-eabi": [],
"@rules_rust//rust/platform:wasm32-unknown-emscripten": [],
"@rules_rust//rust/platform:wasm32-unknown-unknown": [],
"@rules_rust//rust/platform:wasm32-wasip1": [],
"@rules_rust//rust/platform:wasm32-wasip1-threads": [],
"@rules_rust//rust/platform:wasm32-wasip2": [],
"@rules_rust//rust/platform:x86_64-apple-darwin": [],
"@rules_rust//rust/platform:x86_64-apple-ios": [],
"@rules_rust//rust/platform:x86_64-linux-android": [],
"@rules_rust//rust/platform:x86_64-pc-windows-msvc": [],
"@rules_rust//rust/platform:x86_64-unknown-freebsd": [],
"@rules_rust//rust/platform:x86_64-unknown-fuchsia": [],
"@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [],
"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [],
"@rules_rust//rust/platform:x86_64-unknown-none": [],
"@rules_rust//rust/platform:x86_64-unknown-uefi": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
version = "0.2.0",
)
================================================
FILE: bazel/cargo/remote/BUILD.hashbrown-0.16.0.bazel
================================================
###############################################################################
# @generated
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
# regenerate this file, run the following:
#
# bazel run @//bazel/cargo:crates_vendor
###############################################################################
load("@rules_rust//cargo:defs.bzl", "cargo_toml_env_vars")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
cargo_toml_env_vars(
name = "cargo_toml_env_vars",
src = "Cargo.toml",
)
rust_library(
name = "hashbrown",
srcs = glob(
include = ["**/*.rs"],
allow_empty = True,
),
compile_data = glob(
include = ["**"],
allow_empty = True,
exclude = [
"**/* *",
".tmp_git_root/**/*",
"BUILD",
"BUILD.bazel",
"WORKSPACE",
"WORKSPACE.bazel",
],
),
crate_features = [
"allocator-api2",
"default",
"default-hasher",
"equivalent",
"inline-more",
"raw-entry",
],
crate_root = "src/lib.rs",
edition = "2021",
rustc_env_files = [
":cargo_toml_env_vars",
],
rustc_flags = [
"--cap-lints=allow",
],
tags = [
"cargo-bazel",
"crate-name=hashbrown",
"manual",
"noclippy",
"norustfmt",
],
target_compatible_with = select({
"@rules_rust//rust/platform:aarch64-apple-darwin": [],
"@rules_rust//rust/platform:aarch64-apple-ios": [],
"@rules_rust//rust/platform:aarch64-apple-ios-sim": [],
"@rules_rust//rust/platform:aarch64-linux-android": [],
"@rules_rust//rust/platform:aarch64-pc-windows-msvc": [],
"@rules_rust//rust/platform:aarch64-unknown-fuchsia": [],
"@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [],
"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [],
"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [],
"@rules_rust//rust/platform:aarch64-unknown-uefi": [],
"@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [],
"@rules_rust//rust/platform:armv7-linux-androideabi": [],
"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [],
"@rules_rust//rust/platform:i686-apple-darwin": [],
"@rules_rust//rust/platform:i686-linux-android": [],
"@rules_rust//rust/platform:i686-pc-windows-msvc": [],
"@rules_rust//rust/platform:i686-unknown-freebsd": [],
"@rules_rust//rust/platform:i686-unknown-linux-gnu": [],
"@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [],
"@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [],
"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu": [],
"@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [],
"@rules_rust//rust/platform:s390x-unknown-linux-gnu": [],
"@rules_rust//rust/platform:thumbv7em-none-eabi": [],
"@rules_rust//rust/platform:thumbv8m.main-none-eabi": [],
"@rules_rust//rust/platform:wasm32-unknown-emscripten": [],
"@rules_rust//rust/platform:wasm32-unknown-unknown": [],
"@rules_rust//rust/platform:wasm32-wasip1": [],
"@rules_rust//rust/platform:wasm32-wasip1-threads": [],
"@rules_rust//rust/platform:wasm32-wasip2": [],
"@rules_rust//rust/platform:x86_64-apple-darwin": [],
"@rules_rust//rust/platform:x86_64-apple-ios": [],
"@rules_rust//rust/platform:x86_64-linux-android": [],
"@rules_rust//rust/platform:x86_64-pc-windows-msvc": [],
"@rules_rust//rust/platform:x86_64-unknown-freebsd": [],
"@rules_rust//rust/platform:x86_64-unknown-fuchsia": [],
"@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [],
"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [],
"@rules_rust//rust/platform:x86_64-unknown-none": [],
"@rules_rust//rust/platform:x86_64-unknown-uefi": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
version = "0.16.0",
deps = [
"@crates_vendor__allocator-api2-0.2.21//:allocator_api2",
"@crates_vendor__equivalent-1.0.2//:equivalent",
"@crates_vendor__foldhash-0.2.0//:foldhash",
],
)
================================================
FILE: bazel/cargo/remote/BUILD.log-0.4.27.bazel
================================================
###############################################################################
# @generated
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
# regenerate this file, run the following:
#
# bazel run @//bazel/cargo:crates_vendor
###############################################################################
load("@rules_rust//cargo:defs.bzl", "cargo_toml_env_vars")
load("@rules_rust//rust:defs.bzl", "rust_library")
package(default_visibility = ["//visibility:public"])
cargo_toml_env_vars(
name = "cargo_toml_env_vars",
src = "Cargo.toml",
)
rust_library(
name = "log",
srcs = glob(
include = ["**/*.rs"],
allow_empty = True,
),
compile_data = glob(
include = ["**"],
allow_empty = True,
exclude = [
"**/* *",
".tmp_git_root/**/*",
"BUILD",
"BUILD.bazel",
"WORKSPACE",
"WORKSPACE.bazel",
],
),
crate_root = "src/lib.rs",
edition = "2021",
rustc_env_files = [
":cargo_toml_env_vars",
],
rustc_flags = [
"--cap-lints=allow",
],
tags = [
"cargo-bazel",
"crate-name=log",
"manual",
"noclippy",
"norustfmt",
],
target_compatible_with = select({
"@rules_rust//rust/platform:aarch64-apple-darwin": [],
"@rules_rust//rust/platform:aarch64-apple-ios": [],
"@rules_rust//rust/platform:aarch64-apple-ios-sim": [],
"@rules_rust//rust/platform:aarch64-linux-android": [],
"@rules_rust//rust/platform:aarch64-pc-windows-msvc": [],
"@rules_rust//rust/platform:aarch64-unknown-fuchsia": [],
"@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [],
"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu": [],
"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710": [],
"@rules_rust//rust/platform:aarch64-unknown-uefi": [],
"@rules_rust//rust/platform:arm-unknown-linux-gnueabi": [],
"@rules_rust//rust/platform:armv7-linux-androideabi": [],
"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi": [],
"@rules_rust//rust/platform:i686-apple-darwin": [],
"@rules_rust//rust/platform:i686-linux-android": [],
"@rules_rust//rust/platform:i686-pc-windows-msvc": [],
"@rules_rust//rust/platform:i686-unknown-freebsd": [],
"@rules_rust//rust/platform:i686-unknown-linux-gnu": [],
"@rules_rust//rust/platform:powerpc-unknown-linux-gnu": [],
"@rules_rust//rust/platform:riscv32imc-unknown-none-elf": [],
"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu": [],
"@rules_rust//rust/platform:riscv64gc-unknown-none-elf": [],
"@rules_rust//rust/platform:s390x-unknown-linux-gnu": [],
"@rules_rust//rust/platform:thumbv7em-none-eabi": [],
"@rules_rust//rust/platform:thumbv8m.main-none-eabi": [],
"@rules_rust//rust/platform:wasm32-unknown-emscripten": [],
"@rules_rust//rust/platform:wasm32-unknown-unknown": [],
"@rules_rust//rust/platform:wasm32-wasip1": [],
"@rules_rust//rust/platform:wasm32-wasip1-threads": [],
"@rules_rust//rust/platform:wasm32-wasip2": [],
"@rules_rust//rust/platform:x86_64-apple-darwin": [],
"@rules_rust//rust/platform:x86_64-apple-ios": [],
"@rules_rust//rust/platform:x86_64-linux-android": [],
"@rules_rust//rust/platform:x86_64-pc-windows-msvc": [],
"@rules_rust//rust/platform:x86_64-unknown-freebsd": [],
"@rules_rust//rust/platform:x86_64-unknown-fuchsia": [],
"@rules_rust//rust/platform:x86_64-unknown-linux-gnu": [],
"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu": [],
"@rules_rust//rust/platform:x86_64-unknown-none": [],
"@rules_rust//rust/platform:x86_64-unknown-uefi": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
version = "0.4.27",
)
================================================
FILE: bazel/cargo/remote/alias_rules.bzl
================================================
"""Alias that transitions its target to `compilation_mode=opt`. Use `transition_alias="opt"` to enable."""
load("@rules_cc//cc:defs.bzl", "CcInfo")
load("@rules_rust//rust:rust_common.bzl", "COMMON_PROVIDERS")
def _transition_alias_impl(ctx):
# `ctx.attr.actual` is a list of 1 item due to the transition
providers = [ctx.attr.actual[0][provider] for provider in COMMON_PROVIDERS]
if CcInfo in ctx.attr.actual[0]:
providers.append(ctx.attr.actual[0][CcInfo])
return providers
def _change_compilation_mode(compilation_mode):
def _change_compilation_mode_impl(_settings, _attr):
return {
"//command_line_option:compilation_mode": compilation_mode,
}
return transition(
implementation = _change_compilation_mode_impl,
inputs = [],
outputs = [
"//command_line_option:compilation_mode",
],
)
def _transition_alias_rule(compilation_mode):
return rule(
implementation = _transition_alias_impl,
provides = COMMON_PROVIDERS,
attrs = {
"actual": attr.label(
mandatory = True,
doc = "`rust_library()` target to transition to `compilation_mode=opt`.",
providers = COMMON_PROVIDERS,
cfg = _change_compilation_mode(compilation_mode),
),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
doc = "Transitions a Rust library crate to the `compilation_mode=opt`.",
)
transition_alias_dbg = _transition_alias_rule("dbg")
transition_alias_fastbuild = _transition_alias_rule("fastbuild")
transition_alias_opt = _transition_alias_rule("opt")
================================================
FILE: bazel/cargo/remote/crates.bzl
================================================
###############################################################################
# @generated
# This file is auto-generated by the cargo-bazel tool.
#
# DO NOT MODIFY: Local changes may be replaced in future executions.
###############################################################################
"""Rules for defining repositories for remote `crates_vendor` repositories"""
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
# buildifier: disable=bzl-visibility
load("@proxy_wasm_rust_sdk//bazel/cargo/remote:defs.bzl", _crate_repositories = "crate_repositories")
# buildifier: disable=bzl-visibility
load("@rules_rust//crate_universe/private:crates_vendor.bzl", "crates_vendor_remote_repository")
def crate_repositories():
"""Generates repositories for vendored crates.
Returns:
A list of repos visible to the module through the module extension.
"""
maybe(
crates_vendor_remote_repository,
name = "crates_vendor",
build_file = Label("@proxy_wasm_rust_sdk//bazel/cargo/remote:BUILD.bazel"),
defs_module = Label("@proxy_wasm_rust_sdk//bazel/cargo/remote:defs.bzl"),
)
direct_deps = [struct(repo = "crates_vendor", is_dev_dep = False)]
direct_deps.extend(_crate_repositories())
return direct_deps
================================================
FILE: bazel/cargo/remote/defs.bzl
================================================
###############################################################################
# @generated
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
# regenerate this file, run the following:
#
# bazel run @//bazel/cargo:crates_vendor
###############################################################################
"""
# `crates_repository` API
- [aliases](#aliases)
- [crate_deps](#crate_deps)
- [all_crate_deps](#all_crate_deps)
- [crate_repositories](#crate_repositories)
"""
load("@bazel_skylib//lib:selects.bzl", "selects")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
###############################################################################
# MACROS API
###############################################################################
# An identifier that represent common dependencies (unconditional).
_COMMON_CONDITION = ""
def _flatten_dependency_maps(all_dependency_maps):
"""Flatten a list of dependency maps into one dictionary.
Dependency maps have the following structure:
```python
DEPENDENCIES_MAP = {
# The first key in the map is a Bazel package
# name of the workspace this file is defined in.
"workspace_member_package": {
# Not all dependencies are supported for all platforms.
# the condition key is the condition required to be true
# on the host platform.
"condition": {
# An alias to a crate target. # The label of the crate target the
# Aliases are only crate names. # package name refers to.
"package_name": "@full//:label",
}
}
}
```
Args:
all_dependency_maps (list): A list of dicts as described above
Returns:
dict: A dictionary as described above
"""
dependencies = {}
for workspace_deps_map in all_dependency_maps:
for pkg_name, conditional_deps_map in workspace_deps_map.items():
if pkg_name not in dependencies:
non_frozen_map = dict()
for key, values in conditional_deps_map.items():
non_frozen_map.update({key: dict(values.items())})
dependencies.setdefault(pkg_name, non_frozen_map)
continue
for condition, deps_map in conditional_deps_map.items():
# If the condition has not been recorded, do so and continue
if condition not in dependencies[pkg_name]:
dependencies[pkg_name].setdefault(condition, dict(deps_map.items()))
continue
# Alert on any miss-matched dependencies
inconsistent_entries = []
for crate_name, crate_label in deps_map.items():
existing = dependencies[pkg_name][condition].get(crate_name)
if existing and existing != crate_label:
inconsistent_entries.append((crate_name, existing, crate_label))
dependencies[pkg_name][condition].update({crate_name: crate_label})
return dependencies
def crate_deps(deps, package_name = None):
"""Finds the fully qualified label of the requested crates for the package where this macro is called.
Args:
deps (list): The desired list of crate targets.
package_name (str, optional): The package name of the set of dependencies to look up.
Defaults to `native.package_name()`.
Returns:
list: A list of labels to generated rust targets (str)
"""
if not deps:
return []
if package_name == None:
package_name = native.package_name()
# Join both sets of dependencies
dependencies = _flatten_dependency_maps([
_NORMAL_DEPENDENCIES,
_NORMAL_DEV_DEPENDENCIES,
_PROC_MACRO_DEPENDENCIES,
_PROC_MACRO_DEV_DEPENDENCIES,
_BUILD_DEPENDENCIES,
_BUILD_PROC_MACRO_DEPENDENCIES,
]).pop(package_name, {})
# Combine all conditional packages so we can easily index over a flat list
# TODO: Perhaps this should actually return select statements and maintain
# the conditionals of the dependencies
flat_deps = {}
for deps_set in dependencies.values():
for crate_name, crate_label in deps_set.items():
flat_deps.update({crate_name: crate_label})
missing_crates = []
crate_targets = []
for crate_target in deps:
if crate_target not in flat_deps:
missing_crates.append(crate_target)
else:
crate_targets.append(flat_deps[crate_target])
if missing_crates:
fail("Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`".format(
missing_crates,
package_name,
dependencies,
))
return crate_targets
def all_crate_deps(
normal = False,
normal_dev = False,
proc_macro = False,
proc_macro_dev = False,
build = False,
build_proc_macro = False,
package_name = None):
"""Finds the fully qualified label of all requested direct crate dependencies \
for the package where this macro is called.
If no parameters are set, all normal dependencies are returned. Setting any one flag will
otherwise impact the contents of the returned list.
Args:
normal (bool, optional): If True, normal dependencies are included in the
output list.
normal_dev (bool, optional): If True, normal dev dependencies will be
included in the output list..
proc_macro (bool, optional): If True, proc_macro dependencies are included
in the output list.
proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are
included in the output list.
build (bool, optional): If True, build dependencies are included
in the output list.
build_proc_macro (bool, optional): If True, build proc_macro dependencies are
included in the output list.
package_name (str, optional): The package name of the set of dependencies to look up.
Defaults to `native.package_name()` when unset.
Returns:
list: A list of labels to generated rust targets (str)
"""
if package_name == None:
package_name = native.package_name()
# Determine the relevant maps to use
all_dependency_maps = []
if normal:
all_dependency_maps.append(_NORMAL_DEPENDENCIES)
if normal_dev:
all_dependency_maps.append(_NORMAL_DEV_DEPENDENCIES)
if proc_macro:
all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES)
if proc_macro_dev:
all_dependency_maps.append(_PROC_MACRO_DEV_DEPENDENCIES)
if build:
all_dependency_maps.append(_BUILD_DEPENDENCIES)
if build_proc_macro:
all_dependency_maps.append(_BUILD_PROC_MACRO_DEPENDENCIES)
# Default to always using normal dependencies
if not all_dependency_maps:
all_dependency_maps.append(_NORMAL_DEPENDENCIES)
dependencies = _flatten_dependency_maps(all_dependency_maps).pop(package_name, None)
if not dependencies:
if dependencies == None:
fail("Tried to get all_crate_deps for package " + package_name + " but that package had no Cargo.toml file")
else:
return []
crate_deps = list(dependencies.pop(_COMMON_CONDITION, {}).values())
for condition, deps in dependencies.items():
crate_deps += selects.with_or({
tuple(_CONDITIONS[condition]): deps.values(),
"//conditions:default": [],
})
return crate_deps
def aliases(
normal = False,
normal_dev = False,
proc_macro = False,
proc_macro_dev = False,
build = False,
build_proc_macro = False,
package_name = None):
"""Produces a map of Crate alias names to their original label
If no dependency kinds are specified, `normal` and `proc_macro` are used by default.
Setting any one flag will otherwise determine the contents of the returned dict.
Args:
normal (bool, optional): If True, normal dependencies are included in the
output list.
normal_dev (bool, optional): If True, normal dev dependencies will be
included in the output list..
proc_macro (bool, optional): If True, proc_macro dependencies are included
in the output list.
proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are
included in the output list.
build (bool, optional): If True, build dependencies are included
in the output list.
build_proc_macro (bool, optional): If True, build proc_macro dependencies are
included in the output list.
package_name (str, optional): The package name of the set of dependencies to look up.
Defaults to `native.package_name()` when unset.
Returns:
dict: The aliases of all associated packages
"""
if package_name == None:
package_name = native.package_name()
# Determine the relevant maps to use
all_aliases_maps = []
if normal:
all_aliases_maps.append(_NORMAL_ALIASES)
if normal_dev:
all_aliases_maps.append(_NORMAL_DEV_ALIASES)
if proc_macro:
all_aliases_maps.append(_PROC_MACRO_ALIASES)
if proc_macro_dev:
all_aliases_maps.append(_PROC_MACRO_DEV_ALIASES)
if build:
all_aliases_maps.append(_BUILD_ALIASES)
if build_proc_macro:
all_aliases_maps.append(_BUILD_PROC_MACRO_ALIASES)
# Default to always using normal aliases
if not all_aliases_maps:
all_aliases_maps.append(_NORMAL_ALIASES)
all_aliases_maps.append(_PROC_MACRO_ALIASES)
aliases = _flatten_dependency_maps(all_aliases_maps).pop(package_name, None)
if not aliases:
return dict()
common_items = aliases.pop(_COMMON_CONDITION, {}).items()
# If there are only common items in the dictionary, immediately return them
if not len(aliases.keys()) == 1:
return dict(common_items)
# Build a single select statement where each conditional has accounted for the
# common set of aliases.
crate_aliases = {"//conditions:default": dict(common_items)}
for condition, deps in aliases.items():
condition_triples = _CONDITIONS[condition]
for triple in condition_triples:
if triple in crate_aliases:
crate_aliases[triple].update(deps)
else:
crate_aliases.update({triple: dict(deps.items() + common_items)})
return select(crate_aliases)
###############################################################################
# WORKSPACE MEMBER DEPS AND ALIASES
###############################################################################
_NORMAL_DEPENDENCIES = {
"": {
_COMMON_CONDITION: {
"hashbrown": Label("@crates_vendor//:hashbrown-0.16.0"),
"log": Label("@crates_vendor//:log-0.4.27"),
},
},
}
_NORMAL_ALIASES = {
"": {
_COMMON_CONDITION: {
},
},
}
_NORMAL_DEV_DEPENDENCIES = {
"": {
},
}
_NORMAL_DEV_ALIASES = {
"": {
},
}
_PROC_MACRO_DEPENDENCIES = {
"": {
},
}
_PROC_MACRO_ALIASES = {
"": {
},
}
_PROC_MACRO_DEV_DEPENDENCIES = {
"": {
},
}
_PROC_MACRO_DEV_ALIASES = {
"": {
},
}
_BUILD_DEPENDENCIES = {
"": {
},
}
_BUILD_ALIASES = {
"": {
},
}
_BUILD_PROC_MACRO_DEPENDENCIES = {
"": {
},
}
_BUILD_PROC_MACRO_ALIASES = {
"": {
},
}
_CONDITIONS = {
"aarch64-apple-darwin": ["@rules_rust//rust/platform:aarch64-apple-darwin"],
"aarch64-apple-ios": ["@rules_rust//rust/platform:aarch64-apple-ios"],
"aarch64-apple-ios-sim": ["@rules_rust//rust/platform:aarch64-apple-ios-sim"],
"aarch64-linux-android": ["@rules_rust//rust/platform:aarch64-linux-android"],
"aarch64-pc-windows-msvc": ["@rules_rust//rust/platform:aarch64-pc-windows-msvc"],
"aarch64-unknown-fuchsia": ["@rules_rust//rust/platform:aarch64-unknown-fuchsia"],
"aarch64-unknown-linux-gnu": ["@rules_rust//rust/platform:aarch64-unknown-linux-gnu"],
"aarch64-unknown-nixos-gnu": ["@rules_rust//rust/platform:aarch64-unknown-nixos-gnu"],
"aarch64-unknown-nto-qnx710": ["@rules_rust//rust/platform:aarch64-unknown-nto-qnx710"],
"aarch64-unknown-uefi": ["@rules_rust//rust/platform:aarch64-unknown-uefi"],
"arm-unknown-linux-gnueabi": ["@rules_rust//rust/platform:arm-unknown-linux-gnueabi"],
"armv7-linux-androideabi": ["@rules_rust//rust/platform:armv7-linux-androideabi"],
"armv7-unknown-linux-gnueabi": ["@rules_rust//rust/platform:armv7-unknown-linux-gnueabi"],
"i686-apple-darwin": ["@rules_rust//rust/platform:i686-apple-darwin"],
"i686-linux-android": ["@rules_rust//rust/platform:i686-linux-android"],
"i686-pc-windows-msvc": ["@rules_rust//rust/platform:i686-pc-windows-msvc"],
"i686-unknown-freebsd": ["@rules_rust//rust/platform:i686-unknown-freebsd"],
"i686-unknown-linux-gnu": ["@rules_rust//rust/platform:i686-unknown-linux-gnu"],
"powerpc-unknown-linux-gnu": ["@rules_rust//rust/platform:powerpc-unknown-linux-gnu"],
"riscv32imc-unknown-none-elf": ["@rules_rust//rust/platform:riscv32imc-unknown-none-elf"],
"riscv64gc-unknown-linux-gnu": ["@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu"],
"riscv64gc-unknown-none-elf": ["@rules_rust//rust/platform:riscv64gc-unknown-none-elf"],
"s390x-unknown-linux-gnu": ["@rules_rust//rust/platform:s390x-unknown-linux-gnu"],
"thumbv7em-none-eabi": ["@rules_rust//rust/platform:thumbv7em-none-eabi"],
"thumbv8m.main-none-eabi": ["@rules_rust//rust/platform:thumbv8m.main-none-eabi"],
"wasm32-unknown-emscripten": ["@rules_rust//rust/platform:wasm32-unknown-emscripten"],
"wasm32-unknown-unknown": ["@rules_rust//rust/platform:wasm32-unknown-unknown"],
"wasm32-wasip1": ["@rules_rust//rust/platform:wasm32-wasip1"],
"wasm32-wasip1-threads": ["@rules_rust//rust/platform:wasm32-wasip1-threads"],
"wasm32-wasip2": ["@rules_rust//rust/platform:wasm32-wasip2"],
"x86_64-apple-darwin": ["@rules_rust//rust/platform:x86_64-apple-darwin"],
"x86_64-apple-ios": ["@rules_rust//rust/platform:x86_64-apple-ios"],
"x86_64-linux-android": ["@rules_rust//rust/platform:x86_64-linux-android"],
"x86_64-pc-windows-msvc": ["@rules_rust//rust/platform:x86_64-pc-windows-msvc"],
"x86_64-unknown-freebsd": ["@rules_rust//rust/platform:x86_64-unknown-freebsd"],
"x86_64-unknown-fuchsia": ["@rules_rust//rust/platform:x86_64-unknown-fuchsia"],
"x86_64-unknown-linux-gnu": ["@rules_rust//rust/platform:x86_64-unknown-linux-gnu"],
"x86_64-unknown-nixos-gnu": ["@rules_rust//rust/platform:x86_64-unknown-nixos-gnu"],
"x86_64-unknown-none": ["@rules_rust//rust/platform:x86_64-unknown-none"],
"x86_64-unknown-uefi": ["@rules_rust//rust/platform:x86_64-unknown-uefi"],
}
###############################################################################
def crate_repositories():
"""A macro for defining repositories for all generated crates.
Returns:
A list of repos visible to the module through the module extension.
"""
maybe(
http_archive,
name = "crates_vendor__allocator-api2-0.2.21",
sha256 = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923",
type = "tar.gz",
urls = ["https://static.crates.io/crates/allocator-api2/0.2.21/download"],
strip_prefix = "allocator-api2-0.2.21",
build_file = Label("@proxy_wasm_rust_sdk//bazel/cargo/remote:BUILD.allocator-api2-0.2.21.bazel"),
)
maybe(
http_archive,
name = "crates_vendor__equivalent-1.0.2",
sha256 = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f",
type = "tar.gz",
urls = ["https://static.crates.io/crates/equivalent/1.0.2/download"],
strip_prefix = "equivalent-1.0.2",
build_file = Label("@proxy_wasm_rust_sdk//bazel/cargo/remote:BUILD.equivalent-1.0.2.bazel"),
)
maybe(
http_archive,
name = "crates_vendor__foldhash-0.2.0",
sha256 = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb",
type = "tar.gz",
urls = ["https://static.crates.io/crates/foldhash/0.2.0/download"],
strip_prefix = "foldhash-0.2.0",
build_file = Label("@proxy_wasm_rust_sdk//bazel/cargo/remote:BUILD.foldhash-0.2.0.bazel"),
)
maybe(
http_archive,
name = "crates_vendor__hashbrown-0.16.0",
sha256 = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d",
type = "tar.gz",
urls = ["https://static.crates.io/crates/hashbrown/0.16.0/download"],
strip_prefix = "hashbrown-0.16.0",
build_file = Label("@proxy_wasm_rust_sdk//bazel/cargo/remote:BUILD.hashbrown-0.16.0.bazel"),
)
maybe(
http_archive,
name = "crates_vendor__log-0.4.27",
sha256 = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94",
type = "tar.gz",
urls = ["https://static.crates.io/crates/log/0.4.27/download"],
strip_prefix = "log-0.4.27",
build_file = Label("@proxy_wasm_rust_sdk//bazel/cargo/remote:BUILD.log-0.4.27.bazel"),
)
return [
struct(repo = "crates_vendor__hashbrown-0.16.0", is_dev_dep = False),
struct(repo = "crates_vendor__log-0.4.27", is_dev_dep = False),
]
================================================
FILE: bazel/dependencies_bazel.bzl
================================================
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@bazel_features//:deps.bzl", "bazel_features_deps")
def proxy_wasm_rust_sdk_dependencies_bazel():
bazel_features_deps()
================================================
FILE: bazel/dependencies_compat.bzl
================================================
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@rules_cc//cc:extensions.bzl", "compatibility_proxy_repo")
def proxy_wasm_rust_sdk_dependencies_compat():
compatibility_proxy_repo()
================================================
FILE: bazel/dependencies_crates.bzl
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@proxy_wasm_rust_sdk//bazel/cargo/remote:defs.bzl", "crate_repositories")
load("@rules_rust//crate_universe:repositories.bzl", "crate_universe_dependencies")
load("@rules_rust//rust:repositories.bzl", "rust_repositories")
def proxy_wasm_rust_sdk_dependencies_crates():
rust_repositories(versions = ["1.91.1"])
crate_universe_dependencies()
crate_repositories()
================================================
FILE: bazel/extensions.bzl
================================================
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@bazel_features//:features.bzl", "bazel_features")
load("@proxy_wasm_rust_sdk//bazel/cargo/remote:crates.bzl", "crate_repositories")
def _crates_deps_impl(module_ctx):
deps = []
for repo in crate_repositories():
if not repo.is_dev_dep:
deps.append(repo.repo)
return module_ctx.extension_metadata(
reproducible = bazel_features.external_deps.extension_metadata_has_reproducible,
root_module_direct_deps = deps,
root_module_direct_dev_deps = [],
)
crates_deps = module_extension(
doc = "Dependencies for the Proxy-Wasm Rust SDK.",
implementation = _crates_deps_impl,
)
================================================
FILE: bazel/repositories.bzl
================================================
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
def proxy_wasm_rust_sdk_repositories():
maybe(
http_archive,
name = "bazel_features",
sha256 = "07271d0f6b12633777b69020c4cb1eb67b1939c0cf84bb3944dc85cc250c0c01",
url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.38.0/bazel_features-v1.38.0.tar.gz",
strip_prefix = "bazel_features-1.38.0",
)
maybe(
http_archive,
name = "rules_cc",
sha256 = "a2fdfde2ab9b2176bd6a33afca14458039023edb1dd2e73e6823810809df4027",
url = "https://github.com/bazelbuild/rules_cc/releases/download/0.2.14/rules_cc-0.2.14.tar.gz",
strip_prefix = "rules_cc-0.2.14",
)
maybe(
http_archive,
name = "rules_rust",
integrity = "sha256-yKqAbPYGZnmsI0YyQe6ArWkiZdrQRl9RERy74wuJA1I=",
url = "https://github.com/bazelbuild/rules_rust/releases/download/0.68.1/rules_rust-0.68.1.tar.gz",
)
maybe(
http_archive,
name = "bazel_skylib",
sha256 = "6e78f0e57de26801f6f564fa7c4a48dc8b36873e416257a92bbb0937eeac8446",
url = "https://github.com/bazelbuild/bazel-skylib/releases/download/1.8.2/bazel-skylib-1.8.2.tar.gz",
)
================================================
FILE: build.rs
================================================
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-env-changed=RUSTFLAGS");
println!("cargo:rustc-check-cfg=cfg(nightly)");
println!("cargo:rustc-check-cfg=cfg(wasi_exec_model_reactor)");
if let Some(toolchain) = std::env::var_os("RUSTUP_TOOLCHAIN") {
if toolchain.to_string_lossy().contains("nightly") {
println!("cargo:rustc-cfg=nightly");
}
}
if let Some(target_os) = std::env::var_os("CARGO_CFG_TARGET_OS") {
if target_os != "wasi" {
return;
}
}
if let Some(rustflags) = std::env::var_os("CARGO_ENCODED_RUSTFLAGS") {
for flag in rustflags.to_string_lossy().split('\x1f') {
if flag.ends_with("wasi-exec-model=reactor") {
println!("cargo:rustc-cfg=wasi_exec_model_reactor");
return;
}
}
}
}
================================================
FILE: examples/envoy_filter_metadata/Cargo.toml
================================================
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
publish = false
name = "proxy-wasm-example-envoy-filter-metadata"
version = "0.0.1"
authors = ["Martijn Swaagma <martijn@swaagman.online>"]
description = "Proxy-Wasm plugin example: Envoy filter metadata"
license = "Apache-2.0"
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
proxy-wasm = { path = "../../" }
[profile.release]
lto = true
opt-level = 3
codegen-units = 1
panic = "abort"
strip = "debuginfo"
================================================
FILE: examples/envoy_filter_metadata/README.md
================================================
## Proxy-Wasm plugin example: Envoy metadata
Proxy-Wasm plugin that demonstrates reading metadata set by other Envoy filters.
### Building
```sh
$ cargo build --target wasm32-wasip1 --release
```
### Using in Envoy
This example can be run with [`docker compose`](https://docs.docker.com/compose/install/)
and has a matching Envoy configuration.
```sh
$ docker compose up
```
Send a HTTP request to `localhost:10000` that will return the configured response.
```sh
$ curl localhost:10000
Welcome, set the `x-custom-metadata` header to change the response!
```
Send a HTTP request to `localhost:10000` with a `x-custom-metadata` header value to get
the uppercased value in the response.
The response will also contain a response header `uppercased-metadata: SOME-VALUE`.
```sh
$ curl localhost:10000 -H "x-custom-metadata: some-value"
Custom response with Envoy metadata: "SOME-VALUE"
```
================================================
FILE: examples/envoy_filter_metadata/docker-compose.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services:
envoy:
image: envoyproxy/envoy:v1.34-latest
hostname: envoy
ports:
- "10000:10000"
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
- ./target/wasm32-wasip1/release:/etc/envoy/proxy-wasm-plugins
networks:
- envoymesh
networks:
envoymesh: {}
================================================
FILE: examples/envoy_filter_metadata/envoy.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_resources:
listeners:
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_routes
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: "/"
direct_response:
status: 200
body:
inline_string: "Welcome, set the `x-custom-metadata` header to change the response!\n"
http_filters:
# Set uppercase metadata in Lua filter
- name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
default_source_code:
inline_string: |
function envoy_on_request(request_handle)
local headers = request_handle:headers()
local data = headers:get("x-custom-metadata")
if data then
request_handle:streamInfo():dynamicMetadata():set("envoy.filters.http.lua", "uppercased-custom-metadata", string.upper(data))
end
request_handle:logInfo("Metadata set by lua filter")
end
# Read it from a WASM filter
- name: envoy.filters.http.wasm
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
name: "envoy_metadata_filter"
vm_config:
runtime: "envoy.wasm.runtime.v8"
code:
local:
filename: "/etc/envoy/proxy-wasm-plugins/proxy_wasm_example_envoy_filter_metadata.wasm"
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
================================================
FILE: examples/envoy_filter_metadata/src/lib.rs
================================================
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use proxy_wasm::traits::*;
use proxy_wasm::types::*;
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_http_context(|_, _| -> Box<dyn HttpContext> { Box::new(MetadataHttp {}) });
}}
struct MetadataHttp {}
impl Context for MetadataHttp {}
impl HttpContext for MetadataHttp {
fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
// Read data set by the lua filter
match self.get_property(vec![
"metadata",
"filter_metadata",
"envoy.filters.http.lua",
"uppercased-custom-metadata",
]) {
Some(metadata) => match String::from_utf8(metadata) {
Ok(data) => {
self.send_http_response(
200,
vec![("Powered-By", "proxy-wasm"), ("uppercased-metadata", &data)],
Some(format!("Custom response with Envoy metadata: {data:?}\n").as_bytes()),
);
Action::Pause
}
_ => Action::Continue,
},
_ => Action::Continue,
}
}
}
================================================
FILE: examples/grpc_auth_random/Cargo.toml
================================================
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
publish = false
name = "proxy-wasm-example-grpc-auth-random"
version = "0.0.1"
description = "Proxy-Wasm plugin example: gRPC auth (random)"
license = "Apache-2.0"
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
log = "0.4"
proxy-wasm = { path = "../../" }
[profile.release]
lto = true
opt-level = 3
codegen-units = 1
panic = "abort"
strip = "debuginfo"
================================================
FILE: examples/grpc_auth_random/README.md
================================================
## Proxy-Wasm plugin example: gRPC auth (random)
Proxy-Wasm plugin that grants access based on a result of gRPC callout.
### Building
```sh
$ cargo build --target wasm32-wasip1 --release
```
### Using in Envoy
This example can be run with [`docker compose`](https://docs.docker.com/compose/install/)
and has a matching Envoy configuration.
```sh
$ docker compose up
```
#### Access granted.
Send gRPC request to `localhost:10000` service `hello.HelloService`:
```sh
$ grpcurl -d '{"greeting": "Rust"}' -plaintext localhost:10000 hello.HelloService/SayHello
{
"reply": "hello Rust"
}
```
Expected Envoy logs:
```console
[...] wasm log grpc_auth_random: Access granted.
```
#### Access forbidden.
Send gRPC request to `localhost:10000` service `hello.HelloService`:
```sh
$ grpcurl -d '{"greeting": "Rust"}' -plaintext localhost:10000 hello.HelloService/SayHello
ERROR:
Code: Aborted
Message: Aborted by Proxy-Wasm!
```
Expected Envoy logs:
```console
[...] wasm log grpc_auth_random: Access forbidden.
```
================================================
FILE: examples/grpc_auth_random/docker-compose.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services:
envoy:
image: envoyproxy/envoy:v1.34-latest
hostname: envoy
ports:
- "10000:10000"
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
- ./target/wasm32-wasip1/release:/etc/envoy/proxy-wasm-plugins
networks:
- envoymesh
depends_on:
- grpcbin
grpcbin:
image: kong/grpcbin
hostname: grpcbin
ports:
- "9000:9000"
networks:
- envoymesh
networks:
envoymesh: {}
================================================
FILE: examples/grpc_auth_random/envoy.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_resources:
listeners:
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_routes
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: grpcbin
http_filters:
- name: envoy.filters.http.wasm
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
name: "grpc_auth_random"
vm_config:
runtime: "envoy.wasm.runtime.v8"
code:
local:
filename: "/etc/envoy/proxy-wasm-plugins/proxy_wasm_example_grpc_auth_random.wasm"
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: grpcbin
connect_timeout: 5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
http2_protocol_options: {}
load_assignment:
cluster_name: grpcbin
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: grpcbin
port_value: 9000
================================================
FILE: examples/grpc_auth_random/src/lib.rs
================================================
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use log::info;
use proxy_wasm::traits::*;
use proxy_wasm::types::*;
use std::time::Duration;
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_http_context(|_, _| -> Box<dyn HttpContext> { Box::new(GrpcAuthRandom) });
}}
struct GrpcAuthRandom;
impl HttpContext for GrpcAuthRandom {
fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
match self.get_http_request_header("content-type") {
Some(value) if value.starts_with("application/grpc") => {}
_ => {
// Reject non-gRPC clients.
self.send_http_response(
503,
vec![("Powered-By", "proxy-wasm")],
Some(b"Service accessible only to gRPC clients.\n"),
);
return Action::Pause;
}
}
match self.get_http_request_header(":path") {
Some(value) if value.starts_with("/grpc.reflection") => {
// Always allow gRPC calls to the reflection API.
Action::Continue
}
_ => {
// Allow other gRPC calls based on the result of grpcbin.GRPCBin/RandomError.
self.dispatch_grpc_call(
"grpcbin",
"grpcbin.GRPCBin",
"RandomError",
vec![],
None,
Duration::from_secs(1),
)
.unwrap();
Action::Pause
}
}
}
fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action {
self.set_http_response_header("Powered-By", Some("proxy-wasm"));
Action::Continue
}
}
impl Context for GrpcAuthRandom {
fn on_grpc_call_response(&mut self, _: u32, status_code: u32, _: usize) {
#[allow(unknown_lints, clippy::manual_is_multiple_of)]
if status_code % 2 == 0 {
info!("Access granted.");
self.resume_http_request();
} else {
info!("Access forbidden.");
self.send_grpc_response(
GrpcStatusCode::Aborted,
Some("Aborted by Proxy-Wasm!"),
vec![("Powered-By", b"proxy-wasm")],
);
}
}
}
================================================
FILE: examples/hello_world/Cargo.toml
================================================
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
publish = false
name = "proxy-wasm-example-hello-world"
version = "0.0.1"
authors = ["Piotr Sikora <piotrsikora@google.com>"]
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 = { path = "../../" }
[target.'cfg(not(all(target_arch = "wasm32", target_os = "unknown")))'.dependencies]
getrandom = "0.4"
[profile.release]
lto = true
opt-level = 3
codegen-units = 1
panic = "abort"
strip = "debuginfo"
================================================
FILE: examples/hello_world/README.md
================================================
## Proxy-Wasm plugin example: Hello World
Proxy-Wasm background service plugin that logs time and random numbers.
### Building
```sh
$ cargo build --target wasm32-wasip1 --release
```
### Using in Envoy
This example can be run with [`docker compose`](https://docs.docker.com/compose/install/)
and has a matching Envoy configuration.
```sh
$ docker compose up
```
Expected Envoy logs (new line generated every 5s):
```console
[...] wasm log: Hello, World!
[...] wasm log: It's 2022-11-22 03:39:17.849616 UTC, your lucky number is 41.
[...] wasm log: It's 2022-11-22 03:39:22.846531 UTC, your lucky number is 28.
[...] wasm log: It's 2022-11-22 03:39:27.847489 UTC, your lucky number is 102.
[...] wasm log: It's 2022-11-22 03:39:32.848443 UTC, your lucky number is 250.
```
================================================
FILE: examples/hello_world/docker-compose.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services:
envoy:
image: envoyproxy/envoy:v1.34-latest
hostname: envoy
ports:
- "10000:10000"
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
- ./target/wasm32-wasip1/release:/etc/envoy/proxy-wasm-plugins
networks:
- envoymesh
networks:
envoymesh: {}
================================================
FILE: examples/hello_world/envoy.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
bootstrap_extensions:
- name: envoy.bootstrap.wasm
typed_config:
"@type": type.googleapis.com/envoy.extensions.wasm.v3.WasmService
singleton: true
config:
name: "hello_world"
vm_config:
runtime: "envoy.wasm.runtime.v8"
code:
local:
filename: "/etc/envoy/proxy-wasm-plugins/proxy_wasm_example_hello_world.wasm"
================================================
FILE: examples/hello_world/src/lib.rs
================================================
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use cfg_if::cfg_if;
use chrono::{DateTime, Utc};
use log::info;
use proxy_wasm::traits::*;
use proxy_wasm::types::*;
use std::time::Duration;
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> { 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<Utc> = self.get_current_time().into();
info!("It's {}, there is no lucky number.", now);
} else {
let now: DateTime<Utc> = Utc::now();
let mut buf = [0u8; 1];
getrandom::fill(&mut buf).unwrap();
info!("It's {}, your lucky number is {}.", now, buf[0]);
}
}
}
}
================================================
FILE: examples/http_auth_random/Cargo.toml
================================================
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
publish = false
name = "proxy-wasm-example-http-auth-random"
version = "0.0.1"
authors = ["Piotr Sikora <piotrsikora@google.com>"]
description = "Proxy-Wasm plugin example: HTTP auth (random)"
license = "Apache-2.0"
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
log = "0.4"
proxy-wasm = { path = "../../" }
[profile.release]
lto = true
opt-level = 3
codegen-units = 1
panic = "abort"
strip = "debuginfo"
================================================
FILE: examples/http_auth_random/README.md
================================================
## Proxy-Wasm plugin example: HTTP auth (random)
Proxy-Wasm plugin that grants access based on a result of HTTP callout.
### Building
```sh
$ cargo build --target wasm32-wasip1 --release
```
### Using in Envoy
This example can be run with [`docker compose`](https://docs.docker.com/compose/install/)
and has a matching Envoy configuration.
```sh
$ docker compose up
```
#### Access granted.
Send HTTP request to `localhost:10000/headers`:
```sh
$ curl localhost:10000/headers
{
"headers": {
"Accept": "*/*",
"Host": "localhost",
"User-Agent": "curl/7.81.0",
"X-Amzn-Trace-Id": "Root=1-637c4767-6e31776a0b407a0219b5b570",
"X-Envoy-Expected-Rq-Timeout-Ms": "15000"
}
}
```
Expected Envoy logs:
```console
[...] wasm log http_auth_random: Access granted.
```
#### Access forbidden.
Send HTTP request to `localhost:10000/headers`:
```sh
$ curl localhost:10000/headers
Access forbidden.
```
Expected Envoy logs:
```console
[...] wasm log http_auth_random: Access forbidden.
```
================================================
FILE: examples/http_auth_random/docker-compose.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services:
envoy:
image: envoyproxy/envoy:v1.34-latest
hostname: envoy
ports:
- "10000:10000"
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
- ./target/wasm32-wasip1/release:/etc/envoy/proxy-wasm-plugins
networks:
- envoymesh
depends_on:
- httpbin
httpbin:
image: mccutchen/go-httpbin
hostname: httpbin
ports:
- "8080:8080"
networks:
- envoymesh
networks:
envoymesh: {}
================================================
FILE: examples/http_auth_random/envoy.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_resources:
listeners:
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_routes
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: httpbin
http_filters:
- name: envoy.filters.http.wasm
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
name: "http_auth_random"
vm_config:
runtime: "envoy.wasm.runtime.v8"
code:
local:
filename: "/etc/envoy/proxy-wasm-plugins/proxy_wasm_example_http_auth_random.wasm"
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: httpbin
connect_timeout: 5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: httpbin
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: httpbin
port_value: 8080
================================================
FILE: examples/http_auth_random/src/lib.rs
================================================
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use log::info;
use proxy_wasm::traits::*;
use proxy_wasm::types::*;
use std::time::Duration;
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_http_context(|_, _| -> Box<dyn HttpContext> { Box::new(HttpAuthRandom) });
}}
struct HttpAuthRandom;
impl HttpContext for HttpAuthRandom {
fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
self.dispatch_http_call(
"httpbin",
vec![
(":method", "GET"),
(":path", "/bytes/1"),
(":authority", "httpbin.org"),
],
None,
vec![],
Duration::from_secs(1),
)
.unwrap();
Action::Pause
}
fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action {
self.set_http_response_header("Powered-By", Some("proxy-wasm"));
Action::Continue
}
}
impl Context for HttpAuthRandom {
fn on_http_call_response(&mut self, _: u32, _: usize, body_size: usize, _: usize) {
if let Some(body) = self.get_http_call_response_body(0, body_size) {
#[allow(unknown_lints, clippy::manual_is_multiple_of)]
if !body.is_empty() && body[0] % 2 == 0 {
info!("Access granted.");
self.resume_http_request();
return;
}
}
info!("Access forbidden.");
self.send_http_response(
403,
vec![("Powered-By", "proxy-wasm")],
Some(b"Access forbidden.\n"),
);
}
}
================================================
FILE: examples/http_body/Cargo.toml
================================================
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
publish = false
name = "proxy-wasm-example-http-body"
version = "0.0.1"
authors = ["Piotr Sikora <piotrsikora@google.com>"]
description = "Proxy-Wasm plugin example: HTTP body"
license = "Apache-2.0"
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
proxy-wasm = { path = "../../" }
[profile.release]
lto = true
opt-level = 3
codegen-units = 1
panic = "abort"
strip = "debuginfo"
================================================
FILE: examples/http_body/README.md
================================================
## Proxy-Wasm plugin example: HTTP body
Proxy-Wasm plugin that redacts sensitive HTTP responses.
### Building
```sh
$ cargo build --target wasm32-wasip1 --release
```
### Using in Envoy
This example can be run with [`docker compose`](https://docs.docker.com/compose/install/)
and has a matching Envoy configuration.
```sh
$ docker compose up
```
#### Response without secrets.
Send HTTP request to `localhost:10000/hello`:
```sh
$ curl localhost:10000/hello
Everyone may read this message.
```
#### Response with (redacted) secrets.
Send HTTP request to `localhost:10000/secret`:
```sh
$ curl localhost:10000/secret
Original message body (50 bytes) redacted.
```
================================================
FILE: examples/http_body/docker-compose.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services:
envoy:
image: envoyproxy/envoy:v1.34-latest
hostname: envoy
ports:
- "10000:10000"
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
- ./target/wasm32-wasip1/release:/etc/envoy/proxy-wasm-plugins
networks:
- envoymesh
networks:
envoymesh: {}
================================================
FILE: examples/http_body/envoy.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_resources:
listeners:
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_routes
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: "/secret"
direct_response:
status: 200
body:
inline_string: "This secret message should not be read by anyone.\n"
- match:
prefix: "/"
direct_response:
status: 200
body:
inline_string: "Everyone may read this message.\n"
http_filters:
- name: envoy.filters.http.wasm
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
name: "http_body"
vm_config:
runtime: "envoy.wasm.runtime.v8"
code:
local:
filename: "/etc/envoy/proxy-wasm-plugins/proxy_wasm_example_http_body.wasm"
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
================================================
FILE: examples/http_body/src/lib.rs
================================================
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use proxy_wasm::traits::*;
use proxy_wasm::types::*;
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> { Box::new(HttpBodyRoot) });
}}
struct HttpBodyRoot;
impl Context for HttpBodyRoot {}
impl RootContext for HttpBodyRoot {
fn get_type(&self) -> Option<ContextType> {
Some(ContextType::HttpContext)
}
fn create_http_context(&self, _: u32) -> Option<Box<dyn HttpContext>> {
Some(Box::new(HttpBody))
}
}
struct HttpBody;
impl Context for HttpBody {}
impl HttpContext for HttpBody {
fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action {
// If there is a Content-Length header and we change the length of
// the body later, then clients will break. So remove it.
// We must do this here, because once we exit this function we
// can no longer modify the response headers.
self.set_http_response_header("content-length", None);
Action::Continue
}
fn on_http_response_body(&mut self, body_size: usize, end_of_stream: bool) -> Action {
if !end_of_stream {
// Wait -- we'll be called again when the complete body is buffered
// at the host side.
return Action::Pause;
}
// Replace the message body if it contains the text "secret".
// Since we returned "Pause" previuously, this will return the whole body.
if let Some(body_bytes) = self.get_http_response_body(0, body_size) {
let body_str = String::from_utf8(body_bytes).unwrap();
if body_str.contains("secret") {
let new_body = format!("Original message body ({body_size} bytes) redacted.\n");
self.set_http_response_body(0, body_size, &new_body.into_bytes());
}
}
Action::Continue
}
}
================================================
FILE: examples/http_config/Cargo.toml
================================================
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
publish = false
name = "proxy-wasm-example-http-config"
version = "0.0.1"
authors = ["Piotr Sikora <piotrsikora@google.com>"]
description = "Proxy-Wasm plugin example: HTTP config"
license = "Apache-2.0"
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
proxy-wasm = { path = "../../" }
[profile.release]
lto = true
opt-level = 3
codegen-units = 1
panic = "abort"
strip = "debuginfo"
================================================
FILE: examples/http_config/README.md
================================================
## Proxy-Wasm plugin example: HTTP config
Proxy-Wasm plugin that injects HTTP response header with a value from Envoy config.
### Building
```sh
$ cargo build --target wasm32-wasip1 --release
```
### Using in Envoy
This example can be run with [`docker compose`](https://docs.docker.com/compose/install/)
and has a matching Envoy configuration.
```sh
$ docker compose up
```
Send HTTP request to `localhost:10000/hello`:
```sh
$ curl -I localhost:10000/hello
HTTP/1.1 200 OK
content-length: 40
content-type: text/plain
custom-header: The secret to life is meaningless unless you discover it yourself
date: Tue, 22 Nov 2022 04:09:05 GMT
server: envoy
```
================================================
FILE: examples/http_config/docker-compose.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services:
envoy:
image: envoyproxy/envoy:v1.34-latest
hostname: envoy
ports:
- "10000:10000"
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
- ./target/wasm32-wasip1/release:/etc/envoy/proxy-wasm-plugins
networks:
- envoymesh
networks:
envoymesh: {}
================================================
FILE: examples/http_config/envoy.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_resources:
listeners:
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_routes
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: "/"
direct_response:
status: 200
body:
inline_string: "Inspect the HTTP header: custom-header.\n"
http_filters:
- name: envoy.filters.http.wasm
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
name: "http_config"
configuration:
"@type": "type.googleapis.com/google.protobuf.StringValue"
value: The secret to life is meaningless unless you discover it yourself
vm_config:
runtime: "envoy.wasm.runtime.v8"
code:
local:
filename: "/etc/envoy/proxy-wasm-plugins/proxy_wasm_example_http_config.wasm"
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
================================================
FILE: examples/http_config/src/lib.rs
================================================
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use proxy_wasm::traits::*;
use proxy_wasm::types::*;
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> {
Box::new(HttpConfigHeaderRoot {
header_content: String::new(),
})
});
}}
struct HttpConfigHeader {
header_content: String,
}
impl Context for HttpConfigHeader {}
impl HttpContext for HttpConfigHeader {
fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action {
self.add_http_response_header("custom-header", self.header_content.as_str());
Action::Continue
}
}
struct HttpConfigHeaderRoot {
header_content: String,
}
impl Context for HttpConfigHeaderRoot {}
impl RootContext for HttpConfigHeaderRoot {
fn on_configure(&mut self, _: usize) -> bool {
if let Some(config_bytes) = self.get_plugin_configuration() {
self.header_content = String::from_utf8(config_bytes).unwrap()
}
true
}
fn create_http_context(&self, _: u32) -> Option<Box<dyn HttpContext>> {
Some(Box::new(HttpConfigHeader {
header_content: self.header_content.clone(),
}))
}
fn get_type(&self) -> Option<ContextType> {
Some(ContextType::HttpContext)
}
}
================================================
FILE: examples/http_headers/Cargo.toml
================================================
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
publish = false
name = "proxy-wasm-example-http-headers"
version = "0.0.1"
authors = ["Piotr Sikora <piotrsikora@google.com>"]
description = "Proxy-Wasm plugin example: HTTP headers"
license = "Apache-2.0"
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
log = "0.4"
proxy-wasm = { path = "../../" }
[profile.release]
lto = true
opt-level = 3
codegen-units = 1
panic = "abort"
strip = "debuginfo"
================================================
FILE: examples/http_headers/README.md
================================================
## Proxy-Wasm plugin example: HTTP headers
Proxy-Wasm plugin that logs HTTP request/response headers.
### Building
```sh
$ cargo build --target wasm32-wasip1 --release
```
### Using in Envoy
This example can be run with [`docker compose`](https://docs.docker.com/compose/install/)
and has a matching Envoy configuration.
```sh
$ docker compose up
```
Send HTTP request to `localhost:10000/hello`:
```sh
$ curl localhost:10000/hello
Hello, World!
```
Expected Envoy logs:
```console
[...] wasm log http_headers: #2 -> :authority: localhost:10000
[...] wasm log http_headers: #2 -> :path: /hello
[...] wasm log http_headers: #2 -> :method: GET
[...] wasm log http_headers: #2 -> :scheme: http
[...] wasm log http_headers: #2 -> user-agent: curl/7.81.0
[...] wasm log http_headers: #2 -> accept: */*
[...] wasm log http_headers: #2 -> x-forwarded-proto: http
[...] wasm log http_headers: #2 -> x-request-id: 3ed6eb3b-ddce-4fdc-8862-ddb8f168d406
[...] wasm log http_headers: #2 <- :status: 200
[...] wasm log http_headers: #2 <- hello: World
[...] wasm log http_headers: #2 <- powered-by: proxy-wasm
[...] wasm log http_headers: #2 <- content-length: 14
[...] wasm log http_headers: #2 <- content-type: text/plain
[...] wasm log http_headers: #2 completed.
```
================================================
FILE: examples/http_headers/docker-compose.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services:
envoy:
image: envoyproxy/envoy:v1.34-latest
hostname: envoy
ports:
- "10000:10000"
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
- ./target/wasm32-wasip1/release:/etc/envoy/proxy-wasm-plugins
networks:
- envoymesh
networks:
envoymesh: {}
================================================
FILE: examples/http_headers/envoy.yaml
================================================
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_resources:
listeners:
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_routes
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: "/"
direct_response:
status: 200
body:
inline_string: "Request /hello and be welcomed!\n"
http_filters:
- name: envoy.filters.http.wasm
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
name: "http_headers"
vm_config:
runtime: "envoy.wasm.runtime.v8"
code:
local:
filename: "/etc/envoy/proxy-wasm-plugins/proxy_wasm_example_http_headers.wasm"
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
================================================
FILE: examples/http_headers/src/lib.rs
================================================
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use log::info;
use proxy_wasm::traits::*;
use proxy_wasm::types::*;
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> { Box::new(HttpHeadersRoot) });
}}
struct HttpHeadersRoot;
impl Context for HttpHeadersRoot {}
impl RootContext for HttpHeadersRoot {
fn get_type(&self) -> Option<ContextType> {
Some(ContextType::HttpContext)
}
fn create_http_context(&self, context_id: u32) -> Option<Box<dyn HttpContext>> {
Some(Box::new(HttpHeaders { context_id }))
}
}
struct HttpHeaders {
context_id: u32,
}
impl Context for HttpHeaders {}
impl HttpContext for HttpHeaders {
fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
for (name, value) in &self.get_http_request_headers() {
info!("#{} -> {}: {}", self.context_id, name, value);
}
match self.get_http_request_header(":path") {
Some(path) if path == "/hello" => {
self.send_http_response(
200,
vec![("Hello", "World"), ("Powered-By", "proxy-wasm")],
Some(b"Hello, World!\n"),
);
Action::Pause
}
_ => Action::Continue,
}
}
fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action {
for (name, value) in &self.get_http_response_headers() {
info!("#{} <- {}: {}", self.context_id, name, value);
}
Action::Continue
}
fn on_log(&mut self) {
info!("#{} completed.", self.context_id);
}
}
================================================
FILE: src/allocator.rs
================================================
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::mem::MaybeUninit;
#[cfg_attr(
all(target_arch = "wasm32", target_os = "unknown"),
export_name = "malloc"
)]
#[cfg_attr(not(all(target_arch = "wasm32", target_os = "unknown")), no_mangle)]
pub extern "C" fn proxy_on_memory_allocate(size: usize) -> *mut u8 {
let mut vec: Vec<MaybeUninit<u8>> = Vec::with_capacity(size);
unsafe {
vec.set_len(size);
}
let slice = vec.into_boxed_slice();
Box::into_raw(slice) as *mut u8
}
================================================
FILE: src/dispatcher.rs
================================================
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::hostcalls;
use crate::traits::*;
use crate::types::*;
use hashbrown::HashMap;
use log::trace;
use std::cell::{Cell, RefCell};
thread_local! {
static DISPATCHER: Dispatcher = Dispatcher::new();
}
pub(crate) fn set_root_context(callback: NewRootContext) {
DISPATCHER.with(|dispatcher| dispatcher.set_root_context(callback));
}
pub(crate) fn set_stream_context(callback: NewStreamContext) {
DISPATCHER.with(|dispatcher| dispatcher.set_stream_context(callback));
}
pub(crate) fn set_http_context(callback: NewHttpContext) {
DISPATCHER.with(|dispatcher| dispatcher.set_http_context(callback));
}
pub(crate) fn register_callout(token_id: u32) {
DISPATCHER.with(|dispatcher| dispatcher.register_callout(token_id));
}
pub(crate) fn register_grpc_callout(token_id: u32) {
DISPATCHER.with(|dispatcher| dispatcher.register_grpc_callout(token_id));
}
pub(crate) fn register_grpc_stream(token_id: u32) {
DISPATCHER.with(|dispatcher| dispatcher.register_grpc_stream(token_id));
}
struct NoopRoot;
impl Context for NoopRoot {}
impl RootContext for NoopRoot {}
struct Dispatcher {
new_root: Cell<Option<NewRootContext>>,
roots: RefCell<HashMap<u32, Box<dyn RootContext>>>,
new_stream: Cell<Option<NewStreamContext>>,
streams: RefCell<HashMap<u32, Box<dyn StreamContext>>>,
new_http_stream: Cell<Option<NewHttpContext>>,
http_streams: RefCell<HashMap<u32, Box<dyn HttpContext>>>,
active_id: Cell<u32>,
callouts: RefCell<HashMap<u32, u32>>,
grpc_callouts: RefCell<HashMap<u32, u32>>,
grpc_streams: RefCell<HashMap<u32, u32>>,
}
impl Dispatcher {
fn new() -> Dispatcher {
Dispatcher {
new_root: Cell::new(None),
roots: RefCell::new(HashMap::new()),
new_stream: Cell::new(None),
streams: RefCell::new(HashMap::new()),
new_http_stream: Cell::new(None),
http_streams: RefCell::new(HashMap::new()),
active_id: Cell::new(0),
callouts: RefCell::new(HashMap::new()),
grpc_callouts: RefCell::new(HashMap::new()),
grpc_streams: RefCell::new(HashMap::new()),
}
}
fn set_root_context(&self, callback: NewRootContext) {
self.new_root.set(Some(callback));
}
fn set_stream_context(&self, callback: NewStreamContext) {
self.new_stream.set(Some(callback));
}
fn set_http_context(&self, callback: NewHttpContext) {
self.new_http_stream.set(Some(callback));
}
fn register_callout(&self, token_id: u32) {
if self
.callouts
.borrow_mut()
.insert(token_id, self.active_id.get())
.is_some()
{
panic!("duplicate token_id")
}
}
fn register_grpc_stream(&self, token_id: u32) {
if self
.grpc_streams
.borrow_mut()
.insert(token_id, self.active_id.get())
.is_some()
{
panic!("duplicate token_id")
}
}
fn register_grpc_callout(&self, token_id: u32) {
if self
.grpc_callouts
.borrow_mut()
.insert(token_id, self.active_id.get())
.is_some()
{
panic!("duplicate token_id")
}
}
fn create_root_context(&self, context_id: u32) {
let new_context = match self.new_root.get() {
Some(f) => f(context_id),
None => Box::new(NoopRoot),
};
if self
.roots
.borrow_mut()
.insert(context_id, new_context)
.is_some()
{
panic!("duplicate context_id")
}
}
fn create_stream_context(&self, context_id: u32, root_context_id: u32) {
let new_context = match self.roots.borrow().get(&root_context_id) {
Some(root_context) => match self.new_stream.get() {
Some(f) => f(context_id, root_context_id),
None => match root_context.create_stream_context(context_id) {
Some(stream_context) => stream_context,
None => panic!("create_stream_context returned None"),
},
},
None => panic!("invalid root_context_id"),
};
if self
.streams
.borrow_mut()
.insert(context_id, new_context)
.is_some()
{
panic!("duplicate context_id")
}
}
fn create_http_context(&self, context_id: u32, root_context_id: u32) {
let new_context = match self.roots.borrow().get(&root_context_id) {
Some(root_context) => match self.new_http_stream.get() {
Some(f) => f(context_id, root_context_id),
None => match root_context.create_http_context(context_id) {
Some(stream_context) => stream_context,
None => panic!("create_http_context returned None"),
},
},
None => panic!("invalid root_context_id"),
};
if self
.http_streams
.borrow_mut()
.insert(context_id, new_context)
.is_some()
{
panic!("duplicate context_id")
}
}
fn on_create_context(&self, context_id: u32, root_context_id: u32) {
if root_context_id == 0 {
self.create_root_context(context_id);
} else if self.new_http_stream.get().is_some() {
self.create_http_context(context_id, root_context_id);
} else if self.new_stream.get().is_some() {
self.create_stream_context(context_id, root_context_id);
} else if let Some(root_context) = self.roots.borrow().get(&root_context_id) {
match root_context.get_type() {
Some(ContextType::HttpContext) => {
self.create_http_context(context_id, root_context_id)
}
Some(ContextType::StreamContext) => {
self.create_stream_context(context_id, root_context_id)
}
None => panic!("missing ContextType on root_context"),
}
} else {
panic!("invalid root_context_id and missing constructors");
}
}
fn on_done(&self, context_id: u32) -> bool {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
http_stream.on_done()
} else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
stream.on_done()
} else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
root.on_done()
} else {
panic!("invalid context_id")
}
}
fn on_log(&self, context_id: u32) {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
http_stream.on_log()
} else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
stream.on_log()
} else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
root.on_log()
} else {
panic!("invalid context_id")
}
}
fn on_delete(&self, context_id: u32) {
if !(self.http_streams.borrow_mut().remove(&context_id).is_some()
|| self.streams.borrow_mut().remove(&context_id).is_some()
|| self.roots.borrow_mut().remove(&context_id).is_some())
{
panic!("invalid context_id")
}
}
fn on_vm_start(&self, context_id: u32, vm_configuration_size: usize) -> bool {
if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
root.on_vm_start(vm_configuration_size)
} else {
panic!("invalid context_id")
}
}
fn on_configure(&self, context_id: u32, plugin_configuration_size: usize) -> bool {
if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
root.on_configure(plugin_configuration_size)
} else {
panic!("invalid context_id")
}
}
fn on_tick(&self, context_id: u32) {
if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
root.on_tick()
} else {
panic!("invalid context_id")
}
}
fn on_queue_ready(&self, context_id: u32, queue_id: u32) {
if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
root.on_queue_ready(queue_id)
} else {
panic!("invalid context_id")
}
}
fn on_new_connection(&self, context_id: u32) -> Action {
if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
stream.on_new_connection()
} else {
panic!("invalid context_id")
}
}
fn on_downstream_data(&self, context_id: u32, data_size: usize, end_of_stream: bool) -> Action {
if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
stream.on_downstream_data(data_size, end_of_stream)
} else {
panic!("invalid context_id")
}
}
fn on_downstream_close(&self, context_id: u32, peer_type: PeerType) {
if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
stream.on_downstream_close(peer_type)
} else {
panic!("invalid context_id")
}
}
fn on_upstream_data(&self, context_id: u32, data_size: usize, end_of_stream: bool) -> Action {
if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
stream.on_upstream_data(data_size, end_of_stream)
} else {
panic!("invalid context_id")
}
}
fn on_upstream_close(&self, context_id: u32, peer_type: PeerType) {
if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
stream.on_upstream_close(peer_type)
} else {
panic!("invalid context_id")
}
}
fn on_http_request_headers(
&self,
context_id: u32,
num_headers: usize,
end_of_stream: bool,
) -> Action {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
http_stream.on_http_request_headers(num_headers, end_of_stream)
} else {
panic!("invalid context_id")
}
}
fn on_http_request_body(
&self,
context_id: u32,
body_size: usize,
end_of_stream: bool,
) -> Action {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
http_stream.on_http_request_body(body_size, end_of_stream)
} else {
panic!("invalid context_id")
}
}
fn on_http_request_trailers(&self, context_id: u32, num_trailers: usize) -> Action {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
http_stream.on_http_request_trailers(num_trailers)
} else {
panic!("invalid context_id")
}
}
fn on_http_response_headers(
&self,
context_id: u32,
num_headers: usize,
end_of_stream: bool,
) -> Action {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
http_stream.on_http_response_headers(num_headers, end_of_stream)
} else {
panic!("invalid context_id")
}
}
fn on_http_response_body(
&self,
context_id: u32,
body_size: usize,
end_of_stream: bool,
) -> Action {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
http_stream.on_http_response_body(body_size, end_of_stream)
} else {
panic!("invalid context_id")
}
}
fn on_http_response_trailers(&self, context_id: u32, num_trailers: usize) -> Action {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
http_stream.on_http_response_trailers(num_trailers)
} else {
panic!("invalid context_id")
}
}
fn on_http_call_response(
&self,
token_id: u32,
num_headers: usize,
body_size: usize,
num_trailers: usize,
) {
let context_id = self
.callouts
.borrow_mut()
.remove(&token_id)
.expect("invalid token_id");
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
http_stream.on_http_call_response(token_id, num_headers, body_size, num_trailers)
} else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
stream.on_http_call_response(token_id, num_headers, body_size, num_trailers)
} else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
root.on_http_call_response(token_id, num_headers, body_size, num_trailers)
}
}
fn on_grpc_receive_initial_metadata(&self, token_id: u32, headers: u32) {
let context_id = match self.grpc_streams.borrow_mut().get(&token_id) {
Some(id) => *id,
None => {
// TODO: change back to a panic once underlying issue is fixed.
trace!("on_grpc_receive_initial_metadata: invalid token_id");
return;
}
};
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
http_stream.on_grpc_stream_initial_metadata(token_id, headers);
} else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
stream.on_grpc_stream_initial_metadata(token_id, headers);
} else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
root.on_grpc_stream_initial_metadata(token_id, headers);
}
}
fn on_grpc_receive(&self, token_id: u32, response_size: usize) {
let context_id = self.grpc_callouts.borrow_mut().remove(&token_id);
if let Some(context_id) = context_id {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
http_stream.on_grpc_call_response(token_id, 0, response_size);
} else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
stream.on_grpc_call_response(token_id, 0, response_size);
} else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
root.on_grpc_call_response(token_id, 0, response_size);
}
} else {
let context_id = self.grpc_streams.borrow().get(&token_id).cloned();
if let Some(context_id) = context_id {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
http_stream.on_grpc_stream_message(token_id, response_size);
} else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
stream.on_grpc_stream_message(token_id, response_size);
} else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
root.on_grpc_stream_message(token_id, response_size);
}
} else {
// TODO: change back to a panic once underlying issue is fixed.
trace!("on_grpc_receive_initial_metadata: invalid token_id");
}
}
}
fn on_grpc_receive_trailing_metadata(&self, token_id: u32, trailers: u32) {
let context_id = match self.grpc_streams.borrow_mut().get(&token_id) {
Some(id) => *id,
None => {
// TODO: change back to a panic once underlying issue is fixed.
trace!("on_grpc_receive_trailing_metadata: invalid token_id");
return;
}
};
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
http_stream.on_grpc_stream_trailing_metadata(token_id, trailers);
} else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
stream.on_grpc_stream_trailing_metadata(token_id, trailers);
} else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
root.on_grpc_stream_trailing_metadata(token_id, trailers);
}
}
fn on_grpc_close(&self, token_id: u32, status_code: u32) {
let context_id = self.grpc_callouts.borrow_mut().remove(&token_id);
if let Some(context_id) = context_id {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
http_stream.on_grpc_call_response(token_id, status_code, 0);
} else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
stream.on_grpc_call_response(token_id, status_code, 0);
} else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
root.on_grpc_call_response(token_id, status_code, 0);
}
} else {
let context_id = self.grpc_streams.borrow_mut().remove(&token_id);
if let Some(context_id) = context_id {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
http_stream.on_grpc_stream_close(token_id, status_code)
} else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
stream.on_grpc_stream_close(token_id, status_code)
} else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
root.on_grpc_stream_close(token_id, status_code)
}
} else {
// TODO: change back to a panic once underlying issue is fixed.
trace!("on_grpc_close: invalid token_id, a non-connected stream has closed");
}
}
}
fn on_foreign_function(&self, context_id: u32, function_id: u32, arugments_size: usize) {
if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
http_stream.on_foreign_function(function_id, arugments_size)
} else if let Some(stream) = self.streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
stream.on_foreign_function(function_id, arugments_size)
} else if let Some(root) = self.roots.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
root.on_foreign_function(function_id, arugments_size)
}
}
}
#[no_mangle]
pub extern "C" fn proxy_on_context_create(context_id: u32, root_context_id: u32) {
DISPATCHER.with(|dispatcher| dispatcher.on_create_context(context_id, root_context_id))
}
#[no_mangle]
pub extern "C" fn proxy_on_done(context_id: u32) -> bool {
DISPATCHER.with(|dispatcher| dispatcher.on_done(context_id))
}
#[no_mangle]
pub extern "C" fn proxy_on_log(context_id: u32) {
DISPATCHER.with(|dispatcher| dispatcher.on_log(context_id))
}
#[no_mangle]
pub extern "C" fn proxy_on_delete(context_id: u32) {
DISPATCHER.with(|dispatcher| dispatcher.on_delete(context_id))
}
#[no_mangle]
pub extern "C" fn proxy_on_vm_start(context_id: u32, vm_configuration_size: usize) -> bool {
DISPATCHER.with(|dispatcher| dispatcher.on_vm_start(context_id, vm_configuration_size))
}
#[no_mangle]
pub extern "C" fn proxy_on_configure(context_id: u32, plugin_configuration_size: usize) -> bool {
DISPATCHER.with(|dispatcher| dispatcher.on_configure(context_id, plugin_configuration_size))
}
#[no_mangle]
pub extern "C" fn proxy_on_tick(context_id: u32) {
DISPATCHER.with(|dispatcher| dispatcher.on_tick(context_id))
}
#[no_mangle]
pub extern "C" fn proxy_on_queue_ready(context_id: u32, queue_id: u32) {
DISPATCHER.with(|dispatcher| dispatcher.on_queue_ready(context_id, queue_id))
}
#[no_mangle]
pub extern "C" fn proxy_on_new_connection(context_id: u32) -> Action {
DISPATCHER.with(|dispatcher| dispatcher.on_new_connection(context_id))
}
#[no_mangle]
pub extern "C" fn proxy_on_downstream_data(
context_id: u32,
data_size: usize,
end_of_stream: bool,
) -> Action {
DISPATCHER
.with(|dispatcher| dispatcher.on_downstream_data(context_id, data_size, end_of_stream))
}
#[no_mangle]
pub extern "C" fn proxy_on_downstream_connection_close(context_id: u32, peer_type: PeerType) {
DISPATCHER.with(|dispatcher| dispatcher.on_downstream_close(context_id, peer_type))
}
#[no_mangle]
pub extern "C" fn proxy_on_upstream_data(
context_id: u32,
data_size: usize,
end_of_stream: bool,
) -> Action {
DISPATCHER.with(|dispatcher| dispatcher.on_upstream_data(context_id, data_size, end_of_stream))
}
#[no_mangle]
pub extern "C" fn proxy_on_upstream_connection_close(context_id: u32, peer_type: PeerType) {
DISPATCHER.with(|dispatcher| dispatcher.on_upstream_close(context_id, peer_type))
}
#[no_mangle]
pub extern "C" fn proxy_on_request_headers(
context_id: u32,
num_headers: usize,
end_of_stream: bool,
) -> Action {
DISPATCHER.with(|dispatcher| {
dispatcher.on_http_request_headers(context_id, num_headers, end_of_stream)
})
}
#[no_mangle]
pub extern "C" fn proxy_on_request_body(
context_id: u32,
body_size: usize,
end_of_stream: bool,
) -> Action {
DISPATCHER
.with(|dispatcher| dispatcher.on_http_request_body(context_id, body_size, end_of_stream))
}
#[no_mangle]
pub extern "C" fn proxy_on_request_trailers(context_id: u32, num_trailers: usize) -> Action {
DISPATCHER.with(|dispatcher| dispatcher.on_http_request_trailers(context_id, num_trailers))
}
#[no_mangle]
pub extern "C" fn proxy_on_response_headers(
context_id: u32,
num_headers: usize,
end_of_stream: bool,
) -> Action {
DISPATCHER.with(|dispatcher| {
dispatcher.on_http_response_headers(context_id, num_headers, end_of_stream)
})
}
#[no_mangle]
pub extern "C" fn proxy_on_response_body(
context_id: u32,
body_size: usize,
end_of_stream: bool,
) -> Action {
DISPATCHER
.with(|dispatcher| dispatcher.on_http_response_body(context_id, body_size, end_of_stream))
}
#[no_mangle]
pub extern "C" fn proxy_on_response_trailers(context_id: u32, num_trailers: usize) -> Action {
DISPATCHER.with(|dispatcher| dispatcher.on_http_response_trailers(context_id, num_trailers))
}
#[no_mangle]
pub extern "C" fn proxy_on_http_call_response(
_context_id: u32,
token_id: u32,
num_headers: usize,
body_size: usize,
num_trailers: usize,
) {
DISPATCHER.with(|dispatcher| {
dispatcher.on_http_call_response(token_id, num_headers, body_size, num_trailers)
})
}
#[no_mangle]
pub extern "C" fn proxy_on_grpc_receive_initial_metadata(
_context_id: u32,
token_id: u32,
headers: u32,
) {
DISPATCHER.with(|dispatcher| dispatcher.on_grpc_receive_initial_metadata(token_id, headers))
}
#[no_mangle]
pub extern "C" fn proxy_on_grpc_receive(_context_id: u32, token_id: u32, response_size: usize) {
DISPATCHER.with(|dispatcher| dispatcher.on_grpc_receive(token_id, response_size))
}
#[no_mangle]
pub extern "C" fn proxy_on_grpc_receive_trailing_metadata(
_context_id: u32,
token_id: u32,
trailers: u32,
) {
DISPATCHER.with(|dispatcher| dispatcher.on_grpc_receive_trailing_metadata(token_id, trailers))
}
#[no_mangle]
pub extern "C" fn proxy_on_grpc_close(_context_id: u32, token_id: u32, status_code: u32) {
DISPATCHER.with(|dispatcher| dispatcher.on_grpc_close(token_id, status_code))
}
#[no_mangle]
pub extern "C" fn proxy_on_foreign_function(
context_id: u32,
function_id: u32,
arguments_size: usize,
) {
DISPATCHER
.with(|dispatcher| dispatcher.on_foreign_function(context_id, function_id, arguments_size))
}
================================================
FILE: src/hostcalls.rs
================================================
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::dispatcher;
use crate::types::*;
use std::ptr::{null, null_mut};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
extern "C" {
fn proxy_log(level: LogLevel, message_data: *const u8, message_size: usize) -> Status;
}
pub fn log(level: LogLevel, message: &str) -> Result<(), Status> {
unsafe {
match proxy_log(level, message.as_ptr(), message.len()) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
}
}
extern "C" {
fn proxy_get_log_level(return_level: *mut LogLevel) -> Status;
}
pub fn get_log_level() -> Result<LogLevel, Status> {
let mut return_level: LogLevel = LogLevel::Trace;
unsafe {
match proxy_get_log_level(&mut return_level) {
Status::Ok => Ok(return_level),
status => panic!("unexpected status: {}", status as u32),
}
}
}
extern "C" {
fn proxy_get_current_time_nanoseconds(return_time: *mut u64) -> Status;
}
pub fn get_current_time() -> Result<SystemTime, Status> {
let mut return_time: u64 = 0;
unsafe {
match proxy_get_current_time_nanoseconds(&mut return_time) {
Status::Ok => Ok(UNIX_EPOCH + Duration::from_nanos(return_time)),
status => panic!("unexpected status: {}", status as u32),
}
}
}
extern "C" {
fn proxy_set_tick_period_milliseconds(period: u32) -> Status;
}
pub fn set_tick_period(period: Duration) -> Result<(), Status> {
unsafe {
match proxy_set_tick_period_milliseconds(period.as_millis() as u32) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
}
}
extern "C" {
fn proxy_get_buffer_bytes(
buffer_type: BufferType,
start: usize,
max_size: usize,
return_buffer_data: *mut *mut u8,
return_buffer_size: *mut usize,
) -> Status;
}
pub fn get_buffer(
buffer_type: BufferType,
start: usize,
max_size: usize,
) -> Result<Option<Bytes>, Status> {
let mut return_data: *mut u8 = null_mut();
let mut return_size: usize = 0;
unsafe {
match proxy_get_buffer_bytes(
buffer_type,
start,
max_size,
&mut return_data,
&mut return_size,
) {
Status::Ok => {
if !return_data.is_null() {
Ok(Some(Vec::from_raw_parts(
return_data,
return_size,
return_size,
)))
} else {
Ok(None)
}
}
Status::NotFound => Ok(None),
status => panic!("unexpected status: {}", status as u32),
}
}
}
extern "C" {
fn proxy_set_buffer_bytes(
buffer_type: BufferType,
start: usize,
size: usize,
buffer_data: *const u8,
buffer_size: usize,
) -> Status;
}
pub fn set_buffer(
buffer_type: BufferType,
start: usize,
size: usize,
value: &[u8],
) -> Result<(), Status> {
unsafe {
match proxy_set_buffer_bytes(buffer_type, start, size, value.as_ptr(), value.len()) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
}
}
#[cfg(not(all(test, feature = "mockalloc")))]
extern "C" {
fn proxy_get_header_map_pairs(
map_type: MapType,
return_map_data: *mut *mut u8,
return_map_size: *mut usize,
) -> Status;
}
#[cfg(all(test, feature = "mockalloc"))]
fn proxy_get_header_map_pairs(
map_type: MapType,
return_map_data: *mut *mut u8,
return_map_size: *mut usize,
) -> Status {
mocks::proxy_get_header_map_pairs(map_type, return_map_data, return_map_size)
}
pub fn get_map(map_type: MapType) -> Result<Vec<(String, String)>, Status> {
unsafe {
let mut return_data: *mut u8 = null_mut();
let mut return_size: usize = 0;
match proxy_get_header_map_pairs(map_type, &mut return_data, &mut return_size) {
Status::Ok => {
if !return_data.is_null() {
let serialized_map = Vec::from_raw_parts(return_data, return_size, return_size);
Ok(utils::deserialize_map(&serialized_map))
} else {
Ok(Vec::new())
}
}
status => panic!("unexpected status: {}", status as u32),
}
}
}
pub fn get_map_bytes(map_type: MapType) -> Result<Vec<(String, Bytes)>, Status> {
unsafe {
let mut return_data: *mut u8 = null_mut();
let mut return_size: usize = 0;
match proxy_get_header_map_pairs(map_type, &mut return_data, &mut return_size) {
Status::Ok => {
if !return_data.is_null() {
let serialized_map = Vec::from_raw_parts(return_data, return_size, return_size);
Ok(utils::deserialize_map_bytes(&serialized_map))
} else {
Ok(Vec::new())
}
}
status => panic!("unexpected status: {}", status as u32),
}
}
}
extern "C" {
fn proxy_set_header_map_pairs(
map_type: MapType,
map_data: *const u8,
map_size: usize,
) -> Status;
}
pub fn set_map(map_type: MapType, map: Vec<(&str, &str)>) -> Result<(), Status> {
let serialized_map = utils::serialize_map(&map);
unsafe {
match proxy_set_header_map_pairs(map_type, serialized_map.as_ptr(), serialized_map.len()) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
}
}
pub fn set_map_bytes(map_type: MapType, map: Vec<(&str, &[u8])>) -> Result<(), Status> {
let serialized_map = utils::serialize_map_bytes(&map);
unsafe {
match proxy_set_header_map_pairs(map_type, serialized_map.as_ptr(), serialized_map.len()) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
}
}
extern "C" {
fn proxy_get_header_map_value(
map_type: MapType,
key_data: *const u8,
key_size: usize,
return_value_data: *mut *mut u8,
return_value_size: *mut usize,
) -> Status;
}
pub fn get_map_value(map_type: MapType, key: &str) -> Result<Option<String>, Status> {
let mut return_data: *mut u8 = null_mut();
let mut return_size: usize = 0;
unsafe {
match proxy_get_header_map_value(
map_type,
key.as_ptr(),
key.len(),
&mut return_data,
&mut return_size,
) {
Status::Ok => {
if !return_data.is_null() {
Ok(Some(
String::from_utf8(Vec::from_raw_parts(
return_data,
return_size,
return_size,
))
.unwrap(),
))
} else {
Ok(Some(String::new()))
}
}
Status::NotFound => Ok(None),
status => panic!("unexpected status: {}", status as u32),
}
}
}
pub fn get_map_value_bytes(map_type: MapType, key: &str) -> Result<Option<Bytes>, Status> {
let mut return_data: *mut u8 = null_mut();
let mut return_size: usize = 0;
unsafe {
match proxy_get_header_map_value(
map_type,
key.as_ptr(),
key.len(),
&mut return_data,
&mut return_size,
) {
Status::Ok => {
if !return_data.is_null() {
Ok(Some(Vec::from_raw_parts(
return_data,
return_size,
return_size,
)))
} else {
Ok(Some(Vec::new()))
}
}
Status::NotFound => Ok(None),
status => panic!("unexpected status: {}", status as u32),
}
}
}
extern "C" {
fn proxy_remove_header_map_value(
map_type: MapType,
key_data: *const u8,
key_size: usize,
) -> Status;
}
pub fn remove_map_value(map_type: MapType, key: &str) -> Result<(), Status> {
unsafe {
match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
}
}
extern "C" {
fn proxy_replace_header_map_value(
map_type: MapType,
key_data: *const u8,
key_size: usize,
value_data: *const u8,
value_size: usize,
) -> Status;
}
pub fn set_map_value(map_type: MapType, key: &str, value: Option<&str>) -> Result<(), Status> {
unsafe {
if let Some(value) = value {
match proxy_replace_header_map_value(
map_type,
key.as_ptr(),
key.len(),
value.as_ptr(),
value.len(),
) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
} else {
match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
}
}
}
pub fn set_map_value_bytes(
map_type: MapType,
key: &str,
value: Option<&[u8]>,
) -> Result<(), Status> {
unsafe {
if let Some(value) = value {
match proxy_replace_header_map_value(
map_type,
key.as_ptr(),
key.len(),
value.as_ptr(),
value.len(),
) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
} else {
match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
}
}
}
extern "C" {
fn proxy_add_header_map_value(
map_type: MapType,
key_data: *const u8,
key_size: usize,
value_data: *const u8,
value_size: usize,
) -> Status;
}
pub fn add_map_value(map_type: MapType, key: &str, value: &str) -> Result<(), Status> {
unsafe {
match proxy_add_header_map_value(
map_type,
key.as_ptr(),
key.len(),
value.as_ptr(),
value.len(),
) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
}
}
pub fn add_map_value_bytes(map_type: MapType, key: &str, value: &[u8]) -> Result<(), Status> {
unsafe {
match proxy_add_header_map_value(
map_type,
key.as_ptr(),
key.len(),
value.as_ptr(),
value.len(),
) {
Status::Ok => Ok(()),
status => panic!("unexpected status: {}", status as u32),
}
}
}
extern "C" {
fn proxy_get_property(
path_data: *const u8,
path_size: usize,
return_value_data: *mut *mut u8,
return_value_size: *mut usize,
) -> Status;
}
pub fn get_property(path: Vec<&str>) -> Result<Option<Bytes>, Status> {
let serialized_path = utils::serialize_property_path(path);
let mut return_data: *mut u8 = null_mut();
let mut return_size: usize = 0;
unsafe {
match proxy_get_property(
serialized_path.as_ptr(),
serialized_path.len(),
&mut return_data,
&mut return_size,
) {
Status::Ok => {
if !return_data.is_null() {
Ok(Some(Vec::from_raw_parts(
return_data,
return_size,
return_size,
)))
} else {
Ok(None)
}
}
Status::NotFound => Ok(None),
Status::SerializationFailure => Err(Status::SerializationFailure),
Status::InternalFailure => Err(Status::InternalFailure),
status => panic!("unexpected status: {}", status as u32),
}
}
}
extern "C" {
fn proxy_set_property(
path_data: *const u8,
path_size: usize,
value_data: *const u8,
value_size: usize,
) -> Status;
}
pub fn set_property(path: Vec<&str>, value: Option<&[u8]>) -> Result<(), Status> {
let serialized_path = utils::serialize_property_path(path);
unsafe {
match proxy_set_property(
serialized_path.as_ptr(),
serialized_path.len(),
value.map_or(null(), |value| value.as_ptr()),
value.map
gitextract_d2hvdrgx/
├── .actrc
├── .bazelrc
├── .bazelversion
├── .bcr/
│ ├── metadata.template.json
│ ├── presubmit.yml
│ └── source.template.json
├── .github/
│ ├── dependabot.yml
│ └── workflows/
│ ├── publish-to-bcr.yml
│ └── rust.yml
├── .gitignore
├── BUILD
├── CHANGELOG.md
├── CODEOWNERS
├── CONTRIBUTING.md
├── Cargo.toml
├── DEVELOPMENT.md
├── LICENSE
├── MODULE.bazel
├── README.md
├── WORKSPACE
├── WORKSPACE.bzlmod
├── bazel/
│ ├── BUILD
│ ├── cargo/
│ │ ├── BUILD
│ │ └── remote/
│ │ ├── BUILD.allocator-api2-0.2.21.bazel
│ │ ├── BUILD.bazel
│ │ ├── BUILD.equivalent-1.0.2.bazel
│ │ ├── BUILD.foldhash-0.2.0.bazel
│ │ ├── BUILD.hashbrown-0.16.0.bazel
│ │ ├── BUILD.log-0.4.27.bazel
│ │ ├── alias_rules.bzl
│ │ ├── crates.bzl
│ │ └── defs.bzl
│ ├── dependencies_bazel.bzl
│ ├── dependencies_compat.bzl
│ ├── dependencies_crates.bzl
│ ├── extensions.bzl
│ └── repositories.bzl
├── build.rs
├── examples/
│ ├── envoy_filter_metadata/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ ├── grpc_auth_random/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ ├── hello_world/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ ├── http_auth_random/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ ├── http_body/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ ├── http_config/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── docker-compose.yaml
│ │ ├── envoy.yaml
│ │ └── src/
│ │ └── lib.rs
│ └── http_headers/
│ ├── Cargo.toml
│ ├── README.md
│ ├── docker-compose.yaml
│ ├── envoy.yaml
│ └── src/
│ └── lib.rs
└── src/
├── allocator.rs
├── dispatcher.rs
├── hostcalls.rs
├── lib.rs
├── logger.rs
├── traits.rs
└── types.rs
SYMBOL INDEX (372 symbols across 15 files)
FILE: build.rs
function main (line 15) | fn main() {
FILE: examples/envoy_filter_metadata/src/lib.rs
type MetadataHttp (line 23) | struct MetadataHttp {}
method on_http_request_headers (line 28) | fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
FILE: examples/grpc_auth_random/src/lib.rs
type GrpcAuthRandom (line 25) | struct GrpcAuthRandom;
method on_http_request_headers (line 28) | fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
method on_http_response_headers (line 63) | fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action {
method on_grpc_call_response (line 70) | fn on_grpc_call_response(&mut self, _: u32, status_code: u32, _: usize) {
FILE: examples/hello_world/src/lib.rs
type HelloWorld (line 27) | struct HelloWorld;
method on_vm_start (line 32) | fn on_vm_start(&mut self, _: usize) -> bool {
method on_tick (line 38) | fn on_tick(&mut self) {
FILE: examples/http_auth_random/src/lib.rs
type HttpAuthRandom (line 25) | struct HttpAuthRandom;
method on_http_request_headers (line 28) | fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
method on_http_response_headers (line 44) | fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action {
method on_http_call_response (line 51) | fn on_http_call_response(&mut self, _: u32, _: usize, body_size: usize, ...
FILE: examples/http_body/src/lib.rs
type HttpBodyRoot (line 23) | struct HttpBodyRoot;
method get_type (line 28) | fn get_type(&self) -> Option<ContextType> {
method create_http_context (line 32) | fn create_http_context(&self, _: u32) -> Option<Box<dyn HttpContext>> {
type HttpBody (line 37) | struct HttpBody;
method on_http_response_headers (line 42) | fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action {
method on_http_response_body (line 51) | fn on_http_response_body(&mut self, body_size: usize, end_of_stream: boo...
FILE: examples/http_config/src/lib.rs
type HttpConfigHeader (line 27) | struct HttpConfigHeader {
method on_http_response_headers (line 34) | fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action {
type HttpConfigHeaderRoot (line 40) | struct HttpConfigHeaderRoot {
method on_configure (line 47) | fn on_configure(&mut self, _: usize) -> bool {
method create_http_context (line 54) | fn create_http_context(&self, _: u32) -> Option<Box<dyn HttpContext>> {
method get_type (line 60) | fn get_type(&self) -> Option<ContextType> {
FILE: examples/http_headers/src/lib.rs
type HttpHeadersRoot (line 24) | struct HttpHeadersRoot;
method get_type (line 29) | fn get_type(&self) -> Option<ContextType> {
method create_http_context (line 33) | fn create_http_context(&self, context_id: u32) -> Option<Box<dyn HttpCon...
type HttpHeaders (line 38) | struct HttpHeaders {
method on_http_request_headers (line 45) | fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
method on_http_response_headers (line 63) | fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action {
method on_log (line 70) | fn on_log(&mut self) {
FILE: src/allocator.rs
function proxy_on_memory_allocate (line 22) | pub extern "C" fn proxy_on_memory_allocate(size: usize) -> *mut u8 {
FILE: src/dispatcher.rs
function set_root_context (line 26) | pub(crate) fn set_root_context(callback: NewRootContext) {
function set_stream_context (line 30) | pub(crate) fn set_stream_context(callback: NewStreamContext) {
function set_http_context (line 34) | pub(crate) fn set_http_context(callback: NewHttpContext) {
function register_callout (line 38) | pub(crate) fn register_callout(token_id: u32) {
function register_grpc_callout (line 42) | pub(crate) fn register_grpc_callout(token_id: u32) {
function register_grpc_stream (line 46) | pub(crate) fn register_grpc_stream(token_id: u32) {
type NoopRoot (line 50) | struct NoopRoot;
type Dispatcher (line 55) | struct Dispatcher {
method new (line 69) | fn new() -> Dispatcher {
method set_root_context (line 84) | fn set_root_context(&self, callback: NewRootContext) {
method set_stream_context (line 88) | fn set_stream_context(&self, callback: NewStreamContext) {
method set_http_context (line 92) | fn set_http_context(&self, callback: NewHttpContext) {
method register_callout (line 96) | fn register_callout(&self, token_id: u32) {
method register_grpc_stream (line 107) | fn register_grpc_stream(&self, token_id: u32) {
method register_grpc_callout (line 118) | fn register_grpc_callout(&self, token_id: u32) {
method create_root_context (line 129) | fn create_root_context(&self, context_id: u32) {
method create_stream_context (line 144) | fn create_stream_context(&self, context_id: u32, root_context_id: u32) {
method create_http_context (line 165) | fn create_http_context(&self, context_id: u32, root_context_id: u32) {
method on_create_context (line 186) | fn on_create_context(&self, context_id: u32, root_context_id: u32) {
method on_done (line 208) | fn on_done(&self, context_id: u32) -> bool {
method on_log (line 223) | fn on_log(&self, context_id: u32) {
method on_delete (line 238) | fn on_delete(&self, context_id: u32) {
method on_vm_start (line 247) | fn on_vm_start(&self, context_id: u32, vm_configuration_size: usize) -...
method on_configure (line 256) | fn on_configure(&self, context_id: u32, plugin_configuration_size: usi...
method on_tick (line 265) | fn on_tick(&self, context_id: u32) {
method on_queue_ready (line 274) | fn on_queue_ready(&self, context_id: u32, queue_id: u32) {
method on_new_connection (line 283) | fn on_new_connection(&self, context_id: u32) -> Action {
method on_downstream_data (line 292) | fn on_downstream_data(&self, context_id: u32, data_size: usize, end_of...
method on_downstream_close (line 301) | fn on_downstream_close(&self, context_id: u32, peer_type: PeerType) {
method on_upstream_data (line 310) | fn on_upstream_data(&self, context_id: u32, data_size: usize, end_of_s...
method on_upstream_close (line 319) | fn on_upstream_close(&self, context_id: u32, peer_type: PeerType) {
method on_http_request_headers (line 328) | fn on_http_request_headers(
method on_http_request_body (line 342) | fn on_http_request_body(
method on_http_request_trailers (line 356) | fn on_http_request_trailers(&self, context_id: u32, num_trailers: usiz...
method on_http_response_headers (line 365) | fn on_http_response_headers(
method on_http_response_body (line 379) | fn on_http_response_body(
method on_http_response_trailers (line 393) | fn on_http_response_trailers(&self, context_id: u32, num_trailers: usi...
method on_http_call_response (line 402) | fn on_http_call_response(
method on_grpc_receive_initial_metadata (line 430) | fn on_grpc_receive_initial_metadata(&self, token_id: u32, headers: u32) {
method on_grpc_receive (line 455) | fn on_grpc_receive(&self, token_id: u32, response_size: usize) {
method on_grpc_receive_trailing_metadata (line 494) | fn on_grpc_receive_trailing_metadata(&self, token_id: u32, trailers: u...
method on_grpc_close (line 519) | fn on_grpc_close(&self, token_id: u32, status_code: u32) {
method on_foreign_function (line 558) | fn on_foreign_function(&self, context_id: u32, function_id: u32, arugm...
function proxy_on_context_create (line 576) | pub extern "C" fn proxy_on_context_create(context_id: u32, root_context_...
function proxy_on_done (line 581) | pub extern "C" fn proxy_on_done(context_id: u32) -> bool {
function proxy_on_log (line 586) | pub extern "C" fn proxy_on_log(context_id: u32) {
function proxy_on_delete (line 591) | pub extern "C" fn proxy_on_delete(context_id: u32) {
function proxy_on_vm_start (line 596) | pub extern "C" fn proxy_on_vm_start(context_id: u32, vm_configuration_si...
function proxy_on_configure (line 601) | pub extern "C" fn proxy_on_configure(context_id: u32, plugin_configurati...
function proxy_on_tick (line 606) | pub extern "C" fn proxy_on_tick(context_id: u32) {
function proxy_on_queue_ready (line 611) | pub extern "C" fn proxy_on_queue_ready(context_id: u32, queue_id: u32) {
function proxy_on_new_connection (line 616) | pub extern "C" fn proxy_on_new_connection(context_id: u32) -> Action {
function proxy_on_downstream_data (line 621) | pub extern "C" fn proxy_on_downstream_data(
function proxy_on_downstream_connection_close (line 631) | pub extern "C" fn proxy_on_downstream_connection_close(context_id: u32, ...
function proxy_on_upstream_data (line 636) | pub extern "C" fn proxy_on_upstream_data(
function proxy_on_upstream_connection_close (line 645) | pub extern "C" fn proxy_on_upstream_connection_close(context_id: u32, pe...
function proxy_on_request_headers (line 650) | pub extern "C" fn proxy_on_request_headers(
function proxy_on_request_body (line 661) | pub extern "C" fn proxy_on_request_body(
function proxy_on_request_trailers (line 671) | pub extern "C" fn proxy_on_request_trailers(context_id: u32, num_trailer...
function proxy_on_response_headers (line 676) | pub extern "C" fn proxy_on_response_headers(
function proxy_on_response_body (line 687) | pub extern "C" fn proxy_on_response_body(
function proxy_on_response_trailers (line 697) | pub extern "C" fn proxy_on_response_trailers(context_id: u32, num_traile...
function proxy_on_http_call_response (line 702) | pub extern "C" fn proxy_on_http_call_response(
function proxy_on_grpc_receive_initial_metadata (line 715) | pub extern "C" fn proxy_on_grpc_receive_initial_metadata(
function proxy_on_grpc_receive (line 724) | pub extern "C" fn proxy_on_grpc_receive(_context_id: u32, token_id: u32,...
function proxy_on_grpc_receive_trailing_metadata (line 729) | pub extern "C" fn proxy_on_grpc_receive_trailing_metadata(
function proxy_on_grpc_close (line 738) | pub extern "C" fn proxy_on_grpc_close(_context_id: u32, token_id: u32, s...
function proxy_on_foreign_function (line 743) | pub extern "C" fn proxy_on_foreign_function(
FILE: src/hostcalls.rs
function proxy_log (line 21) | fn proxy_log(level: LogLevel, message_data: *const u8, message_size: usi...
function log (line 24) | pub fn log(level: LogLevel, message: &str) -> Result<(), Status> {
function proxy_get_log_level (line 34) | fn proxy_get_log_level(return_level: *mut LogLevel) -> Status;
function get_log_level (line 37) | pub fn get_log_level() -> Result<LogLevel, Status> {
function proxy_get_current_time_nanoseconds (line 48) | fn proxy_get_current_time_nanoseconds(return_time: *mut u64) -> Status;
function get_current_time (line 51) | pub fn get_current_time() -> Result<SystemTime, Status> {
function proxy_set_tick_period_milliseconds (line 62) | fn proxy_set_tick_period_milliseconds(period: u32) -> Status;
function set_tick_period (line 65) | pub fn set_tick_period(period: Duration) -> Result<(), Status> {
function proxy_get_buffer_bytes (line 75) | fn proxy_get_buffer_bytes(
function get_buffer (line 84) | pub fn get_buffer(
function proxy_set_buffer_bytes (line 117) | fn proxy_set_buffer_bytes(
function set_buffer (line 126) | pub fn set_buffer(
function proxy_get_header_map_pairs (line 142) | fn proxy_get_header_map_pairs(
function proxy_get_header_map_pairs (line 150) | fn proxy_get_header_map_pairs(
function get_map (line 158) | pub fn get_map(map_type: MapType) -> Result<Vec<(String, String)>, Statu...
function get_map_bytes (line 176) | pub fn get_map_bytes(map_type: MapType) -> Result<Vec<(String, Bytes)>, ...
function proxy_set_header_map_pairs (line 195) | fn proxy_set_header_map_pairs(
function set_map (line 202) | pub fn set_map(map_type: MapType, map: Vec<(&str, &str)>) -> Result<(), ...
function set_map_bytes (line 212) | pub fn set_map_bytes(map_type: MapType, map: Vec<(&str, &[u8])>) -> Resu...
function proxy_get_header_map_value (line 223) | fn proxy_get_header_map_value(
function get_map_value (line 232) | pub fn get_map_value(map_type: MapType, key: &str) -> Result<Option<Stri...
function get_map_value_bytes (line 263) | pub fn get_map_value_bytes(map_type: MapType, key: &str) -> Result<Optio...
function proxy_remove_header_map_value (line 292) | fn proxy_remove_header_map_value(
function remove_map_value (line 299) | pub fn remove_map_value(map_type: MapType, key: &str) -> Result<(), Stat...
function proxy_replace_header_map_value (line 309) | fn proxy_replace_header_map_value(
function set_map_value (line 318) | pub fn set_map_value(map_type: MapType, key: &str, value: Option<&str>) ...
function set_map_value_bytes (line 340) | pub fn set_map_value_bytes(
function proxy_add_header_map_value (line 367) | fn proxy_add_header_map_value(
function add_map_value (line 376) | pub fn add_map_value(map_type: MapType, key: &str, value: &str) -> Resul...
function add_map_value_bytes (line 391) | pub fn add_map_value_bytes(map_type: MapType, key: &str, value: &[u8]) -...
function proxy_get_property (line 407) | fn proxy_get_property(
function get_property (line 415) | pub fn get_property(path: Vec<&str>) -> Result<Option<Bytes>, Status> {
function proxy_set_property (line 446) | fn proxy_set_property(
function set_property (line 454) | pub fn set_property(path: Vec<&str>, value: Option<&[u8]>) -> Result<(),...
function proxy_get_shared_data (line 470) | fn proxy_get_shared_data(
function get_shared_data (line 479) | pub fn get_shared_data(key: &str) -> Result<(Option<Bytes>, Option<u32>)...
function proxy_set_shared_data (line 512) | fn proxy_set_shared_data(
function set_shared_data (line 521) | pub fn set_shared_data(key: &str, value: Option<&[u8]>, cas: Option<u32>...
function proxy_register_shared_queue (line 538) | fn proxy_register_shared_queue(
function register_shared_queue (line 545) | pub fn register_shared_queue(name: &str) -> Result<u32, Status> {
function proxy_resolve_shared_queue (line 556) | fn proxy_resolve_shared_queue(
function resolve_shared_queue (line 565) | pub fn resolve_shared_queue(vm_id: &str, name: &str) -> Result<Option<u3...
function proxy_dequeue_shared_queue (line 583) | fn proxy_dequeue_shared_queue(
function dequeue_shared_queue (line 590) | pub fn dequeue_shared_queue(queue_id: u32) -> Result<Option<Bytes>, Stat...
function proxy_enqueue_shared_queue (line 614) | fn proxy_enqueue_shared_queue(
function enqueue_shared_queue (line 621) | pub fn enqueue_shared_queue(queue_id: u32, value: Option<&[u8]>) -> Resu...
function proxy_continue_stream (line 636) | fn proxy_continue_stream(stream_type: StreamType) -> Status;
function resume_downstream (line 639) | pub fn resume_downstream() -> Result<(), Status> {
function resume_upstream (line 648) | pub fn resume_upstream() -> Result<(), Status> {
function resume_http_request (line 657) | pub fn resume_http_request() -> Result<(), Status> {
function resume_http_response (line 666) | pub fn resume_http_response() -> Result<(), Status> {
function proxy_close_stream (line 676) | fn proxy_close_stream(stream_type: StreamType) -> Status;
function close_downstream (line 679) | pub fn close_downstream() -> Result<(), Status> {
function close_upstream (line 687) | pub fn close_upstream() -> Result<(), Status> {
function reset_http_request (line 696) | pub fn reset_http_request() -> Result<(), Status> {
function reset_http_response (line 705) | pub fn reset_http_response() -> Result<(), Status> {
function proxy_send_local_response (line 715) | fn proxy_send_local_response(
function send_http_response (line 727) | pub fn send_http_response(
function send_grpc_response (line 750) | pub fn send_grpc_response(
function proxy_http_call (line 774) | fn proxy_http_call(
function dispatch_http_call (line 788) | pub fn dispatch_http_call(
function proxy_grpc_call (line 823) | fn proxy_grpc_call(
function dispatch_grpc_call (line 839) | pub fn dispatch_grpc_call(
function proxy_grpc_stream (line 876) | fn proxy_grpc_stream(
function open_grpc_stream (line 889) | pub fn open_grpc_stream(
function proxy_grpc_send (line 921) | fn proxy_grpc_send(
function send_grpc_stream_message (line 929) | pub fn send_grpc_stream_message(
function proxy_grpc_cancel (line 950) | fn proxy_grpc_cancel(token_id: u32) -> Status;
function cancel_grpc_call (line 953) | pub fn cancel_grpc_call(token_id: u32) -> Result<(), Status> {
function cancel_grpc_stream (line 963) | pub fn cancel_grpc_stream(token_id: u32) -> Result<(), Status> {
function proxy_grpc_close (line 974) | fn proxy_grpc_close(token_id: u32) -> Status;
function close_grpc_stream (line 977) | pub fn close_grpc_stream(token_id: u32) -> Result<(), Status> {
function proxy_get_status (line 988) | fn proxy_get_status(
function get_grpc_status (line 995) | pub fn get_grpc_status() -> Result<(u32, Option<String>), Status> {
function proxy_set_effective_context (line 1024) | fn proxy_set_effective_context(context_id: u32) -> Status;
function set_effective_context (line 1027) | pub fn set_effective_context(context_id: u32) -> Result<(), Status> {
function proxy_call_foreign_function (line 1038) | fn proxy_call_foreign_function(
function call_foreign_function (line 1048) | pub fn call_foreign_function(
function proxy_done (line 1084) | fn proxy_done() -> Status;
function done (line 1087) | pub fn done() -> Result<(), Status> {
function proxy_define_metric (line 1097) | fn proxy_define_metric(
function define_metric (line 1105) | pub fn define_metric(metric_type: MetricType, name: &str) -> Result<u32,...
function proxy_get_metric (line 1116) | fn proxy_get_metric(metric_id: u32, return_value: *mut u64) -> Status;
function get_metric (line 1119) | pub fn get_metric(metric_id: u32) -> Result<u64, Status> {
function proxy_record_metric (line 1132) | fn proxy_record_metric(metric_id: u32, value: u64) -> Status;
function record_metric (line 1135) | pub fn record_metric(metric_id: u32, value: u64) -> Result<(), Status> {
function proxy_increment_metric (line 1146) | fn proxy_increment_metric(metric_id: u32, offset: i64) -> Status;
function increment_metric (line 1149) | pub fn increment_metric(metric_id: u32, offset: i64) -> Result<(), Statu...
function proxy_get_header_map_pairs (line 1166) | pub fn proxy_get_header_map_pairs(
function test_get_map_no_leaks (line 1195) | fn test_get_map_no_leaks() {
function test_get_map_bytes_no_leaks (line 1201) | fn test_get_map_bytes_no_leaks() {
function serialize_property_path (line 1211) | pub(super) fn serialize_property_path(path: Vec<&str>) -> Bytes {
function serialize_map (line 1228) | pub(super) fn serialize_map(map: &[(&str, &str)]) -> Bytes {
function serialize_map_bytes (line 1248) | pub(super) fn serialize_map_bytes(map: &[(&str, &[u8])]) -> Bytes {
function deserialize_map (line 1268) | pub(super) fn deserialize_map(bytes: &[u8]) -> Vec<(String, String)> {
function deserialize_map_bytes (line 1292) | pub(super) fn deserialize_map_bytes(bytes: &[u8]) -> Vec<(String, Bytes)> {
function test_serialize_map_empty (line 1358) | fn test_serialize_map_empty() {
function test_serialize_map_empty_bytes (line 1364) | fn test_serialize_map_empty_bytes() {
function test_deserialize_map_empty (line 1370) | fn test_deserialize_map_empty() {
function test_deserialize_map_empty_bytes (line 1378) | fn test_deserialize_map_empty_bytes() {
function test_serialize_map (line 1386) | fn test_serialize_map() {
function test_serialize_map_bytes (line 1392) | fn test_serialize_map_bytes() {
function test_deserialize_map (line 1399) | fn test_deserialize_map() {
function test_deserialize_map_bytes (line 1409) | fn test_deserialize_map_bytes() {
function test_deserialize_map_roundtrip (line 1419) | fn test_deserialize_map_roundtrip() {
function test_deserialize_map_roundtrip_bytes (line 1429) | fn test_deserialize_map_roundtrip_bytes() {
function test_deserialize_map_all_chars (line 1439) | fn test_deserialize_map_all_chars() {
function test_deserialize_map_all_chars_bytes (line 1462) | fn test_deserialize_map_all_chars_bytes() {
function bench_serialize_map (line 1477) | fn bench_serialize_map(b: &mut Bencher) {
function bench_serialize_map_bytes (line 1486) | fn bench_serialize_map_bytes(b: &mut Bencher) {
function bench_deserialize_map (line 1495) | fn bench_deserialize_map(b: &mut Bencher) {
function bench_deserialize_map_bytes (line 1504) | fn bench_deserialize_map_bytes(b: &mut Bencher) {
FILE: src/lib.rs
function set_log_level (line 62) | pub fn set_log_level(level: types::LogLevel) {
function set_root_context (line 66) | pub fn set_root_context(callback: types::NewRootContext) {
function set_stream_context (line 70) | pub fn set_stream_context(callback: types::NewStreamContext) {
function set_http_context (line 74) | pub fn set_http_context(callback: types::NewHttpContext) {
function proxy_abi_version_0_2_1 (line 79) | pub extern "C" fn proxy_abi_version_0_2_1() {}
FILE: src/logger.rs
type Logger (line 20) | struct Logger;
method set_log_level (line 37) | pub fn set_log_level(&self, level: LogLevel) {
method enabled (line 51) | fn enabled(&self, metadata: &log::Metadata) -> bool {
method log (line 55) | fn log(&self, record: &log::Record) {
method flush (line 70) | fn flush(&self) {}
function set_log_level (line 25) | pub(crate) fn set_log_level(level: LogLevel) {
FILE: src/traits.rs
type Context (line 19) | pub trait Context {
method get_current_time (line 20) | fn get_current_time(&self) -> SystemTime {
method get_property (line 24) | fn get_property(&self, path: Vec<&str>) -> Option<Bytes> {
method set_property (line 28) | fn set_property(&self, path: Vec<&str>, value: Option<&[u8]>) {
method get_shared_data (line 32) | fn get_shared_data(&self, key: &str) -> (Option<Bytes>, Option<u32>) {
method set_shared_data (line 36) | fn set_shared_data(
method remove_shared_data (line 45) | fn remove_shared_data(&self, key: &str, cas: Option<u32>) -> Result<()...
method register_shared_queue (line 49) | fn register_shared_queue(&self, name: &str) -> u32 {
method resolve_shared_queue (line 53) | fn resolve_shared_queue(&self, vm_id: &str, name: &str) -> Option<u32> {
method dequeue_shared_queue (line 57) | fn dequeue_shared_queue(&self, queue_id: u32) -> Result<Option<Bytes>,...
method enqueue_shared_queue (line 61) | fn enqueue_shared_queue(&self, queue_id: u32, value: Option<&[u8]>) ->...
method dispatch_http_call (line 65) | fn dispatch_http_call(
method on_http_call_response (line 76) | fn on_http_call_response(
method get_http_call_response_headers (line 85) | fn get_http_call_response_headers(&self) -> Vec<(String, String)> {
method get_http_call_response_headers_bytes (line 89) | fn get_http_call_response_headers_bytes(&self) -> Vec<(String, Bytes)> {
method get_http_call_response_header (line 93) | fn get_http_call_response_header(&self, name: &str) -> Option<String> {
method get_http_call_response_header_bytes (line 97) | fn get_http_call_response_header_bytes(&self, name: &str) -> Option<By...
method get_http_call_response_body (line 101) | fn get_http_call_response_body(&self, start: usize, max_size: usize) -...
method get_http_call_response_trailers (line 105) | fn get_http_call_response_trailers(&self) -> Vec<(String, String)> {
method get_http_call_response_trailers_bytes (line 109) | fn get_http_call_response_trailers_bytes(&self) -> Vec<(String, Bytes)> {
method get_http_call_response_trailer (line 113) | fn get_http_call_response_trailer(&self, name: &str) -> Option<String> {
method get_http_call_response_trailer_bytes (line 117) | fn get_http_call_response_trailer_bytes(&self, name: &str) -> Option<B...
method dispatch_grpc_call (line 121) | fn dispatch_grpc_call(
method on_grpc_call_response (line 140) | fn on_grpc_call_response(&mut self, _token_id: u32, _status_code: u32,...
method get_grpc_call_response_body (line 142) | fn get_grpc_call_response_body(&self, start: usize, max_size: usize) -...
method cancel_grpc_call (line 146) | fn cancel_grpc_call(&self, token_id: u32) {
method open_grpc_stream (line 150) | fn open_grpc_stream(
method on_grpc_stream_initial_metadata (line 160) | fn on_grpc_stream_initial_metadata(&mut self, _token_id: u32, _num_ele...
method get_grpc_stream_initial_metadata (line 162) | fn get_grpc_stream_initial_metadata(&self) -> Vec<(String, Bytes)> {
method get_grpc_stream_initial_metadata_value (line 166) | fn get_grpc_stream_initial_metadata_value(&self, name: &str) -> Option...
method send_grpc_stream_message (line 170) | fn send_grpc_stream_message(&self, token_id: u32, message: Option<&[u8...
method on_grpc_stream_message (line 174) | fn on_grpc_stream_message(&mut self, _token_id: u32, _message_size: us...
method get_grpc_stream_message (line 176) | fn get_grpc_stream_message(&mut self, start: usize, max_size: usize) -...
method on_grpc_stream_trailing_metadata (line 180) | fn on_grpc_stream_trailing_metadata(&mut self, _token_id: u32, _num_el...
method get_grpc_stream_trailing_metadata (line 182) | fn get_grpc_stream_trailing_metadata(&self) -> Vec<(String, Bytes)> {
method get_grpc_stream_trailing_metadata_value (line 186) | fn get_grpc_stream_trailing_metadata_value(&self, name: &str) -> Optio...
method cancel_grpc_stream (line 190) | fn cancel_grpc_stream(&self, token_id: u32) {
method close_grpc_stream (line 194) | fn close_grpc_stream(&self, token_id: u32) {
method on_grpc_stream_close (line 198) | fn on_grpc_stream_close(&mut self, _token_id: u32, _status_code: u32) {}
method get_grpc_status (line 200) | fn get_grpc_status(&self) -> (u32, Option<String>) {
method on_foreign_function (line 204) | fn on_foreign_function(&mut self, _function_id: u32, _arguments_size: ...
method call_foreign_function (line 206) | fn call_foreign_function(
method on_done (line 214) | fn on_done(&mut self) -> bool {
method done (line 218) | fn done(&self) {
type RootContext (line 223) | pub trait RootContext: Context {
method on_vm_start (line 224) | fn on_vm_start(&mut self, _vm_configuration_size: usize) -> bool {
method get_vm_configuration (line 228) | fn get_vm_configuration(&self) -> Option<Bytes> {
method on_configure (line 232) | fn on_configure(&mut self, _plugin_configuration_size: usize) -> bool {
method get_plugin_configuration (line 236) | fn get_plugin_configuration(&self) -> Option<Bytes> {
method set_tick_period (line 240) | fn set_tick_period(&self, period: Duration) {
method on_tick (line 244) | fn on_tick(&mut self) {}
method on_queue_ready (line 246) | fn on_queue_ready(&mut self, _queue_id: u32) {}
method on_log (line 248) | fn on_log(&mut self) {}
method create_http_context (line 250) | fn create_http_context(&self, _context_id: u32) -> Option<Box<dyn Http...
method create_stream_context (line 254) | fn create_stream_context(&self, _context_id: u32) -> Option<Box<dyn St...
method get_type (line 258) | fn get_type(&self) -> Option<ContextType> {
type StreamContext (line 263) | pub trait StreamContext: Context {
method on_new_connection (line 264) | fn on_new_connection(&mut self) -> Action {
method on_downstream_data (line 268) | fn on_downstream_data(&mut self, _data_size: usize, _end_of_stream: bo...
method get_downstream_data (line 272) | fn get_downstream_data(&self, start: usize, max_size: usize) -> Option...
method set_downstream_data (line 276) | fn set_downstream_data(&self, start: usize, size: usize, value: &[u8]) {
method resume_downstream (line 280) | fn resume_downstream(&self) {
method close_downstream (line 284) | fn close_downstream(&self) {
method on_downstream_close (line 288) | fn on_downstream_close(&mut self, _peer_type: PeerType) {}
method on_upstream_data (line 290) | fn on_upstream_data(&mut self, _data_size: usize, _end_of_stream: bool...
method get_upstream_data (line 294) | fn get_upstream_data(&self, start: usize, max_size: usize) -> Option<B...
method set_upstream_data (line 298) | fn set_upstream_data(&self, start: usize, size: usize, value: &[u8]) {
method resume_upstream (line 302) | fn resume_upstream(&self) {
method close_upstream (line 306) | fn close_upstream(&self) {
method on_upstream_close (line 310) | fn on_upstream_close(&mut self, _peer_type: PeerType) {}
method on_log (line 312) | fn on_log(&mut self) {}
type HttpContext (line 315) | pub trait HttpContext: Context {
method on_http_request_headers (line 316) | fn on_http_request_headers(&mut self, _num_headers: usize, _end_of_str...
method get_http_request_headers (line 320) | fn get_http_request_headers(&self) -> Vec<(String, String)> {
method get_http_request_headers_bytes (line 324) | fn get_http_request_headers_bytes(&self) -> Vec<(String, Bytes)> {
method set_http_request_headers (line 328) | fn set_http_request_headers(&self, headers: Vec<(&str, &str)>) {
method set_http_request_headers_bytes (line 332) | fn set_http_request_headers_bytes(&self, headers: Vec<(&str, &[u8])>) {
method get_http_request_header (line 336) | fn get_http_request_header(&self, name: &str) -> Option<String> {
method get_http_request_header_bytes (line 340) | fn get_http_request_header_bytes(&self, name: &str) -> Option<Bytes> {
method set_http_request_header (line 344) | fn set_http_request_header(&self, name: &str, value: Option<&str>) {
method set_http_request_header_bytes (line 348) | fn set_http_request_header_bytes(&self, name: &str, value: Option<&[u8...
method add_http_request_header (line 352) | fn add_http_request_header(&self, name: &str, value: &str) {
method add_http_request_header_bytes (line 356) | fn add_http_request_header_bytes(&self, name: &str, value: &[u8]) {
method remove_http_request_header (line 360) | fn remove_http_request_header(&self, name: &str) {
method on_http_request_body (line 364) | fn on_http_request_body(&mut self, _body_size: usize, _end_of_stream: ...
method get_http_request_body (line 368) | fn get_http_request_body(&self, start: usize, max_size: usize) -> Opti...
method set_http_request_body (line 372) | fn set_http_request_body(&self, start: usize, size: usize, value: &[u8...
method on_http_request_trailers (line 376) | fn on_http_request_trailers(&mut self, _num_trailers: usize) -> Action {
method get_http_request_trailers (line 380) | fn get_http_request_trailers(&self) -> Vec<(String, String)> {
method get_http_request_trailers_bytes (line 384) | fn get_http_request_trailers_bytes(&self) -> Vec<(String, Bytes)> {
method set_http_request_trailers (line 388) | fn set_http_request_trailers(&self, trailers: Vec<(&str, &str)>) {
method set_http_request_trailers_bytes (line 392) | fn set_http_request_trailers_bytes(&self, trailers: Vec<(&str, &[u8])>) {
method get_http_request_trailer (line 396) | fn get_http_request_trailer(&self, name: &str) -> Option<String> {
method get_http_request_trailer_bytes (line 400) | fn get_http_request_trailer_bytes(&self, name: &str) -> Option<Bytes> {
method set_http_request_trailer (line 404) | fn set_http_request_trailer(&self, name: &str, value: Option<&str>) {
method set_http_request_trailer_bytes (line 408) | fn set_http_request_trailer_bytes(&self, name: &str, value: Option<&[u...
method add_http_request_trailer (line 412) | fn add_http_request_trailer(&self, name: &str, value: &str) {
method add_http_request_trailer_bytes (line 416) | fn add_http_request_trailer_bytes(&self, name: &str, value: &[u8]) {
method remove_http_request_trailer (line 420) | fn remove_http_request_trailer(&self, name: &str) {
method resume_http_request (line 424) | fn resume_http_request(&self) {
method reset_http_request (line 428) | fn reset_http_request(&self) {
method on_http_response_headers (line 432) | fn on_http_response_headers(&mut self, _num_headers: usize, _end_of_st...
method get_http_response_headers (line 436) | fn get_http_response_headers(&self) -> Vec<(String, String)> {
method get_http_response_headers_bytes (line 440) | fn get_http_response_headers_bytes(&self) -> Vec<(String, Bytes)> {
method set_http_response_headers (line 444) | fn set_http_response_headers(&self, headers: Vec<(&str, &str)>) {
method set_http_response_headers_bytes (line 448) | fn set_http_response_headers_bytes(&self, headers: Vec<(&str, &[u8])>) {
method get_http_response_header (line 452) | fn get_http_response_header(&self, name: &str) -> Option<String> {
method get_http_response_header_bytes (line 456) | fn get_http_response_header_bytes(&self, name: &str) -> Option<Bytes> {
method set_http_response_header (line 460) | fn set_http_response_header(&self, name: &str, value: Option<&str>) {
method set_http_response_header_bytes (line 464) | fn set_http_response_header_bytes(&self, name: &str, value: Option<&[u...
method add_http_response_header (line 468) | fn add_http_response_header(&self, name: &str, value: &str) {
method add_http_response_header_bytes (line 472) | fn add_http_response_header_bytes(&self, name: &str, value: &[u8]) {
method remove_http_response_header (line 476) | fn remove_http_response_header(&self, name: &str) {
method on_http_response_body (line 480) | fn on_http_response_body(&mut self, _body_size: usize, _end_of_stream:...
method get_http_response_body (line 484) | fn get_http_response_body(&self, start: usize, max_size: usize) -> Opt...
method set_http_response_body (line 488) | fn set_http_response_body(&self, start: usize, size: usize, value: &[u...
method on_http_response_trailers (line 492) | fn on_http_response_trailers(&mut self, _num_trailers: usize) -> Action {
method get_http_response_trailers (line 496) | fn get_http_response_trailers(&self) -> Vec<(String, String)> {
method get_http_response_trailers_bytes (line 500) | fn get_http_response_trailers_bytes(&self) -> Vec<(String, Bytes)> {
method set_http_response_trailers (line 504) | fn set_http_response_trailers(&self, trailers: Vec<(&str, &str)>) {
method set_http_response_trailers_bytes (line 508) | fn set_http_response_trailers_bytes(&self, trailers: Vec<(&str, &[u8])...
method get_http_response_trailer (line 512) | fn get_http_response_trailer(&self, name: &str) -> Option<String> {
method get_http_response_trailer_bytes (line 516) | fn get_http_response_trailer_bytes(&self, name: &str) -> Option<Bytes> {
method set_http_response_trailer (line 520) | fn set_http_response_trailer(&self, name: &str, value: Option<&str>) {
method set_http_response_trailer_bytes (line 524) | fn set_http_response_trailer_bytes(&self, name: &str, value: Option<&[...
method add_http_response_trailer (line 528) | fn add_http_response_trailer(&self, name: &str, value: &str) {
method add_http_response_trailer_bytes (line 532) | fn add_http_response_trailer_bytes(&self, name: &str, value: &[u8]) {
method remove_http_response_trailer (line 536) | fn remove_http_response_trailer(&self, name: &str) {
method resume_http_response (line 540) | fn resume_http_response(&self) {
method reset_http_response (line 544) | fn reset_http_response(&self) {
method send_http_response (line 548) | fn send_http_response(
method send_grpc_response (line 557) | fn send_grpc_response(
method on_log (line 566) | fn on_log(&mut self) {}
FILE: src/types.rs
type NewRootContext (line 17) | pub type NewRootContext = fn(context_id: u32) -> Box<dyn RootContext>;
type NewStreamContext (line 18) | pub type NewStreamContext = fn(context_id: u32, root_context_id: u32) ->...
type NewHttpContext (line 19) | pub type NewHttpContext = fn(context_id: u32, root_context_id: u32) -> B...
type LogLevel (line 23) | pub enum LogLevel {
type Action (line 35) | pub enum Action {
type Status (line 43) | pub enum Status {
type ContextType (line 57) | pub enum ContextType {
type StreamType (line 65) | pub enum StreamType {
type BufferType (line 75) | pub enum BufferType {
type MapType (line 90) | pub enum MapType {
type PeerType (line 104) | pub enum PeerType {
type MetricType (line 113) | pub enum MetricType {
type GrpcStatusCode (line 122) | pub enum GrpcStatusCode {
type Bytes (line 142) | pub type Bytes = Vec<u8>;
Condensed preview — 80 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (264K chars).
[
{
"path": ".actrc",
"chars": 46,
"preview": "-P ubuntu-24.04=catthehacker/ubuntu:act-24.04\n"
},
{
"path": ".bazelrc",
"chars": 94,
"preview": "# Force Bazel to use --target=wasm32-wasip1\nbuild --platforms=@rules_rust//rust/platform:wasi\n"
},
{
"path": ".bazelversion",
"chars": 6,
"preview": "8.5.1\n"
},
{
"path": ".bcr/metadata.template.json",
"chars": 308,
"preview": "{\n \"homepage\": \"https://github.com/proxy-wasm/proxy-wasm-rust-sdk\",\n \"maintainers\": [\n {\n \"github\": \"PiotrSiko"
},
{
"path": ".bcr/presubmit.yml",
"chars": 880,
"preview": "# Copyright 2025 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": ".bcr/source.template.json",
"chars": 155,
"preview": "{\n \"integrity\": \"\",\n \"strip_prefix\": \"proxy-wasm-rust-sdk-{VERSION}\",\n \"url\": \"https://github.com/{OWNER}/{REPO}/arch"
},
{
"path": ".github/dependabot.yml",
"chars": 1088,
"preview": "# Copyright 2025 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": ".github/workflows/publish-to-bcr.yml",
"chars": 1325,
"preview": "# Copyright 2025 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": ".github/workflows/rust.yml",
"chars": 15344,
"preview": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": ".gitignore",
"chars": 27,
"preview": "/bazel-*\ntarget\nCargo.lock\n"
},
{
"path": "BUILD",
"chars": 1484,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "CHANGELOG.md",
"chars": 4357,
"preview": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Change"
},
{
"path": "CODEOWNERS",
"chars": 15,
"preview": "* @PiotrSikora\n"
},
{
"path": "CONTRIBUTING.md",
"chars": 1097,
"preview": "# How to Contribute\n\nWe'd love to accept your patches and contributions to this project. There are\njust a few small guid"
},
{
"path": "Cargo.toml",
"chars": 1181,
"preview": "# Copyright 2026 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "DEVELOPMENT.md",
"chars": 796,
"preview": "# Development\n\n## Testing\n\nGitHub Actions can be executed locally using the [`act`] tool.\n\nAll tests can be executed usi"
},
{
"path": "LICENSE",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "MODULE.bazel",
"chars": 1608,
"preview": "# Copyright 2025 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "README.md",
"chars": 1551,
"preview": "# WebAssembly for Proxies (Rust SDK)\n\n[![Build Status][build-badge]][build-link]\n[![Crate][crate-badge]][crate-link]\n[!["
},
{
"path": "WORKSPACE",
"chars": 604,
"preview": "workspace(name = \"proxy_wasm_rust_sdk\")\n\nload(\"@proxy_wasm_rust_sdk//bazel:repositories.bzl\", \"proxy_wasm_rust_sdk_repos"
},
{
"path": "WORKSPACE.bzlmod",
"chars": 575,
"preview": "# Copyright 2025 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "bazel/BUILD",
"chars": 575,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "bazel/cargo/BUILD",
"chars": 904,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "bazel/cargo/remote/BUILD.allocator-api2-0.2.21.bazel",
"chars": 4066,
"preview": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file "
},
{
"path": "bazel/cargo/remote/BUILD.bazel",
"chars": 1466,
"preview": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file "
},
{
"path": "bazel/cargo/remote/BUILD.equivalent-1.0.2.bazel",
"chars": 4010,
"preview": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file "
},
{
"path": "bazel/cargo/remote/BUILD.foldhash-0.2.0.bazel",
"chars": 4006,
"preview": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file "
},
{
"path": "bazel/cargo/remote/BUILD.hashbrown-0.16.0.bazel",
"chars": 4372,
"preview": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file "
},
{
"path": "bazel/cargo/remote/BUILD.log-0.4.27.bazel",
"chars": 3997,
"preview": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file "
},
{
"path": "bazel/cargo/remote/alias_rules.bzl",
"chars": 1786,
"preview": "\"\"\"Alias that transitions its target to `compilation_mode=opt`. Use `transition_alias=\"opt\"` to enable.\"\"\"\n\nload(\"@rule"
},
{
"path": "bazel/cargo/remote/crates.bzl",
"chars": 1287,
"preview": "###############################################################################\n# @generated\n# This file is auto-generat"
},
{
"path": "bazel/cargo/remote/defs.bzl",
"chars": 17693,
"preview": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file "
},
{
"path": "bazel/dependencies_bazel.bzl",
"chars": 707,
"preview": "# Copyright 2025 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "bazel/dependencies_compat.bzl",
"chars": 720,
"preview": "# Copyright 2025 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "bazel/dependencies_crates.bzl",
"chars": 956,
"preview": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "bazel/extensions.bzl",
"chars": 1220,
"preview": "# Copyright 2025 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "bazel/repositories.bzl",
"chars": 1891,
"preview": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "build.rs",
"chars": 1484,
"preview": "// Copyright 2022 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "examples/envoy_filter_metadata/Cargo.toml",
"chars": 1008,
"preview": "# Copyright 2026 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/envoy_filter_metadata/README.md",
"chars": 898,
"preview": "## Proxy-Wasm plugin example: Envoy metadata\n\nProxy-Wasm plugin that demonstrates reading metadata set by other Envoy fi"
},
{
"path": "examples/envoy_filter_metadata/docker-compose.yaml",
"chars": 872,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/envoy_filter_metadata/envoy.yaml",
"chars": 3258,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/envoy_filter_metadata/src/lib.rs",
"chars": 1753,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "examples/grpc_auth_random/Cargo.toml",
"chars": 956,
"preview": "# Copyright 2026 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/grpc_auth_random/README.md",
"chars": 1027,
"preview": "## Proxy-Wasm plugin example: gRPC auth (random)\n\nProxy-Wasm plugin that grants access based on a result of gRPC callout"
},
{
"path": "examples/grpc_auth_random/docker-compose.yaml",
"chars": 1024,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/grpc_auth_random/envoy.yaml",
"chars": 2618,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/grpc_auth_random/src/lib.rs",
"chars": 2895,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "examples/hello_world/Cargo.toml",
"chars": 1199,
"preview": "# Copyright 2026 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/hello_world/README.md",
"chars": 781,
"preview": "## Proxy-Wasm plugin example: Hello World\n\nProxy-Wasm background service plugin that logs time and random numbers.\n\n### "
},
{
"path": "examples/hello_world/docker-compose.yaml",
"chars": 872,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/hello_world/envoy.yaml",
"chars": 972,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/hello_world/src/lib.rs",
"chars": 1668,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "examples/http_auth_random/Cargo.toml",
"chars": 1008,
"preview": "# Copyright 2026 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_auth_random/README.md",
"chars": 1017,
"preview": "## Proxy-Wasm plugin example: HTTP auth (random)\n\nProxy-Wasm plugin that grants access based on a result of HTTP callout"
},
{
"path": "examples/http_auth_random/docker-compose.yaml",
"chars": 1032,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_auth_random/envoy.yaml",
"chars": 2585,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_auth_random/src/lib.rs",
"chars": 2159,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "examples/http_body/Cargo.toml",
"chars": 980,
"preview": "# Copyright 2026 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_body/README.md",
"chars": 675,
"preview": "## Proxy-Wasm plugin example: HTTP body\n\nProxy-Wasm plugin that redacts sensitive HTTP responses.\n\n### Building\n\n```sh\n$"
},
{
"path": "examples/http_body/docker-compose.yaml",
"chars": 872,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_body/envoy.yaml",
"chars": 2595,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_body/src/lib.rs",
"chars": 2482,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "examples/http_config/Cargo.toml",
"chars": 984,
"preview": "# Copyright 2026 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_config/README.md",
"chars": 662,
"preview": "## Proxy-Wasm plugin example: HTTP config\n\nProxy-Wasm plugin that injects HTTP response header with a value from Envoy c"
},
{
"path": "examples/http_config/docker-compose.yaml",
"chars": 872,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_config/envoy.yaml",
"chars": 2547,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_config/src/lib.rs",
"chars": 1871,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "examples/http_headers/Cargo.toml",
"chars": 998,
"preview": "# Copyright 2026 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_headers/README.md",
"chars": 1267,
"preview": "## Proxy-Wasm plugin example: HTTP headers\n\nProxy-Wasm plugin that logs HTTP request/response headers.\n\n### Building\n\n``"
},
{
"path": "examples/http_headers/docker-compose.yaml",
"chars": 872,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_headers/envoy.yaml",
"chars": 2318,
"preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
},
{
"path": "examples/http_headers/src/lib.rs",
"chars": 2228,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "src/allocator.rs",
"chars": 1054,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "src/dispatcher.rs",
"chars": 28178,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "src/hostcalls.rs",
"chars": 46428,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "src/lib.rs",
"chars": 1973,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "src/logger.rs",
"chars": 2357,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "src/traits.rs",
"chars": 19349,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
},
{
"path": "src/types.rs",
"chars": 3307,
"preview": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use th"
}
]
About this extraction
This page contains the full source code of the proxy-wasm/proxy-wasm-rust-sdk GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 80 files (243.7 KB), approximately 63.0k tokens, and a symbol index with 372 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.