summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tests/unit/fetch_test.ts14
-rw-r--r--op_crates/fetch/lib.rs15
-rw-r--r--test_util/src/lib.rs13
3 files changed, 40 insertions, 2 deletions
diff --git a/cli/tests/unit/fetch_test.ts b/cli/tests/unit/fetch_test.ts
index 99b7531a3..6a5cff164 100644
--- a/cli/tests/unit/fetch_test.ts
+++ b/cli/tests/unit/fetch_test.ts
@@ -689,6 +689,20 @@ unitTest(
{
perms: { net: true },
},
+ async function fetchWithNonAsciiRedirection(): Promise<void> {
+ const response = await fetch("http://localhost:4545/non_ascii_redirect", {
+ redirect: "manual",
+ });
+ assertEquals(response.status, 301);
+ assertEquals(response.headers.get("location"), "/redirect®");
+ await response.text();
+ },
+);
+
+unitTest(
+ {
+ perms: { net: true },
+ },
async function fetchWithManualRedirection(): Promise<void> {
const response = await fetch("http://localhost:4546/", {
redirect: "manual",
diff --git a/op_crates/fetch/lib.rs b/op_crates/fetch/lib.rs
index 49d951d8f..8a4c1ee16 100644
--- a/op_crates/fetch/lib.rs
+++ b/op_crates/fetch/lib.rs
@@ -156,7 +156,20 @@ where
let status = res.status();
let mut res_headers = Vec::new();
for (key, val) in res.headers().iter() {
- res_headers.push((key.to_string(), val.to_str().unwrap().to_owned()));
+ let key_string = key.to_string();
+
+ if val.as_bytes().is_ascii() {
+ res_headers.push((key_string, val.to_str().unwrap().to_owned()))
+ } else {
+ res_headers.push((
+ key_string,
+ val
+ .as_bytes()
+ .iter()
+ .map(|&c| c as char)
+ .collect::<String>(),
+ ));
+ }
}
let rid = state
diff --git a/test_util/src/lib.rs b/test_util/src/lib.rs
index a45581491..8a47eb139 100644
--- a/test_util/src/lib.rs
+++ b/test_util/src/lib.rs
@@ -290,6 +290,16 @@ pub async fn run_all_servers() {
*res.status_mut() = StatusCode::FOUND;
Box::new(res)
});
+ let non_ascii_redirect =
+ warp::path("non_ascii_redirect").map(|| -> Box<dyn Reply> {
+ let mut res = Response::new(Body::empty());
+ *res.status_mut() = StatusCode::MOVED_PERMANENTLY;
+ res.headers_mut().insert(
+ "location",
+ HeaderValue::from_bytes(b"/redirect\xae").unwrap(),
+ );
+ Box::new(res)
+ });
let etag_script = warp::path!("etag_script.ts")
.and(warp::header::optional::<String>("if-none-match"))
@@ -444,7 +454,8 @@ pub async fn run_all_servers() {
.or(echo_server)
.or(echo_multipart_file)
.or(multipart_form_data)
- .or(bad_redirect);
+ .or(bad_redirect)
+ .or(non_ascii_redirect);
let http_fut =
warp::serve(content_type_handler.clone()).bind(([127, 0, 0, 1], PORT));