Skip to content

Commit 0542a78

Browse files
committed
review: retain values from more forgiving hosts.
Signed-off-by: Piotr Sikora <[email protected]>
1 parent 9e1c348 commit 0542a78

File tree

6 files changed

+34
-19
lines changed

6 files changed

+34
-19
lines changed

BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ rust_library(
4848
visibility = ["//visibility:public"],
4949
deps = [
5050
":proxy_wasm_build_script",
51+
"//bazel/cargo/remote:bytes",
5152
"//bazel/cargo/remote:hashbrown",
5253
"//bazel/cargo/remote:http",
5354
"//bazel/cargo/remote:log",

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ edition = "2018"
1111
build = "build.rs"
1212

1313
[dependencies]
14+
bytes = { version = "1", optional = true }
1415
hashbrown = "0.15"
1516
http = { version = "1", optional = true }
1617
log = "0.4"
1718

1819
[features]
1920
default = []
20-
header-value = ["dep:http"]
21+
header-value = ["dep:bytes", "dep:http"]
2122

2223
[profile.release]
2324
lto = true

bazel/cargo/Cargo.Bazel.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
7070
name = "proxy-wasm"
7171
version = "0.2.3-dev"
7272
dependencies = [
73+
"bytes",
7374
"hashbrown",
7475
"http",
7576
"log",

bazel/cargo/remote/BUILD.bazel

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ filegroup(
3131
)
3232

3333
# Workspace Member Dependencies
34+
alias(
35+
name = "bytes",
36+
actual = "@crates_vendor__bytes-1.8.0//:bytes",
37+
tags = ["manual"],
38+
)
39+
3440
alias(
3541
name = "hashbrown",
3642
actual = "@crates_vendor__hashbrown-0.15.0//:hashbrown",

bazel/cargo/remote/defs.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ def aliases(
295295
_NORMAL_DEPENDENCIES = {
296296
"": {
297297
_COMMON_CONDITION: {
298+
"bytes": Label("@crates_vendor__bytes-1.8.0//:bytes"),
298299
"hashbrown": Label("@crates_vendor__hashbrown-0.15.0//:hashbrown"),
299300
"http": Label("@crates_vendor__http-1.1.0//:http"),
300301
"log": Label("@crates_vendor__log-0.4.22//:log"),
@@ -495,6 +496,7 @@ def crate_repositories():
495496
)
496497

497498
return [
499+
struct(repo = "crates_vendor__bytes-1.8.0", is_dev_dep = False),
498500
struct(repo = "crates_vendor__hashbrown-0.15.0", is_dev_dep = False),
499501
struct(repo = "crates_vendor__http-1.1.0", is_dev_dep = False),
500502
struct(repo = "crates_vendor__log-0.4.22", is_dev_dep = False),

src/hostcalls.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,9 @@ pub fn get_map(map_type: MapType) -> Result<Vec<(String, HeaderValue)>, Status>
153153
match proxy_get_header_map_pairs(map_type, &mut return_data, &mut return_size) {
154154
Status::Ok => {
155155
if !return_data.is_null() {
156-
let serialized_map = Vec::from_raw_parts(return_data, return_size, return_size);
157-
Ok(utils::deserialize_map(&serialized_map))
156+
let serialized_map =
157+
bytes::Bytes::from(std::slice::from_raw_parts(return_data, return_size));
158+
Ok(utils::deserialize_map(serialized_map))
158159
} else {
159160
Ok(Vec::new())
160161
}
@@ -1174,6 +1175,8 @@ mod utils {
11741175
use crate::types::Bytes;
11751176
#[cfg(feature = "header-value")]
11761177
use crate::types::HeaderValue;
1178+
#[cfg(feature = "header-value")]
1179+
use bytes::Buf;
11771180
use std::convert::TryFrom;
11781181

11791182
pub(super) fn serialize_property_path(path: Vec<&str>) -> Bytes {
@@ -1221,25 +1224,26 @@ mod utils {
12211224
}
12221225

12231226
#[cfg(feature = "header-value")]
1224-
pub(super) fn deserialize_map(bytes: &[u8]) -> Vec<(String, HeaderValue)> {
1225-
let mut map = Vec::new();
1227+
pub(super) fn deserialize_map(mut bytes: bytes::Bytes) -> Vec<(String, HeaderValue)> {
12261228
if bytes.is_empty() {
1227-
return map;
1229+
return Vec::new();
12281230
}
1229-
let size = u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[0..4]).unwrap()) as usize;
1230-
let mut p = 4 + size * 8;
1231-
for n in 0..size {
1232-
let s = 4 + n * 8;
1233-
let size = u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[s..s + 4]).unwrap()) as usize;
1234-
let key = bytes[p..p + size].to_vec();
1235-
p += size + 1;
1236-
let size =
1237-
u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[s + 4..s + 8]).unwrap()) as usize;
1238-
let value = &bytes[p..p + size];
1239-
p += size + 1;
1231+
let size = bytes.get_u32_le() as usize;
1232+
let mut sizes = bytes.split_to(size * 8);
1233+
let mut map = Vec::with_capacity(size);
1234+
for _ in 0..size {
1235+
let size = sizes.get_u32_le() as usize;
1236+
let key = bytes.split_to(size);
1237+
bytes.advance(1);
1238+
let size = sizes.get_u32_le() as usize;
1239+
let value = bytes.split_to(size);
1240+
bytes.advance(1);
12401241
map.push((
1241-
String::from_utf8(key).unwrap(),
1242-
HeaderValue::from_bytes(value).unwrap(),
1242+
String::from_utf8(key.to_vec()).unwrap(),
1243+
// We're intentionally using the unchecked variant in order to retain
1244+
// values accepted by the hosts and proxies that don't enforce strict
1245+
// RFC compliance on HTTP field values.
1246+
unsafe { HeaderValue::from_maybe_shared_unchecked(value) },
12431247
));
12441248
}
12451249
map

0 commit comments

Comments
 (0)