Commit 172ecb3e authored by jan.koester's avatar jan.koester
Browse files

test

parent c39aa70b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
build/
build-warn/
build-release/
build-scratch/
obj-*-linux-gnu/*
obj-x86_64-linux-gnu/*
out/
+19 −22
Original line number Diff line number Diff line
@@ -594,13 +594,13 @@ void libhttppp::HttpEvent::_finishH2Dispatch(HttpRequest &cureq,
                if (key == ":res-valid" || key == ":res-status" ||
                    key == ":res-content-type" || key == ":res-content-length") continue;
                std::string realKey = key.substr(5);
                std::string joined;
                // See the twin loop below (H3 path) for why this must be one HPACK header
                // field per value rather than one "; "-joined field -- multiple values are
                // multiple separate header lines (e.g. two Set-Cookie headers), and joining
                // them corrupts any response that sets more than one cookie.
                for (auto *v = hd->getfirstValue(); v; v = v->nextvalue()) {
                    if (!joined.empty()) joined += "; ";
                    joined += v->getvalue();
                    extra.push_back({realKey, v->getvalue()});
                }
                if (!joined.empty())
                    extra.push_back({realKey, joined});
            }

            // HEADERS frame
@@ -696,15 +696,15 @@ void libhttppp::HttpEvent::_finishH2Dispatch(HttpRequest &cureq,
            if (key == ":res-valid" || key == ":res-status" ||
                key == ":res-content-type" || key == ":res-content-length") continue;
            std::string realKey = key.substr(5);
            // Join all Values with "; " to reconstruct the full
            // header value (e.g. set-cookie attributes).
            std::string joined;
            // Each Values entry is already one complete header instance (e.g. a full
            // "name=value; Path=/; HttpOnly" Set-Cookie line) -- multiple values on the same
            // key mean multiple *separate* header lines (e.g. two Set-Cookie headers), not
            // attribute fragments of one line. Emit one HPACK header field per value: joining
            // them with "; " produced one line no client could parse back apart, silently
            // breaking any response that sets more than one cookie.
            for (auto *v = hd->getfirstValue(); v; v = v->nextvalue()) {
                if (!joined.empty()) joined += "; ";
                joined += v->getvalue();
                extra.push_back({realKey, v->getvalue()});
            }
            if (!joined.empty())
                extra.push_back({realKey, joined});
        }

        // Build HPACK-encoded HEADERS frame
@@ -1638,13 +1638,12 @@ void libhttppp::HttpEvent::Http3StreamEvent(netplus::socket *sock,
                if (ekey == ":res-valid" || ekey == ":res-status" ||
                    ekey == ":res-content-type" || ekey == ":res-content-length") continue;
                std::string realKey = ekey.substr(5);
                std::string joined;
                // One QPACK header field per value, not one "; "-joined field -- see the H2
                // HPACK path's identical fix for why (multiple values are multiple separate
                // header lines, e.g. two Set-Cookie headers, not attribute fragments).
                for (auto *v = hd->getfirstValue(); v; v = v->nextvalue()) {
                    if (!joined.empty()) joined += "; ";
                    joined += v->getvalue();
                    hdr_extra.push_back({realKey, v->getvalue()});
                }
                if (!joined.empty())
                    hdr_extra.push_back({realKey, joined});
            }

            // Build and send H3 HEADERS frame immediately
@@ -1778,13 +1777,11 @@ void libhttppp::HttpEvent::Http3StreamEvent(netplus::socket *sock,
            if (ekey == ":res-valid" || ekey == ":res-status" ||
                ekey == ":res-content-type" || ekey == ":res-content-length") continue;
            std::string realKey = ekey.substr(5);
            std::string joined;
            // One QPACK header field per value -- see the streaming H3 path above / H2 HPACK
            // path for why joining multiple values with "; " corrupts multi-cookie responses.
            for (auto *v = hd->getfirstValue(); v; v = v->nextvalue()) {
                if (!joined.empty()) joined += "; ";
                joined += v->getvalue();
                extra.push_back({realKey, v->getvalue()});
            }
            if (!joined.empty())
                extra.push_back({realKey, joined});
        }

        std::vector<uint8_t> response = h3BuildResponse(