Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't send the Set-Cookie header multiple times for the same cookie #237

Merged
merged 30 commits into from
Aug 1, 2023

Conversation

gurgunday
Copy link
Member

@gurgunday gurgunday commented Jul 22, 2023

Hey everyone!

This PR closes #218 by decorating the reply with a Map to check if a cookie was already set during the lifecycle of a request. If that's the case, instead of multiplying the header, we now just update it.

Please let me know if there is an even better/more performant way to achieve the same outcome.

Finally, I got inspired (as usual) by @Uzlopak's suggestion.

Checklist

@gurgunday gurgunday marked this pull request as draft July 23, 2023 06:23
test/cookie.test.js Outdated Show resolved Hide resolved
test/cookie.test.js Outdated Show resolved Hide resolved
plugin.js Outdated Show resolved Hide resolved
@Uzlopak
Copy link
Contributor

Uzlopak commented Jul 25, 2023

I think we should discuss how we handle overwriting cookies. I think it is error prone to merge the attributes.

@gurgunday
Copy link
Member Author

I think we should discuss how we handle overwriting cookies. I think it is error prone to merge the attributes.

Agreed, maybe a shallow comparison of the opts, or just domain and path

@gurgunday
Copy link
Member Author

What do you think of this?

@gurgunday gurgunday marked this pull request as ready for review July 25, 2023 15:54
@Uzlopak
Copy link
Contributor

Uzlopak commented Jul 25, 2023

Dont expect much from me. I am on vacation with my wife on crete and have limited access to my laptop. :))

Most stuff i currently do is with my phone. I will see if i can review it with my laptop.

@gurgunday
Copy link
Member Author

Dont expect much from me. I am on vacation with my wife on crete and have limited access to my laptop. :))

Most stuff i currently do is with my phone. I will see if i can review it with my laptop.

It’s all good, have a great vacation 🏖️

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

I think this is worthwhile for a semver-major. Wdyt?

plugin.js Outdated Show resolved Hide resolved
plugin.js Outdated Show resolved Hide resolved
plugin.js Outdated Show resolved Hide resolved
plugin.js Outdated Show resolved Hide resolved
@Uzlopak
Copy link
Contributor

Uzlopak commented Jul 26, 2023

I agree with @mcollina
The unit test "share options for setCookie and clearCookie" got changed, indicating that it is a semver major.

@gurgunday
Copy link
Member Author

lgtm
I think this is worthwhile for a semver-major. Wdyt?

I agree, this is a behavior change at the API level as well.

@mcollina
Copy link
Member

Can we avoid a change of the API? This module has quite a few dependencies and I fear it would be harder to update them all.

@gurgunday
Copy link
Member Author

By API behavior change I meant this very specific scenario: user registers cookie, uses the decorators provided by cookie to set a cookie, then sets the Set-Cookie header manually with header('Set-Cookie', header)

In this case, the onSend hook will override the manually set header

We can revert it by simply appending to the header instead of setting it manually during onSend, will do that 👍

@mcollina
Copy link
Member

Probably would be better, thx!

@mcollina
Copy link
Member

Thanks!

@Uzlopak
Copy link
Contributor

Uzlopak commented Jul 28, 2023

Is it the code coverage or is it the linter saying an else is mssing?

@gurgunday
You are absolutely right: Encapsulation could be a serious issue. Could be a massive perf eater, when different instances of fastify-cookie try to reconcile the cookies, as i proposed.
But still seams odd.

@mcollina
What do you think about collisions?

@gurgunday
Copy link
Member Author

Is it the code coverage or is it the linter saying an else is mssing?

tap coverage, not the linter, adding istanbul ignore else fixed it

Copy link
Contributor

@Uzlopak Uzlopak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My personal view on this PR:
Yes definitely an improvement and the collisiion issue could also happen in the previous implementation.
But would like have a final comment by @mcollina and/or @Eomm, if possible.

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina
Copy link
Member

I would still ship as semver-major but this looks very good now.

plugin.js Show resolved Hide resolved
@gurgunday
Copy link
Member Author

Latest results for 1 cookie

PR, OLD:

100 connections


┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬────────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%  │ Avg     │ Stdev   │ Max    │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼────────┤
│ Latency │ 1 ms │ 1 ms │ 2 ms  │ 2 ms │ 1.05 ms │ 0.76 ms │ 127 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴────────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬─────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg      │ Stdev   │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤
│ Req/Sec   │ 69375   │ 69375   │ 75967   │ 76991   │ 75429.82 │ 2068.17 │ 69367   │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤
│ Bytes/Sec │ 15.1 MB │ 15.1 MB │ 16.5 MB │ 16.7 MB │ 16.4 MB  │ 447 kB  │ 15.1 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴─────────┴─────────┘

Req/Bytes counts sampled once per second.
# of samples: 11

830k requests in 11.01s, 180 MB read

PR, NEW:

100 connections


┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬───────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%  │ Avg     │ Stdev   │ Max   │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼───────┤
│ Latency │ 1 ms │ 1 ms │ 2 ms  │ 2 ms │ 1.04 ms │ 0.59 ms │ 75 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴───────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬─────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg      │ Stdev   │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤
│ Req/Sec   │ 73471   │ 73471   │ 81023   │ 81535   │ 79956.37 │ 2286.45 │ 73442   │
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼─────────┼─────────┤
│ Bytes/Sec │ 15.9 MB │ 15.9 MB │ 17.6 MB │ 17.7 MB │ 17.3 MB  │ 495 kB  │ 15.9 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴─────────┴─────────┘

Req/Bytes counts sampled once per second.
# of samples: 11

880k requests in 11.01s, 191 MB read

master:

100 connections


┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬───────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%  │ Avg     │ Stdev   │ Max   │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼───────┤
│ Latency │ 0 ms │ 1 ms │ 2 ms  │ 2 ms │ 1.03 ms │ 0.56 ms │ 79 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴───────┘
┌───────────┬─────────┬─────────┬───────┬─────────┬──────────┬────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%   │ 97.5%   │ Avg      │ Stdev  │ Min     │
├───────────┼─────────┼─────────┼───────┼─────────┼──────────┼────────┼─────────┤
│ Req/Sec   │ 76351   │ 76351   │ 83135 │ 83775   │ 82196.37 │ 2105   │ 76308   │
├───────────┼─────────┼─────────┼───────┼─────────┼──────────┼────────┼─────────┤
│ Bytes/Sec │ 16.6 MB │ 16.6 MB │ 18 MB │ 18.2 MB │ 17.8 MB  │ 457 kB │ 16.6 MB │
└───────────┴─────────┴─────────┴───────┴─────────┴──────────┴────────┴─────────┘

Req/Bytes counts sampled once per second.
# of samples: 11

904k requests in 11.01s, 196 MB read

plugin.js Outdated Show resolved Hide resolved
@gurgunday
Copy link
Member Author

gurgunday commented Jul 31, 2023

The numbers budge, but for...of is consistently (slightly) faster on my machine

Here is why I think that is: .values creates an iterator object but calling next() on it is another method call and creates yet another object while for...of directly gets the value. Or maybe for...of causes an optimization since it's language syntax

Anyway I think we're good

@mcollina mcollina merged commit c4c2c19 into fastify:master Aug 1, 2023
15 checks passed
@mcollina mcollina mentioned this pull request Aug 1, 2023
@gurgunday gurgunday deleted the improv branch August 2, 2023 10:19
bodinsamuel referenced this pull request in specfy/specfy Aug 7, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@fastify/cookie](https://github.com/fastify/fastify-cookie) |
[`8.3.0` ->
`9.0.4`](https://renovatebot.com/diffs/npm/@fastify%2fcookie/8.3.0/9.0.4)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@fastify%2fcookie/9.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@fastify%2fcookie/9.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@fastify%2fcookie/8.3.0/9.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@fastify%2fcookie/8.3.0/9.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>fastify/fastify-cookie (@&#8203;fastify/cookie)</summary>

###
[`v9.0.4`](https://github.com/fastify/fastify-cookie/releases/tag/v9.0.4)

[Compare
Source](https://github.com/fastify/fastify-cookie/compare/v9.0.3...v9.0.4)

#### What's Changed

- Fix support for response that does not set a cookie by
[@&#8203;mcollina](https://github.com/mcollina) in
[https://github.com/fastify/fastify-cookie/pull/247](https://github.com/fastify/fastify-cookie/pull/247)

**Full Changelog**:
fastify/fastify-cookie@v9.0.3...v9.0.4

###
[`v9.0.3`](https://github.com/fastify/fastify-cookie/releases/tag/v9.0.3)

[Compare
Source](https://github.com/fastify/fastify-cookie/compare/v9.0.2...v9.0.3)

#### What's Changed

- Do not crash if responding from a previously-registered onRequest hook
by [@&#8203;mcollina](https://github.com/mcollina) in
[https://github.com/fastify/fastify-cookie/pull/245](https://github.com/fastify/fastify-cookie/pull/245)

**Full Changelog**:
fastify/fastify-cookie@v9.0.2...v9.0.3

###
[`v9.0.2`](https://github.com/fastify/fastify-cookie/releases/tag/v9.0.2)

[Compare
Source](https://github.com/fastify/fastify-cookie/compare/v9.0.1...v9.0.2)

#### What's Changed

- use for loop instead of for...of by
[@&#8203;gurgunday](https://github.com/gurgunday) in
[https://github.com/fastify/fastify-cookie/pull/239](https://github.com/fastify/fastify-cookie/pull/239)
- Check if onSend ran and keep resetting the map by
[@&#8203;gurgunday](https://github.com/gurgunday) in
[https://github.com/fastify/fastify-cookie/pull/242](https://github.com/fastify/fastify-cookie/pull/242)
- perf: only clear map when it's populated by
[@&#8203;gurgunday](https://github.com/gurgunday) in
[https://github.com/fastify/fastify-cookie/pull/243](https://github.com/fastify/fastify-cookie/pull/243)
- perf: only call removeHeader when needed by
[@&#8203;gurgunday](https://github.com/gurgunday) in
[https://github.com/fastify/fastify-cookie/pull/244](https://github.com/fastify/fastify-cookie/pull/244)

**Full Changelog**:
fastify/fastify-cookie@v9.0.1...v9.0.2

###
[`v9.0.1`](https://github.com/fastify/fastify-cookie/releases/tag/v9.0.1)

[Compare
Source](https://github.com/fastify/fastify-cookie/compare/v9.0.0...v9.0.1)

#### What's Changed

- Fix [@&#8203;fastify/session](https://github.com/fastify/session) by
[@&#8203;mcollina](https://github.com/mcollina) in
[https://github.com/fastify/fastify-cookie/pull/240](https://github.com/fastify/fastify-cookie/pull/240)

**Full Changelog**:
fastify/fastify-cookie@v9.0.0...v9.0.1

###
[`v9.0.0`](https://github.com/fastify/fastify-cookie/releases/tag/v9.0.0)

[Compare
Source](https://github.com/fastify/fastify-cookie/compare/v8.3.0...v9.0.0)

#### What's Changed

- fix(docs): msecs to seconds
([#&#8203;219](https://github.com/fastify/fastify-cookie/issues/219))
by [@&#8203;seia-soto](https://github.com/seia-soto) in
[https://github.com/fastify/fastify-cookie/pull/220](https://github.com/fastify/fastify-cookie/pull/220)
- chore(deps-dev): bump sinon from 14.0.2 to 15.0.0 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/fastify/fastify-cookie/pull/222](https://github.com/fastify/fastify-cookie/pull/222)
- chore(deps-dev): bump tsd from 0.24.1 to 0.25.0 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/fastify/fastify-cookie/pull/223](https://github.com/fastify/fastify-cookie/pull/223)
- chore(.gitignore): add clinic by
[@&#8203;Fdawgs](https://github.com/Fdawgs) in
[https://github.com/fastify/fastify-cookie/pull/226](https://github.com/fastify/fastify-cookie/pull/226)
- chore(.gitignore): add bun lockfile by
[@&#8203;Fdawgs](https://github.com/Fdawgs) in
[https://github.com/fastify/fastify-cookie/pull/228](https://github.com/fastify/fastify-cookie/pull/228)
- chore(deps-dev): bump tsd from 0.25.0 to 0.26.0 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/fastify/fastify-cookie/pull/229](https://github.com/fastify/fastify-cookie/pull/229)
- chore(deps-dev): bump tsd from 0.26.1 to 0.27.0 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/fastify/fastify-cookie/pull/230](https://github.com/fastify/fastify-cookie/pull/230)
- chore(deps-dev): bump tsd from 0.27.0 to 0.28.0 by
[@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/fastify/fastify-cookie/pull/231](https://github.com/fastify/fastify-cookie/pull/231)
- ci: only trigger on pushes to main branches by
[@&#8203;Fdawgs](https://github.com/Fdawgs) in
[https://github.com/fastify/fastify-cookie/pull/232](https://github.com/fastify/fastify-cookie/pull/232)
- chore(deps-dev): bump
[@&#8203;types/node](https://github.com/types/node) from 18.16.5 to
20.1.0 by [@&#8203;dependabot](https://github.com/dependabot) in
[https://github.com/fastify/fastify-cookie/pull/233](https://github.com/fastify/fastify-cookie/pull/233)
- Fix typo from 'node' to 'none' in CookieSerializeOptions for sameSite
attribute by [@&#8203;Mihai-MCW](https://github.com/Mihai-MCW) in
[https://github.com/fastify/fastify-cookie/pull/236](https://github.com/fastify/fastify-cookie/pull/236)
- Don't send the `Set-Cookie` header multiple times for the same cookie
by [@&#8203;gurgunday](https://github.com/gurgunday) in
[https://github.com/fastify/fastify-cookie/pull/237](https://github.com/fastify/fastify-cookie/pull/237)

#### New Contributors

- [@&#8203;seia-soto](https://github.com/seia-soto) made their first
contribution in
[https://github.com/fastify/fastify-cookie/pull/220](https://github.com/fastify/fastify-cookie/pull/220)
- [@&#8203;Mihai-MCW](https://github.com/Mihai-MCW) made their first
contribution in
[https://github.com/fastify/fastify-cookie/pull/236](https://github.com/fastify/fastify-cookie/pull/236)
- [@&#8203;gurgunday](https://github.com/gurgunday) made their first
contribution in
[https://github.com/fastify/fastify-cookie/pull/237](https://github.com/fastify/fastify-cookie/pull/237)

**Full Changelog**:
fastify/fastify-cookie@v8.3.0...v9.0.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 4pm on friday,before 9am on
monday,every weekend" in timezone Europe/Paris, Automerge - At any time
(no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/specfy/specfy).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4yNy4xIiwidXBkYXRlZEluVmVyIjoiMzYuMjcuMSIsInRhcmdldEJyYW5jaCI6ImNob3JlL3Jlbm92YXRlQmFzZUJyYW5jaCJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@gurgunday gurgunday mentioned this pull request Jan 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Calling setCookie, deleteCookie multiple times in the same request adds multiple set-cookie headers.
4 participants