Fix stale Set-Cookie pointer after HttpHeader mutations by songgaoye · Pull Request #3606 · apache/brpc · GitHub
Skip to content

Fix stale Set-Cookie pointer after HttpHeader mutations - #3606

Draft
songgaoye wants to merge 6 commits into
apache:masterfrom
songgaoye:fix/http-header-set-cookie-cache
Draft

songgaoye wants to merge 6 commits into
apache:masterfrom
songgaoye:fix/http-header-set-cookie-cache

Conversation

@songgaoye

@songgaoye songgaoye commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: resolve

Problem Summary:

HttpHeader caches the first Set-Cookie value as a pointer into its
HeaderMap. The pointer becomes stale when the map grows.

Refreshing it with HeaderMap::seek() is not sufficient: HeaderMap is a
multi-map and does not preserve the identity or insertion order of duplicate
Set-Cookie fields. The refreshed pointer may therefore select a different
cookie.

What is changed and the side effects?

Changed:

Store Set-Cookie fields separately in insertion order and keep HeaderMap
synchronized for header iteration and serialization.

Make GetHeader(SET_COOKIE) and GetAllSetCookieHeader() read the stable
ordered storage. This also makes Swap() and Clear() safe without retaining
a stale cached pointer.

Add regression coverage for actual map growth, multiple Set-Cookie fields,
fragmented HTTP parsing, Swap(), copy construction, and assignment.

Side effects:

  • Performance effects:

    The change only adds separate storage and synchronization for Set-Cookie
    fields. Ordinary headers keep the existing path.

  • Breaking backward compatibility:

    None.

@chenBright
chenBright requested a lite review from Copilot October 14, 2026 11:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

4 open findings
What changed in this PR

Fixes a stale cached pointer for the first Set-Cookie header in HttpHeader after HeaderMap mutations (rehash/growth), Swap(), and Clear(), and adds regression tests for these cases.

Changes:

  • Refresh _first_set_cookie after HeaderMap growth and after HttpHeader::Swap()
  • Clear _first_set_cookie in HttpHeader::Clear()
  • Add unit tests covering map growth, Swap(), and Clear()
File Description
test/​brpc_http_message_unittest.cpp Adds regression tests to catch stale _first_set_cookie after growth, Swap(), and Clear().
src/​brpc/​http_header.h Declares RefreshFirstSetCookie() helper to rebuild the cached pointer safely.
src/​brpc/​http_header.cpp Implements pointer refresh logic on rehash/growth and Swap(), and clears cache on Clear().

🧠 Review effort: Lite


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread test/brpc_http_message_unittest.cpp Outdated
Comment thread test/brpc_http_message_unittest.cpp
Comment thread src/brpc/http_header.cpp Outdated
Comment thread test/brpc_http_message_unittest.cpp Outdated
@songgaoye

songgaoye commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor Author

The CI failure is unrelated to this PR. It was fixed in #3610.

Comment thread src/brpc/http_header.cpp Outdated
@songgaoye
songgaoye force-pushed the fix/http-header-set-cookie-cache branch from bfe433d to 70608b9 Compare October 15, 2026 05:50
@chenBright
chenBright requested a lite review from Copilot October 16, 2026 03:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment thread src/brpc/details/http_message.cpp
Comment thread src/brpc/http_header.cpp
Comment thread test/brpc_http_message_unittest.cpp Outdated
Comment thread test/brpc_http_message_unittest.cpp Outdated
@songgaoye
songgaoye force-pushed the fix/http-header-set-cookie-cache branch from f9c55d5 to b6001dc Compare October 16, 2026 06:02
@chenBright
chenBright requested a lite review from Copilot October 17, 2026 10:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment thread src/brpc/http_header.cpp
@songgaoye
songgaoye requested a review from chenBright October 18, 2026 01:13
@wwbmmm

wwbmmm commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

LGTM

Comment thread src/brpc/http_header.cpp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AppendHeader() now inserts incrementally, but SetHeader() still forces a full synchronization. With the default 16-bucket map, the following sequence reaches the unsafe deletion path:

brpc::HttpHeader h;
h.SetHeader("Set-Cookie", "sid=" + std::string(128, 'x'));
h.SetHeader("User-Agent", "client");
h.SetHeader("Set-Cookie", "sid=new");

Set-Cookie and User-Agent collide. During the final update, _headers.erase(SET_COOKIE) removes the Cookie bucket head while retaining the User-Agent node.

MultiFlatMap::erase() destroys the head’s strings at flat_map_inl.h:473, then assigns the surviving node into those destroyed objects at lines 501–503 without reconstructing the element. With a heap-backed Cookie value, this can cause a double-free or heap corruption.

@songgaoye
songgaoye marked this pull request as draft October 21, 2026 15:03
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.

4 participants