From fcccb00b8fd7d4835b1df4894120f1013a8d9a5f Mon Sep 17 00:00:00 2001 From: Gary Pennington Date: Tue, 6 Dec 2022 10:57:39 +0000 Subject: [PATCH 1/2] add support for appending to header map from rhai This adds support for setting a header map key with an array. This causes the HeaderMap key/values to be appended() to the map, rather than inserted(). Useful when setting cookies with multiple "set-cookie" for example. --- apollo-router/src/plugins/rhai.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apollo-router/src/plugins/rhai.rs b/apollo-router/src/plugins/rhai.rs index 28c9e39e71..2a92d89a96 100644 --- a/apollo-router/src/plugins/rhai.rs +++ b/apollo-router/src/plugins/rhai.rs @@ -1196,6 +1196,18 @@ impl Rhai { ); Ok(()) }) + // Register an additional setter which allows us to set multiple values for the same + // key + .register_indexer_set(|x: &mut HeaderMap, key: &str, value: rhai::Array| { + let h_key = HeaderName::from_str(key).map_err(|e| e.to_string())?; + for v in value { + x.append( + h_key.clone(), + HeaderValue::from_str(&v.into_string()?).map_err(|e| e.to_string())?, + ); + } + Ok(()) + }) // Register a Context indexer so we can get/set context .register_indexer_get( |x: &mut Context, key: &str| -> Result> { From 48626e3ff30081042297f78317b23ea7fe1dad01 Mon Sep 17 00:00:00 2001 From: Gary Pennington Date: Tue, 6 Dec 2022 11:37:05 +0000 Subject: [PATCH 2/2] add changelog and documentation --- NEXT_CHANGELOG.md | 23 +++++++++++++++++++++++ docs/source/customizations/rhai-api.mdx | 6 ++++++ 2 files changed, 29 insertions(+) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 0ed480a744..3e2dddb471 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -25,3 +25,26 @@ By [@USERNAME](https://github.com/USERNAME) in https://github.com/apollographql/ --> # [x.x.x] (unreleased) - 2022-mm-dd + +## ❗ BREAKING ❗ +## 🚀 Features + +### Add support for setting multi-value header keys to rhai ([Issue #2211](https://github.com/apollographql/router/issues/2211)) + +Adds support for setting a header map key with an array. This causes the HeaderMap key/values to be appended() to the map, rather than inserted(). + +Example use from rhai as: + +``` + response.headers["set-cookie"] = [ + "foo=bar; Domain=localhost; Path=/; Expires=Wed, 04 Jan 2023 17:25:27 GMT; HttpOnly; Secure; SameSite=None", + "foo2=bar2; Domain=localhost; Path=/; Expires=Wed, 04 Jan 2023 17:25:27 GMT; HttpOnly; Secure; SameSite=None", + ]; +``` + +By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/2219 + +## 🐛 Fixes +## 🛠 Maintenance +## 📚 Documentation +## 🥼 Experimental diff --git a/docs/source/customizations/rhai-api.mdx b/docs/source/customizations/rhai-api.mdx index 201a616262..57f06f3d6e 100644 --- a/docs/source/customizations/rhai-api.mdx +++ b/docs/source/customizations/rhai-api.mdx @@ -248,6 +248,12 @@ The headers of a request are accessible as a read/write indexed variable. The ke // You can interact with request.headers as an indexed variable request.headers["x-my-new-header"] = 42.to_string(); // Inserts a new header "x-my-new-header" with value "42" print(`${request.headers["x-my-new-header"]}`); // Writes "42" into the router log at info level +// You can also set an header value from an array. Useful with the "set-cookie" header, +// Note: It's probably more useful to do this on response headers. Simply illustrating the syntax here. +request.headers["set-cookie"] = [ + "foo=bar; Domain=localhost; Path=/; Expires=Wed, 04 Jan 2023 17:25:27 GMT; HttpOnly; Secure; SameSite=None", + "foo2=bar2; Domain=localhost; Path=/; Expires=Wed, 04 Jan 2023 17:25:27 GMT; HttpOnly; Secure; SameSite=None", +]; // Rhai also supports extended dot notation for indexed variables, so this is equivalent request.headers.x-my-new-header = 42.to_string(); ```