From 260f1b3e67f1d515f2ed1b4ca1adc40ec81247e8 Mon Sep 17 00:00:00 2001 From: wangbaiping/wbpcode Date: Fri, 18 Oct 2024 18:11:31 +0800 Subject: [PATCH 1/3] proxy wasm 0.3.0: bring stop iteration support back Signed-off-by: wangbaiping/wbpcode --- include/proxy-wasm/context.h | 3 +- include/proxy-wasm/wasm.h | 4 +-- include/proxy-wasm/wasm_vm.h | 8 ++++- src/context.cc | 62 ++++++++++++++++++++++++++---------- src/wasm.cc | 13 ++++++-- 5 files changed, 67 insertions(+), 23 deletions(-) diff --git a/include/proxy-wasm/context.h b/include/proxy-wasm/context.h index 12937041..4bebebe9 100644 --- a/include/proxy-wasm/context.h +++ b/include/proxy-wasm/context.h @@ -28,6 +28,7 @@ #include "include/proxy-wasm/sdk.h" #include "include/proxy-wasm/context_interface.h" +#include "include/proxy-wasm/wasm_vm.h" namespace proxy_wasm { @@ -399,7 +400,7 @@ class ContextBase : public RootInterface, private: // helper functions - FilterHeadersStatus convertVmCallResultToFilterHeadersStatus(uint64_t result); + FilterHeadersStatus convertVmCallResultToFilterHeadersStatus(uint64_t result, AbiVersion version); FilterDataStatus convertVmCallResultToFilterDataStatus(uint64_t result); FilterTrailersStatus convertVmCallResultToFilterTrailersStatus(uint64_t result); FilterMetadataStatus convertVmCallResultToFilterMetadataStatus(uint64_t result); diff --git a/include/proxy-wasm/wasm.h b/include/proxy-wasm/wasm.h index 9fa2bda1..2182bed3 100644 --- a/include/proxy-wasm/wasm.h +++ b/include/proxy-wasm/wasm.h @@ -243,13 +243,13 @@ class WasmBase : public std::enable_shared_from_this { WasmCallVoid<2> on_upstream_connection_close_; WasmCallWord<2> on_request_headers_abi_01_; - WasmCallWord<3> on_request_headers_abi_02_; + WasmCallWord<3> on_request_headers_; WasmCallWord<3> on_request_body_; WasmCallWord<2> on_request_trailers_; WasmCallWord<2> on_request_metadata_; WasmCallWord<2> on_response_headers_abi_01_; - WasmCallWord<3> on_response_headers_abi_02_; + WasmCallWord<3> on_response_headers_; WasmCallWord<3> on_response_body_; WasmCallWord<2> on_response_trailers_; WasmCallWord<2> on_response_metadata_; diff --git a/include/proxy-wasm/wasm_vm.h b/include/proxy-wasm/wasm_vm.h index a573212e..bd27c2e6 100644 --- a/include/proxy-wasm/wasm_vm.h +++ b/include/proxy-wasm/wasm_vm.h @@ -139,7 +139,13 @@ enum class Cloneable { InstantiatedModule // VMs can be cloned from an instantiated module. }; -enum class AbiVersion { ProxyWasm_0_1_0, ProxyWasm_0_2_0, ProxyWasm_0_2_1, Unknown }; +enum class AbiVersion { + ProxyWasm_0_1_0, + ProxyWasm_0_2_0, + ProxyWasm_0_2_1, + ProxyWasm_0_3_0, + Unknown, +}; class NullPlugin; diff --git a/src/context.cc b/src/context.cc index 5353a52a..92b551c7 100644 --- a/src/context.cc +++ b/src/context.cc @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include @@ -312,21 +313,31 @@ void ContextBase::onUpstreamConnectionClose(CloseType close_type) { } } -// Empty headers/trailers have zero size. -template static uint32_t headerSize(const P &p) { return p ? p->size() : 0; } - FilterHeadersStatus ContextBase::onRequestHeaders(uint32_t headers, bool end_of_stream) { CHECK_FAIL_HTTP(FilterHeadersStatus::Continue, FilterHeadersStatus::StopAllIterationAndWatermark); - if (!wasm_->on_request_headers_abi_01_ && !wasm_->on_request_headers_abi_02_) { + if (!wasm_->on_request_headers_abi_01_ && !wasm_->on_request_headers_) { return FilterHeadersStatus::Continue; } DeferAfterCallActions actions(this); - const auto result = wasm_->on_request_headers_abi_01_ - ? wasm_->on_request_headers_abi_01_(this, id_, headers) - : wasm_->on_request_headers_abi_02_(this, id_, headers, - static_cast(end_of_stream)); + + AbiVersion wasm_abi_version = wasm_->abi_version_; + uint64_t result{}; + switch (wasm_abi_version) { + case AbiVersion::ProxyWasm_0_1_0: + result = wasm_->on_request_headers_abi_01_(this, id_, headers); + break; + case AbiVersion::ProxyWasm_0_2_0: + case AbiVersion::ProxyWasm_0_2_1: + case AbiVersion::ProxyWasm_0_3_0: + result = wasm_->on_request_headers_(this, id_, headers, static_cast(end_of_stream)); + break; + case AbiVersion::Unknown: + assert(false); // Should never reach here. + return FilterHeadersStatus::Continue; + } + CHECK_FAIL_HTTP(FilterHeadersStatus::Continue, FilterHeadersStatus::StopAllIterationAndWatermark); - return convertVmCallResultToFilterHeadersStatus(result); + return convertVmCallResultToFilterHeadersStatus(result, wasm_abi_version); } FilterDataStatus ContextBase::onRequestBody(uint32_t body_length, bool end_of_stream) { @@ -365,16 +376,29 @@ FilterMetadataStatus ContextBase::onRequestMetadata(uint32_t elements) { FilterHeadersStatus ContextBase::onResponseHeaders(uint32_t headers, bool end_of_stream) { CHECK_FAIL_HTTP(FilterHeadersStatus::Continue, FilterHeadersStatus::StopAllIterationAndWatermark); - if (!wasm_->on_response_headers_abi_01_ && !wasm_->on_response_headers_abi_02_) { + if (!wasm_->on_response_headers_abi_01_ && !wasm_->on_response_headers_) { return FilterHeadersStatus::Continue; } DeferAfterCallActions actions(this); - const auto result = wasm_->on_response_headers_abi_01_ - ? wasm_->on_response_headers_abi_01_(this, id_, headers) - : wasm_->on_response_headers_abi_02_( - this, id_, headers, static_cast(end_of_stream)); + + AbiVersion wasm_abi_version = wasm_->abi_version_; + uint64_t result{}; + switch (wasm_abi_version) { + case AbiVersion::ProxyWasm_0_1_0: + result = wasm_->on_response_headers_abi_01_(this, id_, headers); + break; + case AbiVersion::ProxyWasm_0_2_0: + case AbiVersion::ProxyWasm_0_2_1: + case AbiVersion::ProxyWasm_0_3_0: + result = wasm_->on_response_headers_(this, id_, headers, static_cast(end_of_stream)); + break; + case AbiVersion::Unknown: + assert(false); // Should never reach here. + return FilterHeadersStatus::Continue; + } + CHECK_FAIL_HTTP(FilterHeadersStatus::Continue, FilterHeadersStatus::StopAllIterationAndWatermark); - return convertVmCallResultToFilterHeadersStatus(result); + return convertVmCallResultToFilterHeadersStatus(result, wasm_abi_version); } FilterDataStatus ContextBase::onResponseBody(uint32_t body_length, bool end_of_stream) { @@ -488,12 +512,16 @@ WasmResult ContextBase::setTimerPeriod(std::chrono::milliseconds period, return WasmResult::Ok; } -FilterHeadersStatus ContextBase::convertVmCallResultToFilterHeadersStatus(uint64_t result) { +FilterHeadersStatus ContextBase::convertVmCallResultToFilterHeadersStatus(uint64_t result, + AbiVersion abi_version) { if (wasm()->isNextIterationStopped() || result > static_cast(FilterHeadersStatus::StopAllIterationAndWatermark)) { return FilterHeadersStatus::StopAllIterationAndWatermark; } - if (result == static_cast(FilterHeadersStatus::StopIteration)) { + + // Only Proxy-WASM 0.2.1 and earlier convert StopIteration to StopAllIterationAndWatermark. + if (abi_version < AbiVersion::ProxyWasm_0_3_0 && + result == static_cast(FilterHeadersStatus::StopIteration)) { // Always convert StopIteration (pause processing headers, but continue processing body) // to StopAllIterationAndWatermark (pause all processing), since the former breaks all // assumptions about HTTP processing. diff --git a/src/wasm.cc b/src/wasm.cc index cb1dd9b3..32e72d3a 100644 --- a/src/wasm.cc +++ b/src/wasm.cc @@ -31,6 +31,7 @@ #include "include/proxy-wasm/bytecode_util.h" #include "include/proxy-wasm/signature_util.h" #include "include/proxy-wasm/vm_id_handle.h" +#include "include/proxy-wasm/wasm_vm.h" #include "src/hash.h" namespace proxy_wasm { @@ -150,6 +151,10 @@ void WasmBase::registerCallbacks() { _REGISTER_PROXY(continue_stream); _REGISTER_PROXY(close_stream); _REGISTER_PROXY(get_log_level); + } else if (abiVersion() == AbiVersion::ProxyWasm_0_3_0) { + _REGISTER_PROXY(continue_stream); + _REGISTER_PROXY(close_stream); + _REGISTER_PROXY(get_log_level); } #undef _REGISTER_PROXY @@ -197,8 +202,12 @@ void WasmBase::getFunctions() { _GET_PROXY_ABI(on_response_headers, _abi_01); } else if (abiVersion() == AbiVersion::ProxyWasm_0_2_0 || abiVersion() == AbiVersion::ProxyWasm_0_2_1) { - _GET_PROXY_ABI(on_request_headers, _abi_02); - _GET_PROXY_ABI(on_response_headers, _abi_02); + _GET_PROXY(on_request_headers); + _GET_PROXY(on_response_headers); + _GET_PROXY(on_foreign_function); + } else if (abiVersion() == AbiVersion::ProxyWasm_0_3_0) { + _GET_PROXY(on_request_headers); + _GET_PROXY(on_response_headers); _GET_PROXY(on_foreign_function); } #undef _GET_PROXY_ABI From 4af1b534c2f4993a2be7ec458d549943337822d8 Mon Sep 17 00:00:00 2001 From: wangbaiping/wbpcode Date: Sat, 19 Oct 2024 17:28:46 +0800 Subject: [PATCH 2/3] simplify the code Signed-off-by: wangbaiping/wbpcode --- include/proxy-wasm/null_plugin.h | 1 + src/context.cc | 30 ++++++++++-------------------- src/wasm.cc | 18 +++++++----------- 3 files changed, 18 insertions(+), 31 deletions(-) diff --git a/include/proxy-wasm/null_plugin.h b/include/proxy-wasm/null_plugin.h index b33187ce..7480f1f3 100644 --- a/include/proxy-wasm/null_plugin.h +++ b/include/proxy-wasm/null_plugin.h @@ -31,6 +31,7 @@ struct NullPluginRegistry { void (*proxy_abi_version_0_1_0_)() = nullptr; void (*proxy_abi_version_0_2_0_)() = nullptr; void (*proxy_abi_version_0_2_1_)() = nullptr; + void (*proxy_abi_version_0_3_0_)() = nullptr; void (*proxy_on_log_)(uint32_t context_id) = nullptr; uint32_t (*proxy_validate_configuration_)(uint32_t root_context_id, uint32_t plugin_configuration_size) = nullptr; diff --git a/src/context.cc b/src/context.cc index 92b551c7..e6d14cf0 100644 --- a/src/context.cc +++ b/src/context.cc @@ -322,18 +322,13 @@ FilterHeadersStatus ContextBase::onRequestHeaders(uint32_t headers, bool end_of_ AbiVersion wasm_abi_version = wasm_->abi_version_; uint64_t result{}; - switch (wasm_abi_version) { - case AbiVersion::ProxyWasm_0_1_0: + + if (wasm_->abi_version_ == AbiVersion::ProxyWasm_0_1_0) { + // For ProxyWasm_0_1_0. result = wasm_->on_request_headers_abi_01_(this, id_, headers); - break; - case AbiVersion::ProxyWasm_0_2_0: - case AbiVersion::ProxyWasm_0_2_1: - case AbiVersion::ProxyWasm_0_3_0: + } else { + // For ProxyWasm_0_2_0, ProxyWasm_0_2_1, or ProxyWasm_0_3_0. result = wasm_->on_request_headers_(this, id_, headers, static_cast(end_of_stream)); - break; - case AbiVersion::Unknown: - assert(false); // Should never reach here. - return FilterHeadersStatus::Continue; } CHECK_FAIL_HTTP(FilterHeadersStatus::Continue, FilterHeadersStatus::StopAllIterationAndWatermark); @@ -383,18 +378,13 @@ FilterHeadersStatus ContextBase::onResponseHeaders(uint32_t headers, bool end_of AbiVersion wasm_abi_version = wasm_->abi_version_; uint64_t result{}; - switch (wasm_abi_version) { - case AbiVersion::ProxyWasm_0_1_0: + + if (wasm_->abi_version_ == AbiVersion::ProxyWasm_0_1_0) { + // For ProxyWasm_0_1_0. result = wasm_->on_response_headers_abi_01_(this, id_, headers); - break; - case AbiVersion::ProxyWasm_0_2_0: - case AbiVersion::ProxyWasm_0_2_1: - case AbiVersion::ProxyWasm_0_3_0: + } else { + // For ProxyWasm_0_2_0, ProxyWasm_0_2_1, or ProxyWasm_0_3_0. result = wasm_->on_response_headers_(this, id_, headers, static_cast(end_of_stream)); - break; - case AbiVersion::Unknown: - assert(false); // Should never reach here. - return FilterHeadersStatus::Continue; } CHECK_FAIL_HTTP(FilterHeadersStatus::Continue, FilterHeadersStatus::StopAllIterationAndWatermark); diff --git a/src/wasm.cc b/src/wasm.cc index 32e72d3a..5cb7fcb9 100644 --- a/src/wasm.cc +++ b/src/wasm.cc @@ -140,18 +140,17 @@ void WasmBase::registerCallbacks() { FOR_ALL_HOST_FUNCTIONS(_REGISTER_PROXY); if (abiVersion() == AbiVersion::ProxyWasm_0_1_0) { + // For ProxyWasm_0_1_0. _REGISTER_PROXY(get_configuration); _REGISTER_PROXY(continue_request); _REGISTER_PROXY(continue_response); _REGISTER_PROXY(clear_route_cache); } else if (abiVersion() == AbiVersion::ProxyWasm_0_2_0) { + // For ProxyWasm_0_2_0. _REGISTER_PROXY(continue_stream); _REGISTER_PROXY(close_stream); - } else if (abiVersion() == AbiVersion::ProxyWasm_0_2_1) { - _REGISTER_PROXY(continue_stream); - _REGISTER_PROXY(close_stream); - _REGISTER_PROXY(get_log_level); - } else if (abiVersion() == AbiVersion::ProxyWasm_0_3_0) { + } else { + // For ProxyWasm_0_2_1 or ProxyWasm_0_3_0. _REGISTER_PROXY(continue_stream); _REGISTER_PROXY(close_stream); _REGISTER_PROXY(get_log_level); @@ -198,14 +197,11 @@ void WasmBase::getFunctions() { FOR_ALL_MODULE_FUNCTIONS(_GET_PROXY); if (abiVersion() == AbiVersion::ProxyWasm_0_1_0) { + // For ProxyWasm_0_1_0. _GET_PROXY_ABI(on_request_headers, _abi_01); _GET_PROXY_ABI(on_response_headers, _abi_01); - } else if (abiVersion() == AbiVersion::ProxyWasm_0_2_0 || - abiVersion() == AbiVersion::ProxyWasm_0_2_1) { - _GET_PROXY(on_request_headers); - _GET_PROXY(on_response_headers); - _GET_PROXY(on_foreign_function); - } else if (abiVersion() == AbiVersion::ProxyWasm_0_3_0) { + } else { + // For ProxyWasm_0_2_0, ProxyWasm_0_2_1, or ProxyWasm_0_3_0. _GET_PROXY(on_request_headers); _GET_PROXY(on_response_headers); _GET_PROXY(on_foreign_function); From 93b4650b6707da3e6410be9783990c64ade59a98 Mon Sep 17 00:00:00 2001 From: wangbaiping/wbpcode Date: Mon, 21 Oct 2024 15:17:08 +0800 Subject: [PATCH 3/3] parse the abi version Signed-off-by: wangbaiping/wbpcode --- src/bytecode_util.cc | 4 ++++ src/context.cc | 26 ++++++++------------------ src/wasm.cc | 7 +++++-- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/bytecode_util.cc b/src/bytecode_util.cc index 70a373e0..fcb2033d 100644 --- a/src/bytecode_util.cc +++ b/src/bytecode_util.cc @@ -83,6 +83,10 @@ bool BytecodeUtil::getAbiVersion(std::string_view bytecode, proxy_wasm::AbiVersi ret = AbiVersion::ProxyWasm_0_2_1; return true; } + if (export_name == "proxy_abi_version_0_3_0") { + ret = AbiVersion::ProxyWasm_0_3_0; + return true; + } } // Skip export's index. if (!parseVarint(pos, end, export_name_size)) { diff --git a/src/context.cc b/src/context.cc index e6d14cf0..28e8d9e6 100644 --- a/src/context.cc +++ b/src/context.cc @@ -321,15 +321,10 @@ FilterHeadersStatus ContextBase::onRequestHeaders(uint32_t headers, bool end_of_ DeferAfterCallActions actions(this); AbiVersion wasm_abi_version = wasm_->abi_version_; - uint64_t result{}; - - if (wasm_->abi_version_ == AbiVersion::ProxyWasm_0_1_0) { - // For ProxyWasm_0_1_0. - result = wasm_->on_request_headers_abi_01_(this, id_, headers); - } else { - // For ProxyWasm_0_2_0, ProxyWasm_0_2_1, or ProxyWasm_0_3_0. - result = wasm_->on_request_headers_(this, id_, headers, static_cast(end_of_stream)); - } + const uint64_t result = + wasm_->on_request_headers_abi_01_ + ? wasm_->on_request_headers_abi_01_(this, id_, headers) + : wasm_->on_request_headers_(this, id_, headers, static_cast(end_of_stream)); CHECK_FAIL_HTTP(FilterHeadersStatus::Continue, FilterHeadersStatus::StopAllIterationAndWatermark); return convertVmCallResultToFilterHeadersStatus(result, wasm_abi_version); @@ -377,15 +372,10 @@ FilterHeadersStatus ContextBase::onResponseHeaders(uint32_t headers, bool end_of DeferAfterCallActions actions(this); AbiVersion wasm_abi_version = wasm_->abi_version_; - uint64_t result{}; - - if (wasm_->abi_version_ == AbiVersion::ProxyWasm_0_1_0) { - // For ProxyWasm_0_1_0. - result = wasm_->on_response_headers_abi_01_(this, id_, headers); - } else { - // For ProxyWasm_0_2_0, ProxyWasm_0_2_1, or ProxyWasm_0_3_0. - result = wasm_->on_response_headers_(this, id_, headers, static_cast(end_of_stream)); - } + const uint64_t result = + wasm_->on_response_headers_abi_01_ + ? wasm_->on_response_headers_abi_01_(this, id_, headers) + : wasm_->on_response_headers_(this, id_, headers, static_cast(end_of_stream)); CHECK_FAIL_HTTP(FilterHeadersStatus::Continue, FilterHeadersStatus::StopAllIterationAndWatermark); return convertVmCallResultToFilterHeadersStatus(result, wasm_abi_version); diff --git a/src/wasm.cc b/src/wasm.cc index 5cb7fcb9..9c296df4 100644 --- a/src/wasm.cc +++ b/src/wasm.cc @@ -149,7 +149,8 @@ void WasmBase::registerCallbacks() { // For ProxyWasm_0_2_0. _REGISTER_PROXY(continue_stream); _REGISTER_PROXY(close_stream); - } else { + } else if (abiVersion() == AbiVersion::ProxyWasm_0_2_1 || + abiVersion() == AbiVersion::ProxyWasm_0_3_0) { // For ProxyWasm_0_2_1 or ProxyWasm_0_3_0. _REGISTER_PROXY(continue_stream); _REGISTER_PROXY(close_stream); @@ -200,7 +201,9 @@ void WasmBase::getFunctions() { // For ProxyWasm_0_1_0. _GET_PROXY_ABI(on_request_headers, _abi_01); _GET_PROXY_ABI(on_response_headers, _abi_01); - } else { + } else if (abiVersion() == AbiVersion::ProxyWasm_0_2_0 || + abiVersion() == AbiVersion::ProxyWasm_0_2_1 || + abiVersion() == AbiVersion::ProxyWasm_0_3_0) { // For ProxyWasm_0_2_0, ProxyWasm_0_2_1, or ProxyWasm_0_3_0. _GET_PROXY(on_request_headers); _GET_PROXY(on_response_headers);