From feb1c88c0e6307e426d372e71ae663d9a26aaa05 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Wed, 18 Nov 2020 09:38:30 +0000 Subject: [PATCH 1/2] Update ABI to Proxy-Wasm ABI v0.2.1. Signed-off-by: Piotr Sikora --- CHANGELOG.md | 7 ++++ examples/http_auth_random.rs | 4 +-- examples/http_body.rs | 2 +- examples/http_config.rs | 4 +-- examples/http_headers.rs | 4 +-- src/dispatcher.rs | 38 +++++++++++++++----- src/hostcalls.rs | 70 ++++++++++++------------------------ src/lib.rs | 2 +- src/traits.rs | 36 +++++++++++++------ src/types.rs | 11 ++++++ 10 files changed, 105 insertions(+), 73 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c9ca036..e14d31b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ 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/). +## [Unreleased] + +### Changed + +- Updated ABI to Proxy-Wasm ABI v0.2.1. + ## [0.1.3] - 2020-12-04 ### Fixed @@ -46,6 +52,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Initial release. +[Unreleased]: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/compare/v0.1.3...HEAD [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 diff --git a/examples/http_auth_random.rs b/examples/http_auth_random.rs index b9e747c6..732b2f5f 100644 --- a/examples/http_auth_random.rs +++ b/examples/http_auth_random.rs @@ -26,7 +26,7 @@ pub fn _start() { struct HttpAuthRandom; impl HttpContext for HttpAuthRandom { - fn on_http_request_headers(&mut self, _: usize) -> Action { + fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action { self.dispatch_http_call( "httpbin", vec![ @@ -42,7 +42,7 @@ impl HttpContext for HttpAuthRandom { Action::Pause } - fn on_http_response_headers(&mut self, _: usize) -> Action { + fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action { self.set_http_response_header("Powered-By", Some("proxy-wasm")); Action::Continue } diff --git a/examples/http_body.rs b/examples/http_body.rs index ff884648..41eec096 100644 --- a/examples/http_body.rs +++ b/examples/http_body.rs @@ -40,7 +40,7 @@ struct HttpBody; impl Context for HttpBody {} impl HttpContext for HttpBody { - fn on_http_response_headers(&mut self, _: usize) -> Action { + 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 diff --git a/examples/http_config.rs b/examples/http_config.rs index d912ae03..790c259c 100644 --- a/examples/http_config.rs +++ b/examples/http_config.rs @@ -32,7 +32,7 @@ struct HttpConfigHeader { impl Context for HttpConfigHeader {} impl HttpContext for HttpConfigHeader { - fn on_http_response_headers(&mut self, _: usize) -> Action { + fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action { self.add_http_response_header("custom-header", self.header_content.as_str()); Action::Continue } @@ -46,7 +46,7 @@ impl Context for HttpConfigHeaderRoot {} impl RootContext for HttpConfigHeaderRoot { fn on_configure(&mut self, _: usize) -> bool { - if let Some(config_bytes) = self.get_configuration() { + if let Some(config_bytes) = self.get_plugin_configuration() { self.header_content = String::from_utf8(config_bytes).unwrap() } true diff --git a/examples/http_headers.rs b/examples/http_headers.rs index b0f1a745..0af2b528 100644 --- a/examples/http_headers.rs +++ b/examples/http_headers.rs @@ -43,7 +43,7 @@ struct HttpHeaders { impl Context for HttpHeaders {} impl HttpContext for HttpHeaders { - fn on_http_request_headers(&mut self, _: usize) -> Action { + fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action { for (name, value) in &self.get_http_request_headers() { trace!("#{} -> {}: {}", self.context_id, name, value); } @@ -61,7 +61,7 @@ impl HttpContext for HttpHeaders { } } - fn on_http_response_headers(&mut self, _: usize) -> Action { + fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action { for (name, value) in &self.get_http_response_headers() { trace!("#{} <- {}: {}", self.context_id, name, value); } diff --git a/src/dispatcher.rs b/src/dispatcher.rs index d9c9d491..6c329b9d 100644 --- a/src/dispatcher.rs +++ b/src/dispatcher.rs @@ -290,10 +290,15 @@ impl Dispatcher { } } - fn on_http_request_headers(&self, context_id: u32, num_headers: usize) -> Action { + 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) + http_stream.on_http_request_headers(num_headers, end_of_stream) } else { panic!("invalid context_id") } @@ -322,10 +327,15 @@ impl Dispatcher { } } - fn on_http_response_headers(&self, context_id: u32, num_headers: usize) -> Action { + 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) + http_stream.on_http_response_headers(num_headers, end_of_stream) } else { panic!("invalid context_id") } @@ -458,8 +468,14 @@ pub extern "C" fn proxy_on_upstream_connection_close(context_id: u32, peer_type: } #[no_mangle] -pub extern "C" fn proxy_on_request_headers(context_id: u32, num_headers: usize) -> Action { - DISPATCHER.with(|dispatcher| dispatcher.on_http_request_headers(context_id, num_headers)) +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] @@ -478,8 +494,14 @@ pub extern "C" fn proxy_on_request_trailers(context_id: u32, num_trailers: usize } #[no_mangle] -pub extern "C" fn proxy_on_response_headers(context_id: u32, num_headers: usize) -> Action { - DISPATCHER.with(|dispatcher| dispatcher.on_http_response_headers(context_id, num_headers)) +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] diff --git a/src/hostcalls.rs b/src/hostcalls.rs index 8f37f2ae..1c2628aa 100644 --- a/src/hostcalls.rs +++ b/src/hostcalls.rs @@ -31,55 +31,41 @@ pub fn log(level: LogLevel, message: &str) -> Result<(), Status> { } extern "C" { - fn proxy_get_current_time_nanoseconds(return_time: *mut u64) -> Status; + fn proxy_get_log_level(return_level: *mut LogLevel) -> Status; } -pub fn get_current_time() -> Result { - let mut return_time: u64 = 0; +pub fn get_log_level() -> Result { + let mut return_level: LogLevel = LogLevel::Trace; unsafe { - match proxy_get_current_time_nanoseconds(&mut return_time) { - Status::Ok => Ok(UNIX_EPOCH + Duration::from_nanos(return_time)), + match proxy_get_log_level(&mut return_level) { + Status::Ok => Ok(return_level), status => panic!("unexpected status: {}", status as u32), } } } extern "C" { - fn proxy_set_tick_period_milliseconds(period: u32) -> Status; + fn proxy_get_current_time_nanoseconds(return_time: *mut u64) -> Status; } -pub fn set_tick_period(period: Duration) -> Result<(), Status> { +pub fn get_current_time() -> Result { + let mut return_time: u64 = 0; unsafe { - match proxy_set_tick_period_milliseconds(period.as_millis() as u32) { - Status::Ok => Ok(()), + 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_get_configuration( - return_buffer_data: *mut *mut u8, - return_buffer_size: *mut usize, - ) -> Status; + fn proxy_set_tick_period_milliseconds(period: u32) -> Status; } -pub fn get_configuration() -> Result, Status> { - let mut return_data: *mut u8 = null_mut(); - let mut return_size: usize = 0; +pub fn set_tick_period(period: Duration) -> Result<(), Status> { unsafe { - match proxy_get_configuration(&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) - } - } + match proxy_set_tick_period_milliseconds(period.as_millis() as u32) { + Status::Ok => Ok(()), status => panic!("unexpected status: {}", status as u32), } } @@ -230,6 +216,7 @@ pub fn get_map_value(map_type: MapType, key: &str) -> Result, Sta Ok(None) } } + Status::NotFound => Ok(None), status => panic!("unexpected status: {}", status as u32), } } @@ -528,26 +515,28 @@ pub fn enqueue_shared_queue(queue_id: u32, value: Option<&[u8]>) -> Result<(), S } extern "C" { - fn proxy_continue_request() -> Status; + fn proxy_continue_stream(stream_type: StreamType) -> Status; } -pub fn resume_http_request() -> Result<(), Status> { +pub fn resume_stream(stream_type: StreamType) -> Result<(), Status> { unsafe { - match proxy_continue_request() { + match proxy_continue_stream(stream_type) { Status::Ok => Ok(()), + Status::BadArgument => Err(Status::BadArgument), status => panic!("unexpected status: {}", status as u32), } } } extern "C" { - fn proxy_continue_response() -> Status; + fn proxy_close_stream(stream_type: StreamType) -> Status; } -pub fn resume_http_response() -> Result<(), Status> { +pub fn close_stream(stream_type: StreamType) -> Result<(), Status> { unsafe { - match proxy_continue_response() { + match proxy_close_stream(stream_type) { Status::Ok => Ok(()), + Status::BadArgument => Err(Status::BadArgument), status => panic!("unexpected status: {}", status as u32), } } @@ -589,19 +578,6 @@ pub fn send_http_response( } } -extern "C" { - fn proxy_clear_route_cache() -> Status; -} - -pub fn clear_http_route_cache() -> Result<(), Status> { - unsafe { - match proxy_clear_route_cache() { - Status::Ok => Ok(()), - status => panic!("unexpected status: {}", status as u32), - } - } -} - extern "C" { fn proxy_http_call( upstream_data: *const u8, diff --git a/src/lib.rs b/src/lib.rs index cee98b72..fa8c7ca5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,4 +37,4 @@ pub fn set_http_context(callback: types::NewHttpContext) { } #[no_mangle] -pub extern "C" fn proxy_abi_version_0_1_0() {} +pub extern "C" fn proxy_abi_version_0_2_1() {} diff --git a/src/traits.rs b/src/traits.rs index 5b7fc4be..7a4dd27a 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -104,12 +104,16 @@ pub trait RootContext: Context { true } + fn get_vm_configuration(&self) -> Option { + hostcalls::get_buffer(BufferType::VmConfiguration, 0, usize::MAX).unwrap() + } + fn on_configure(&mut self, _plugin_configuration_size: usize) -> bool { true } - fn get_configuration(&self) -> Option { - hostcalls::get_configuration().unwrap() + fn get_plugin_configuration(&self) -> Option { + hostcalls::get_buffer(BufferType::PluginConfiguration, 0, usize::MAX).unwrap() } fn set_tick_period(&self, period: Duration) { @@ -152,6 +156,14 @@ pub trait StreamContext: Context { hostcalls::set_buffer(BufferType::DownstreamData, start, size, value).unwrap() } + fn resume_downstream(&self) { + hostcalls::resume_stream(StreamType::Downstream).unwrap() + } + + fn close_downstream(&self) { + hostcalls::close_stream(StreamType::Downstream).unwrap() + } + fn on_downstream_close(&mut self, _peer_type: PeerType) {} fn on_upstream_data(&mut self, _data_size: usize, _end_of_stream: bool) -> Action { @@ -166,13 +178,21 @@ pub trait StreamContext: Context { hostcalls::set_buffer(BufferType::UpstreamData, start, size, value).unwrap() } + fn resume_upstream(&self) { + hostcalls::resume_stream(StreamType::Upstream).unwrap() + } + + fn close_upstream(&self) { + hostcalls::close_stream(StreamType::Upstream).unwrap() + } + fn on_upstream_close(&mut self, _peer_type: PeerType) {} fn on_log(&mut self) {} } pub trait HttpContext: Context { - fn on_http_request_headers(&mut self, _num_headers: usize) -> Action { + fn on_http_request_headers(&mut self, _num_headers: usize, _end_of_stream: bool) -> Action { Action::Continue } @@ -233,10 +253,10 @@ pub trait HttpContext: Context { } fn resume_http_request(&self) { - hostcalls::resume_http_request().unwrap() + hostcalls::resume_stream(StreamType::HttpRequest).unwrap() } - fn on_http_response_headers(&mut self, _num_headers: usize) -> Action { + fn on_http_response_headers(&mut self, _num_headers: usize, _end_of_stream: bool) -> Action { Action::Continue } @@ -297,7 +317,7 @@ pub trait HttpContext: Context { } fn resume_http_response(&self) { - hostcalls::resume_http_response().unwrap() + hostcalls::resume_stream(StreamType::HttpResponse).unwrap() } fn send_http_response( @@ -309,9 +329,5 @@ pub trait HttpContext: Context { hostcalls::send_http_response(status_code, headers, body).unwrap() } - fn clear_http_route_cache(&self) { - hostcalls::clear_http_route_cache().unwrap() - } - fn on_log(&mut self) {} } diff --git a/src/types.rs b/src/types.rs index 855a414b..f36226df 100644 --- a/src/types.rs +++ b/src/types.rs @@ -54,6 +54,15 @@ pub enum ContextType { StreamContext = 1, } +#[repr(u32)] +#[derive(Debug)] +pub enum StreamType { + HttpRequest = 0, + HttpResponse = 1, + Downstream = 2, + Upstream = 3, +} + #[repr(u32)] #[derive(Debug)] pub enum BufferType { @@ -62,6 +71,8 @@ pub enum BufferType { DownstreamData = 2, UpstreamData = 3, HttpCallResponseBody = 4, + VmConfiguration = 6, + PluginConfiguration = 7, } #[repr(u32)] From ce9bf341817ae2a49cc9bc05ffda3a04f40892ef Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Tue, 13 Jul 2021 01:56:59 -0700 Subject: [PATCH 2/2] review: unroll {resume,close}_stream hostcalls. Signed-off-by: Piotr Sikora --- src/hostcalls.rs | 63 +++++++++++++++++++++++++++++++++++++++++++----- src/traits.rs | 20 ++++++++++----- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/hostcalls.rs b/src/hostcalls.rs index e9230558..7c8d4da6 100644 --- a/src/hostcalls.rs +++ b/src/hostcalls.rs @@ -615,11 +615,37 @@ extern "C" { fn proxy_continue_stream(stream_type: StreamType) -> Status; } -pub fn resume_stream(stream_type: StreamType) -> Result<(), Status> { +pub fn resume_downstream() -> Result<(), Status> { unsafe { - match proxy_continue_stream(stream_type) { + match proxy_continue_stream(StreamType::Downstream) { + Status::Ok => Ok(()), + status => panic!("unexpected status: {}", status as u32), + } + } +} + +pub fn resume_upstream() -> Result<(), Status> { + unsafe { + match proxy_continue_stream(StreamType::Upstream) { + Status::Ok => Ok(()), + status => panic!("unexpected status: {}", status as u32), + } + } +} + +pub fn resume_http_request() -> Result<(), Status> { + unsafe { + match proxy_continue_stream(StreamType::HttpRequest) { + Status::Ok => Ok(()), + status => panic!("unexpected status: {}", status as u32), + } + } +} + +pub fn resume_http_response() -> Result<(), Status> { + unsafe { + match proxy_continue_stream(StreamType::HttpResponse) { Status::Ok => Ok(()), - Status::BadArgument => Err(Status::BadArgument), status => panic!("unexpected status: {}", status as u32), } } @@ -629,11 +655,36 @@ extern "C" { fn proxy_close_stream(stream_type: StreamType) -> Status; } -pub fn close_stream(stream_type: StreamType) -> Result<(), Status> { +pub fn close_downstream() -> Result<(), Status> { unsafe { - match proxy_close_stream(stream_type) { + match proxy_close_stream(StreamType::Downstream) { + Status::Ok => Ok(()), + status => panic!("unexpected status: {}", status as u32), + } + } +} +pub fn close_upstream() -> Result<(), Status> { + unsafe { + match proxy_close_stream(StreamType::Upstream) { + Status::Ok => Ok(()), + status => panic!("unexpected status: {}", status as u32), + } + } +} + +pub fn reset_http_request() -> Result<(), Status> { + unsafe { + match proxy_close_stream(StreamType::HttpRequest) { + Status::Ok => Ok(()), + status => panic!("unexpected status: {}", status as u32), + } + } +} + +pub fn reset_http_response() -> Result<(), Status> { + unsafe { + match proxy_close_stream(StreamType::HttpResponse) { Status::Ok => Ok(()), - Status::BadArgument => Err(Status::BadArgument), status => panic!("unexpected status: {}", status as u32), } } diff --git a/src/traits.rs b/src/traits.rs index 74d71d15..819008c0 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -264,11 +264,11 @@ pub trait StreamContext: Context { } fn resume_downstream(&self) { - hostcalls::resume_stream(StreamType::Downstream).unwrap() + hostcalls::resume_downstream().unwrap() } fn close_downstream(&self) { - hostcalls::close_stream(StreamType::Downstream).unwrap() + hostcalls::close_downstream().unwrap() } fn on_downstream_close(&mut self, _peer_type: PeerType) {} @@ -286,11 +286,11 @@ pub trait StreamContext: Context { } fn resume_upstream(&self) { - hostcalls::resume_stream(StreamType::Upstream).unwrap() + hostcalls::resume_upstream().unwrap() } fn close_upstream(&self) { - hostcalls::close_stream(StreamType::Upstream).unwrap() + hostcalls::close_upstream().unwrap() } fn on_upstream_close(&mut self, _peer_type: PeerType) {} @@ -400,7 +400,11 @@ pub trait HttpContext: Context { } fn resume_http_request(&self) { - hostcalls::resume_stream(StreamType::HttpRequest).unwrap() + hostcalls::resume_http_request().unwrap() + } + + fn reset_http_request(&self) { + hostcalls::reset_http_request().unwrap() } fn on_http_response_headers(&mut self, _num_headers: usize, _end_of_stream: bool) -> Action { @@ -504,7 +508,11 @@ pub trait HttpContext: Context { } fn resume_http_response(&self) { - hostcalls::resume_stream(StreamType::HttpResponse).unwrap() + hostcalls::resume_http_response().unwrap() + } + + fn reset_http_response(&self) { + hostcalls::reset_http_response().unwrap() } fn send_http_response(