DioxusLabs / DioxusLabs/dioxus
add_response_header will override existing Set-Cookie headers
- Dominant language
- Rust
- Stars
- 39.1k
- Forks
- 1.9k
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 4
Description
**Problem**
In fullstack-core/src/streaming.rs, the add_response_header mehod uses insert method to add headers to the response. However, insert method replaces any existing header with the same name, which breaks multi-valued headers like Set-Cookie.
https://github.com/DioxusLabs/dioxus/blob/4b1b60a487b682f62305342c29ece0553d0da8d8/packages/fullstack-core/src/streaming.rs#L196-L205
**Steps To Reproduce**
Steps to reproduce the behavior:
- In a fullstack Dioxus app, call at server function
```rust
ctx.add_response_header(
http::header::SET_COOKIE,
http::HeaderValue::from_str(
"name=example_1",
)
.unwrap(),
);
ctx.add_response_header(
http::header::SET_COOKIE,
http::HeaderValue::from_str(
"name=example_2",
)
.unwrap(),
);
```
- Only last set Set-Cookie header ("name=example_2") appears in the response.
**Expected behavior**
At least regarding the Set-Cookie response header, I believe it's preferable to be able to set and return multiple values.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie
https://datatracker.ietf.org/doc/html/rfc6265#section-3
**Screenshots**
N/A
**Environment:**
- Dioxus version: v0.7.9
- Rust version:
- OS info: Windows 11
- App platform: fullstack web
**Questionnaire**
I would like to fix and I have a solution.
In the add_response_header method, I think modify it to treat Set-Cookie headers as a special case by replacing the insert method with the append method when the argument contains a Set-Cookie header.
```rust
/// Add a header to the response. This will be sent to the client when the response is committed.
/// Set-Cookie headers will be appended to any existing Set-Cookie headers (compliance with RFC 6265),
/// while all other headers will overwrite any existing header with the same name.
pub fn add_response_header(
&self,
key: impl Into,
value: impl Into,
) {
let mut lock = self.lock.write();
if let Some(headers) = lock.response_headers.as_mut() {
let key_into = key.into();
if key_into == http::header::SET_COOKIE {
headers.append(key_into, value.into());
} else {
headers.insert(key_into, value.into());
}
}
}
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.