fix(relay): multiple Set-Cookie headers in resp (#5394)

Co-authored-by: jamesgeorge007 <25279263+jamesgeorge007@users.noreply.github.com>
This commit is contained in:
Shreyas 2025-09-23 17:14:29 +05:30 committed by GitHub
parent 81fe98f25d
commit 3be91a4a51
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 76 additions and 15 deletions

View file

@ -4110,7 +4110,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "relay"
version = "0.1.1"
source = "git+https://github.com/CuriousCorrelation/relay.git#10aca0e5d74515a6fed231ee9d7220a014f8b184"
source = "git+https://github.com/CuriousCorrelation/relay.git#7270b956321972269eea7cecdccbb2ae839bd0ff"
dependencies = [
"bytes",
"curl",

View file

@ -21,6 +21,54 @@ const extractTiming = (response: RelayResponse): number =>
const extractSize = (response: RelayResponse): number =>
response.meta?.size?.total ?? 0
/**
* Response headers processor to handle multiple `\n` split Set-Cookie
* headers.
*
*
* TODO: This is a special case handler, a temporary workaround.
* Temporary workaround often get calcified as permanent but a complete
* solution, but the other more better option is rather involved,
* like swapping `Record`/`HashMap` with a flat array and propagating
* the refactor throughout the codebase, from the underlying networking
* to the FE.
*
* The problem with that approach is you lose that O(1) lookup. There's
* also little point in going from key-value to key-pair-value since
* you'd just be putting this same workaround somewhere else.
* A simpler approach is `HashMap<String, Vec<String>>` but even that
* doesn't substantially reduces the refactor surface area.
* Given all of those issues, a temporary workaround is perhaps the best
* solution at the moment.
*
* Headers should always be present from the `RelayResponse`, this defends
* against potential serde/boundary issues between typed conversions.
*/
const processHeaders = (
headers?: Record<string, string> | null
): HoppRESTResponseHeader[] => {
const processedHeaders: HoppRESTResponseHeader[] = []
// `headers` should theoretically exist, always
for (const [key, value] of Object.entries(headers ?? {})) {
if (key.toLowerCase() === "set-cookie") {
// To split concatenated `Set-Cookie` headers and create separate header entries,
// see `if key.to_lowercase() == "set-cookie" {` in `transfer.rs`
const cookieStrings = value
.split("\n")
.map((s) => s.trim())
.filter(Boolean)
for (const cookieString of cookieStrings) {
processedHeaders.push({ key: "Set-Cookie", value: cookieString })
}
} else {
processedHeaders.push({ key, value })
}
}
return processedHeaders
}
export const RESTResponse = {
async toResponse(
response: RelayResponse,
@ -38,9 +86,7 @@ export const RESTResponse = {
return {
type: "success",
headers: Object.entries(response.headers ?? {}).map(
([key, value]) => ({ key, value }) as HoppRESTResponseHeader
),
headers: processHeaders(response.headers),
body: response.body.body.buffer,
statusCode: response.status,
statusText: response.statusText ?? "",

View file

@ -53,7 +53,22 @@ impl TransferHandler {
let key = key.trim().to_string();
let value = value[1..].trim().to_string();
headers.entry(key).or_insert(value);
if key.to_lowercase() == "set-cookie" {
// NOTE: Special handling workaround.
// Concatenate multiple `Set-Cookie` headers.
match headers.entry(key) {
std::collections::hash_map::Entry::Occupied(mut e) => {
let existing = e.get_mut();
existing.push_str("\n");
existing.push_str(&value);
}
std::collections::hash_map::Entry::Vacant(e) => {
e.insert(value);
}
}
} else {
headers.entry(key).or_insert(value);
}
}
}
true

View file

@ -2888,7 +2888,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "relay"
version = "0.1.1"
source = "git+https://github.com/CuriousCorrelation/relay.git#10aca0e5d74515a6fed231ee9d7220a014f8b184"
source = "git+https://github.com/CuriousCorrelation/relay.git#7270b956321972269eea7cecdccbb2ae839bd0ff"
dependencies = [
"bytes",
"curl",

View file

@ -4413,7 +4413,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "relay"
version = "0.1.1"
source = "git+https://github.com/CuriousCorrelation/relay.git#10aca0e5d74515a6fed231ee9d7220a014f8b184"
source = "git+https://github.com/CuriousCorrelation/relay.git#7270b956321972269eea7cecdccbb2ae839bd0ff"
dependencies = [
"bytes",
"curl",
@ -5603,7 +5603,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-relay"
version = "0.1.0"
source = "git+https://github.com/CuriousCorrelation/tauri-plugin-relay?rev=ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158#ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158"
source = "git+https://github.com/CuriousCorrelation/tauri-plugin-relay?rev=5d59b97fe331ca62e8be0454ff3f4e5f6185ae70#5d59b97fe331ca62e8be0454ff3f4e5f6185ae70"
dependencies = [
"relay",
"serde",

View file

@ -30,7 +30,7 @@ tauri-plugin-dialog = "2.2.0"
tauri-plugin-fs = "2.2.0"
tauri-plugin-deep-link = "2.2.0"
tauri-plugin-appload = { git = "https://github.com/CuriousCorrelation/tauri-plugin-appload", rev = "e05861959938b57479a1a81fa796735ebbd08c7c" }
tauri-plugin-relay = { git = "https://github.com/CuriousCorrelation/tauri-plugin-relay", rev = "ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158" }
tauri-plugin-relay = { git = "https://github.com/CuriousCorrelation/tauri-plugin-relay", rev = "5d59b97fe331ca62e8be0454ff3f4e5f6185ae70" }
axum = "0.8.1"
tower-http = { version = "0.6.2", features = ["cors"] }
random-port = "0.1.1"

View file

@ -57,6 +57,6 @@
"@tauri-apps/plugin-dialog": "2.0.1",
"@tauri-apps/plugin-fs": "2.0.2",
"@tauri-apps/plugin-store": "2.2.0",
"@hoppscotch/plugin-relay": "github:CuriousCorrelation/tauri-plugin-relay#ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158"
"@hoppscotch/plugin-relay": "github:CuriousCorrelation/tauri-plugin-relay#5d59b97fe331ca62e8be0454ff3f4e5f6185ae70"
}
}

View file

@ -1217,8 +1217,8 @@ importers:
packages/hoppscotch-kernel:
dependencies:
'@hoppscotch/plugin-relay':
specifier: github:CuriousCorrelation/tauri-plugin-relay#ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158
version: '@CuriousCorrelation/plugin-relay@https://codeload.github.com/CuriousCorrelation/tauri-plugin-relay/tar.gz/ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158'
specifier: github:CuriousCorrelation/tauri-plugin-relay#5d59b97fe331ca62e8be0454ff3f4e5f6185ae70
version: '@CuriousCorrelation/plugin-relay@https://codeload.github.com/CuriousCorrelation/tauri-plugin-relay/tar.gz/5d59b97fe331ca62e8be0454ff3f4e5f6185ae70'
'@tauri-apps/api':
specifier: 2.1.1
version: 2.1.1
@ -1853,8 +1853,8 @@ packages:
resolution: {tarball: https://codeload.github.com/CuriousCorrelation/tauri-plugin-appload/tar.gz/e05861959938b57479a1a81fa796735ebbd08c7c}
version: 0.1.0
'@CuriousCorrelation/plugin-relay@https://codeload.github.com/CuriousCorrelation/tauri-plugin-relay/tar.gz/ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158':
resolution: {tarball: https://codeload.github.com/CuriousCorrelation/tauri-plugin-relay/tar.gz/ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158}
'@CuriousCorrelation/plugin-relay@https://codeload.github.com/CuriousCorrelation/tauri-plugin-relay/tar.gz/5d59b97fe331ca62e8be0454ff3f4e5f6185ae70':
resolution: {tarball: https://codeload.github.com/CuriousCorrelation/tauri-plugin-relay/tar.gz/5d59b97fe331ca62e8be0454ff3f4e5f6185ae70}
version: 0.1.0
'@alloc/quick-lru@5.2.0':
@ -15538,7 +15538,7 @@ snapshots:
dependencies:
'@tauri-apps/api': 2.1.1
'@CuriousCorrelation/plugin-relay@https://codeload.github.com/CuriousCorrelation/tauri-plugin-relay/tar.gz/ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158':
'@CuriousCorrelation/plugin-relay@https://codeload.github.com/CuriousCorrelation/tauri-plugin-relay/tar.gz/5d59b97fe331ca62e8be0454ff3f4e5f6185ae70':
dependencies:
'@tauri-apps/api': 2.1.1