From 1c885e46b38fc4ac91e0ea3e9f8cd965d1eb1a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Krasnoborski?= Date: Thu, 16 Sep 2021 15:44:13 +0200 Subject: [PATCH 1/2] Avoid taking Vec as argument in hostcalls::utils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't need ownership, so slice should be enough. Note: Public-facing functions still do take Vecs as arguments, to avoid breaking changes. They could also be changed to take slices in the future. Signed-off-by: Michał Krasnoborski --- src/hostcalls.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/hostcalls.rs b/src/hostcalls.rs index 7c8d4da6..837a0982 100644 --- a/src/hostcalls.rs +++ b/src/hostcalls.rs @@ -190,7 +190,7 @@ extern "C" { } pub fn set_map(map_type: MapType, map: Vec<(&str, &str)>) -> Result<(), Status> { - let serialized_map = utils::serialize_map(map); + 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(()), @@ -200,7 +200,7 @@ 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); + 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(()), @@ -394,7 +394,7 @@ extern "C" { } pub fn get_property(path: Vec<&str>) -> Result, Status> { - let serialized_path = utils::serialize_property_path(path); + let serialized_path = utils::serialize_property_path(&path); let mut return_data: *mut u8 = null_mut(); let mut return_size: usize = 0; unsafe { @@ -431,7 +431,7 @@ extern "C" { } pub fn set_property(path: Vec<&str>, value: Option<&[u8]>) -> Result<(), Status> { - let serialized_path = utils::serialize_property_path(path); + let serialized_path = utils::serialize_property_path(&path); unsafe { match proxy_set_property( serialized_path.as_ptr(), @@ -708,7 +708,7 @@ pub fn send_http_response( headers: Vec<(&str, &str)>, body: Option<&[u8]>, ) -> Result<(), Status> { - let serialized_headers = utils::serialize_map(headers); + let serialized_headers = utils::serialize_map(&headers); unsafe { match proxy_send_local_response( status_code, @@ -748,8 +748,8 @@ pub fn dispatch_http_call( trailers: Vec<(&str, &str)>, timeout: Duration, ) -> Result { - let serialized_headers = utils::serialize_map(headers); - let serialized_trailers = utils::serialize_map(trailers); + let serialized_headers = utils::serialize_map(&headers); + let serialized_trailers = utils::serialize_map(&trailers); let mut return_token: u32 = 0; unsafe { match proxy_http_call( @@ -801,7 +801,7 @@ pub fn dispatch_grpc_call( timeout: Duration, ) -> Result { let mut return_callout_id = 0; - let serialized_initial_metadata = utils::serialize_map_bytes(initial_metadata); + let serialized_initial_metadata = utils::serialize_map_bytes(&initial_metadata); unsafe { match proxy_grpc_call( upstream_name.as_ptr(), @@ -849,7 +849,7 @@ pub fn open_grpc_stream( initial_metadata: Vec<(&str, &[u8])>, ) -> Result { let mut return_stream_id = 0; - let serialized_initial_metadata = utils::serialize_map_bytes(initial_metadata); + let serialized_initial_metadata = utils::serialize_map_bytes(&initial_metadata); unsafe { match proxy_grpc_stream( upstream_name.as_ptr(), @@ -1071,16 +1071,16 @@ mod utils { use crate::types::Bytes; use std::convert::TryFrom; - pub(super) fn serialize_property_path(path: Vec<&str>) -> Bytes { + pub(super) fn serialize_property_path(path: &[&str]) -> Bytes { if path.is_empty() { return Vec::new(); } let mut size: usize = 0; - for part in &path { + for part in path { size += part.len() + 1; } let mut bytes: Bytes = Vec::with_capacity(size); - for part in &path { + for part in path { bytes.extend_from_slice(part.as_bytes()); bytes.push(0); } @@ -1088,18 +1088,18 @@ mod utils { bytes } - pub(super) fn serialize_map(map: Vec<(&str, &str)>) -> Bytes { + pub(super) fn serialize_map(map: &[(&str, &str)]) -> Bytes { let mut size: usize = 4; - for (name, value) in &map { + for (name, value) in map { size += name.len() + value.len() + 10; } let mut bytes: Bytes = Vec::with_capacity(size); bytes.extend_from_slice(&map.len().to_le_bytes()); - for (name, value) in &map { + for (name, value) in map { bytes.extend_from_slice(&name.len().to_le_bytes()); bytes.extend_from_slice(&value.len().to_le_bytes()); } - for (name, value) in &map { + for (name, value) in map { bytes.extend_from_slice(name.as_bytes()); bytes.push(0); bytes.extend_from_slice(value.as_bytes()); @@ -1108,18 +1108,18 @@ mod utils { bytes } - pub(super) fn serialize_map_bytes(map: Vec<(&str, &[u8])>) -> Bytes { + pub(super) fn serialize_map_bytes(map: &[(&str, &[u8])]) -> Bytes { let mut size: usize = 4; - for (name, value) in &map { + for (name, value) in map { size += name.len() + value.len() + 10; } let mut bytes: Bytes = Vec::with_capacity(size); bytes.extend_from_slice(&map.len().to_le_bytes()); - for (name, value) in &map { + for (name, value) in map { bytes.extend_from_slice(&name.len().to_le_bytes()); bytes.extend_from_slice(&value.len().to_le_bytes()); } - for (name, value) in &map { + for (name, value) in map { bytes.extend_from_slice(name.as_bytes()); bytes.push(0); bytes.extend_from_slice(value); From 3c2099329ee01e3e7199519f86b77e5d27327e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Krasnoborski?= Date: Thu, 16 Sep 2021 15:53:44 +0200 Subject: [PATCH 2/2] Make map serialization/deserialization utils public MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These functions are helpful as "serialized map" format is used in some other places, eg. in envoy `get_property(["metadata", "filter_metadata", "xxx"])` may return a map in such a format. Signed-off-by: Michał Krasnoborski --- src/hostcalls.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hostcalls.rs b/src/hostcalls.rs index 837a0982..5a4cdcd9 100644 --- a/src/hostcalls.rs +++ b/src/hostcalls.rs @@ -1067,7 +1067,7 @@ pub fn increment_metric(metric_id: u32, offset: i64) -> Result<(), Status> { } } -mod utils { +pub mod utils { use crate::types::Bytes; use std::convert::TryFrom; @@ -1088,7 +1088,7 @@ mod utils { bytes } - pub(super) fn serialize_map(map: &[(&str, &str)]) -> Bytes { + pub fn serialize_map(map: &[(&str, &str)]) -> Bytes { let mut size: usize = 4; for (name, value) in map { size += name.len() + value.len() + 10; @@ -1108,7 +1108,7 @@ mod utils { bytes } - pub(super) fn serialize_map_bytes(map: &[(&str, &[u8])]) -> Bytes { + pub fn serialize_map_bytes(map: &[(&str, &[u8])]) -> Bytes { let mut size: usize = 4; for (name, value) in map { size += name.len() + value.len() + 10; @@ -1128,7 +1128,7 @@ mod utils { bytes } - pub(super) fn deserialize_map(bytes: &[u8]) -> Vec<(String, String)> { + pub fn deserialize_map(bytes: &[u8]) -> Vec<(String, String)> { let mut map = Vec::new(); if bytes.is_empty() { return map; @@ -1152,7 +1152,7 @@ mod utils { map } - pub(super) fn deserialize_map_bytes(bytes: &[u8]) -> Vec<(String, Bytes)> { + pub fn deserialize_map_bytes(bytes: &[u8]) -> Vec<(String, Bytes)> { let mut map = Vec::new(); if bytes.is_empty() { return map;