From 5a55cebfb34fe4c5e9d3fca184597dcc17424d2b Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Fri, 25 Jun 2021 04:10:51 -0700 Subject: [PATCH] Add hostcalls for maps that use bytes instead of UTF-8 strings. Partially addresses #25. Signed-off-by: Piotr Sikora --- src/hostcalls.rs | 61 ++++++++++++++++++++++++++--- src/traits.rs | 100 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 154 insertions(+), 7 deletions(-) diff --git a/src/hostcalls.rs b/src/hostcalls.rs index 3df832c4..ff4eed0a 100644 --- a/src/hostcalls.rs +++ b/src/hostcalls.rs @@ -185,7 +185,7 @@ pub fn get_map_bytes(map_type: MapType) -> Result, Status> Status::Ok => { if !return_data.is_null() { let serialized_map = Vec::from_raw_parts(return_data, return_size, return_size); - Ok(utils::deserialize_bytes_map(&serialized_map)) + Ok(utils::deserialize_map_bytes(&serialized_map)) } else { Ok(Vec::new()) } @@ -213,6 +213,16 @@ pub fn set_map(map_type: MapType, map: Vec<(&str, &str)>) -> Result<(), Status> } } +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, @@ -320,6 +330,32 @@ pub fn set_map_value(map_type: MapType, key: &str, value: Option<&str>) -> Resul } } +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, @@ -345,6 +381,21 @@ pub fn add_map_value(map_type: MapType, key: &str, value: &str) -> Result<(), St } } +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, @@ -722,7 +773,7 @@ pub fn dispatch_grpc_call( timeout: Duration, ) -> Result { let mut return_callout_id = 0; - let serialized_initial_metadata = utils::serialize_bytes_map(initial_metadata); + let serialized_initial_metadata = utils::serialize_map_bytes(initial_metadata); unsafe { match proxy_grpc_call( upstream_name.as_ptr(), @@ -770,7 +821,7 @@ pub fn open_grpc_stream( initial_metadata: Vec<(&str, &[u8])>, ) -> Result { let mut return_stream_id = 0; - let serialized_initial_metadata = utils::serialize_bytes_map(initial_metadata); + let serialized_initial_metadata = utils::serialize_map_bytes(initial_metadata); unsafe { match proxy_grpc_stream( upstream_name.as_ptr(), @@ -1029,7 +1080,7 @@ mod utils { bytes } - pub(super) fn serialize_bytes_map(map: Vec<(&str, &[u8])>) -> Bytes { + pub(super) fn serialize_map_bytes(map: Vec<(&str, &[u8])>) -> Bytes { let mut size: usize = 4; for (name, value) in &map { size += name.len() + value.len() + 10; @@ -1073,7 +1124,7 @@ mod utils { map } - pub(super) fn deserialize_bytes_map(bytes: &[u8]) -> Vec<(String, Bytes)> { + pub(super) fn deserialize_map_bytes(bytes: &[u8]) -> Vec<(String, Bytes)> { let mut map = Vec::new(); if bytes.is_empty() { return map; diff --git a/src/traits.rs b/src/traits.rs index 4553a0aa..33ba7a80 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -82,10 +82,18 @@ pub trait Context { hostcalls::get_map(MapType::HttpCallResponseHeaders).unwrap() } + fn get_http_call_response_headers_bytes(&self) -> Vec<(String, Bytes)> { + hostcalls::get_map_bytes(MapType::HttpCallResponseHeaders).unwrap() + } + fn get_http_call_response_header(&self, name: &str) -> Option { hostcalls::get_map_value(MapType::HttpCallResponseHeaders, &name).unwrap() } + fn get_http_call_response_header_bytes(&self, name: &str) -> Option { + hostcalls::get_map_value_bytes(MapType::HttpCallResponseHeaders, name).unwrap() + } + fn get_http_call_response_body(&self, start: usize, max_size: usize) -> Option { hostcalls::get_buffer(BufferType::HttpCallResponseBody, start, max_size).unwrap() } @@ -94,10 +102,18 @@ pub trait Context { hostcalls::get_map(MapType::HttpCallResponseTrailers).unwrap() } + fn get_http_call_response_trailers_bytes(&self) -> Vec<(String, Bytes)> { + hostcalls::get_map_bytes(MapType::HttpCallResponseTrailers).unwrap() + } + fn get_http_call_response_trailer(&self, name: &str) -> Option { hostcalls::get_map_value(MapType::HttpCallResponseTrailers, &name).unwrap() } + fn get_http_call_response_trailer_bytes(&self, name: &str) -> Option { + hostcalls::get_map_value_bytes(MapType::HttpCallResponseTrailers, name).unwrap() + } + fn dispatch_grpc_call( &self, upstream_name: &str, @@ -271,22 +287,42 @@ pub trait HttpContext: Context { hostcalls::get_map(MapType::HttpRequestHeaders).unwrap() } + fn get_http_request_headers_bytes(&self) -> Vec<(String, Bytes)> { + hostcalls::get_map_bytes(MapType::HttpRequestHeaders).unwrap() + } + fn set_http_request_headers(&self, headers: Vec<(&str, &str)>) { hostcalls::set_map(MapType::HttpRequestHeaders, headers).unwrap() } + fn set_http_request_headers_bytes(&self, headers: Vec<(&str, &[u8])>) { + hostcalls::set_map_bytes(MapType::HttpRequestHeaders, headers).unwrap() + } + fn get_http_request_header(&self, name: &str) -> Option { hostcalls::get_map_value(MapType::HttpRequestHeaders, &name).unwrap() } + fn get_http_request_header_bytes(&self, name: &str) -> Option { + hostcalls::get_map_value_bytes(MapType::HttpRequestHeaders, name).unwrap() + } + fn set_http_request_header(&self, name: &str, value: Option<&str>) { hostcalls::set_map_value(MapType::HttpRequestHeaders, &name, value).unwrap() } + fn set_http_request_header_bytes(&self, name: &str, value: Option<&[u8]>) { + hostcalls::set_map_value_bytes(MapType::HttpRequestHeaders, name, value).unwrap() + } + fn add_http_request_header(&self, name: &str, value: &str) { hostcalls::add_map_value(MapType::HttpRequestHeaders, &name, value).unwrap() } + fn add_http_request_header_bytes(&self, name: &str, value: &[u8]) { + hostcalls::add_map_value_bytes(MapType::HttpRequestHeaders, name, value).unwrap() + } + fn on_http_request_body(&mut self, _body_size: usize, _end_of_stream: bool) -> Action { Action::Continue } @@ -307,22 +343,42 @@ pub trait HttpContext: Context { hostcalls::get_map(MapType::HttpRequestTrailers).unwrap() } + fn get_http_request_trailers_bytes(&self) -> Vec<(String, Bytes)> { + hostcalls::get_map_bytes(MapType::HttpRequestTrailers).unwrap() + } + fn set_http_request_trailers(&self, trailers: Vec<(&str, &str)>) { hostcalls::set_map(MapType::HttpRequestTrailers, trailers).unwrap() } + fn set_http_request_trailers_bytes(&self, trailers: Vec<(&str, &[u8])>) { + hostcalls::set_map_bytes(MapType::HttpRequestTrailers, trailers).unwrap() + } + fn get_http_request_trailer(&self, name: &str) -> Option { hostcalls::get_map_value(MapType::HttpRequestTrailers, &name).unwrap() } + fn get_http_request_trailer_bytes(&self, name: &str) -> Option { + hostcalls::get_map_value_bytes(MapType::HttpRequestTrailers, name).unwrap() + } + fn set_http_request_trailer(&self, name: &str, value: Option<&str>) { hostcalls::set_map_value(MapType::HttpRequestTrailers, &name, value).unwrap() } + fn set_http_request_trailer_bytes(&self, name: &str, value: Option<&[u8]>) { + hostcalls::set_map_value_bytes(MapType::HttpRequestTrailers, name, value).unwrap() + } + fn add_http_request_trailer(&self, name: &str, value: &str) { hostcalls::add_map_value(MapType::HttpRequestTrailers, &name, value).unwrap() } + fn add_http_request_trailer_bytes(&self, name: &str, value: &[u8]) { + hostcalls::add_map_value_bytes(MapType::HttpRequestTrailers, name, value).unwrap() + } + fn resume_http_request(&self) { hostcalls::resume_http_request().unwrap() } @@ -335,22 +391,42 @@ pub trait HttpContext: Context { hostcalls::get_map(MapType::HttpResponseHeaders).unwrap() } + fn get_http_response_headers_bytes(&self) -> Vec<(String, Bytes)> { + hostcalls::get_map_bytes(MapType::HttpResponseHeaders).unwrap() + } + fn set_http_response_headers(&self, headers: Vec<(&str, &str)>) { hostcalls::set_map(MapType::HttpResponseHeaders, headers).unwrap() } + fn set_http_response_headers_bytes(&self, headers: Vec<(&str, &[u8])>) { + hostcalls::set_map_bytes(MapType::HttpResponseHeaders, headers).unwrap() + } + fn get_http_response_header(&self, name: &str) -> Option { hostcalls::get_map_value(MapType::HttpResponseHeaders, &name).unwrap() } + fn get_http_response_header_bytes(&self, name: &str) -> Option { + hostcalls::get_map_value_bytes(MapType::HttpResponseHeaders, name).unwrap() + } + fn set_http_response_header(&self, name: &str, value: Option<&str>) { hostcalls::set_map_value(MapType::HttpResponseHeaders, &name, value).unwrap() } + fn set_http_response_header_bytes(&self, name: &str, value: Option<&[u8]>) { + hostcalls::set_map_value_bytes(MapType::HttpResponseHeaders, name, value).unwrap() + } + fn add_http_response_header(&self, name: &str, value: &str) { hostcalls::add_map_value(MapType::HttpResponseHeaders, &name, value).unwrap() } + fn add_http_response_header_bytes(&self, name: &str, value: &[u8]) { + hostcalls::add_map_value_bytes(MapType::HttpResponseHeaders, name, value).unwrap() + } + fn on_http_response_body(&mut self, _body_size: usize, _end_of_stream: bool) -> Action { Action::Continue } @@ -371,22 +447,42 @@ pub trait HttpContext: Context { hostcalls::get_map(MapType::HttpResponseTrailers).unwrap() } - fn set_http_response_trailers(&self, headers: Vec<(&str, &str)>) { - hostcalls::set_map(MapType::HttpResponseTrailers, headers).unwrap() + fn get_http_response_trailers_bytes(&self) -> Vec<(String, Bytes)> { + hostcalls::get_map_bytes(MapType::HttpResponseTrailers).unwrap() + } + + fn set_http_response_trailers(&self, trailers: Vec<(&str, &str)>) { + hostcalls::set_map(MapType::HttpResponseTrailers, trailers).unwrap() + } + + fn set_http_response_trailers_bytes(&self, trailers: Vec<(&str, &[u8])>) { + hostcalls::set_map_bytes(MapType::HttpResponseTrailers, trailers).unwrap() } fn get_http_response_trailer(&self, name: &str) -> Option { hostcalls::get_map_value(MapType::HttpResponseTrailers, &name).unwrap() } + fn get_http_response_trailer_bytes(&self, name: &str) -> Option { + hostcalls::get_map_value_bytes(MapType::HttpResponseTrailers, name).unwrap() + } + fn set_http_response_trailer(&self, name: &str, value: Option<&str>) { hostcalls::set_map_value(MapType::HttpResponseTrailers, &name, value).unwrap() } + fn set_http_response_trailer_bytes(&self, name: &str, value: Option<&[u8]>) { + hostcalls::set_map_value_bytes(MapType::HttpResponseTrailers, name, value).unwrap() + } + fn add_http_response_trailer(&self, name: &str, value: &str) { hostcalls::add_map_value(MapType::HttpResponseTrailers, &name, value).unwrap() } + fn add_http_response_trailer_bytes(&self, name: &str, value: &[u8]) { + hostcalls::add_map_value_bytes(MapType::HttpResponseTrailers, name, value).unwrap() + } + fn resume_http_response(&self) { hostcalls::resume_http_response().unwrap() }