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/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/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/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 5353a52a..28e8d9e6 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,21 @@ 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_; + 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); + return convertVmCallResultToFilterHeadersStatus(result, wasm_abi_version); } FilterDataStatus ContextBase::onRequestBody(uint32_t body_length, bool end_of_stream) { @@ -365,16 +366,19 @@ 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_; + 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); + return convertVmCallResultToFilterHeadersStatus(result, wasm_abi_version); } FilterDataStatus ContextBase::onResponseBody(uint32_t body_length, bool end_of_stream) { @@ -488,12 +492,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..9c296df4 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 { @@ -139,14 +140,18 @@ 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) { + } 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); _REGISTER_PROXY(get_log_level); @@ -193,12 +198,15 @@ 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_ABI(on_request_headers, _abi_02); - _GET_PROXY_ABI(on_response_headers, _abi_02); + 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); _GET_PROXY(on_foreign_function); } #undef _GET_PROXY_ABI