Loading src/httpd.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -371,6 +371,17 @@ void libhttppp::HttpEvent::_dispatchH2Stream(HttpRequest &cureq, HttpRequest &tempreq = *tempreq_ptr; tempreq.parseH2(decoded, sid); // Log dispatch for debugging std::string dbg_path; for (auto &hf : decoded) { if (hf.name == ":path") { dbg_path = hf.value; break; } } bool had_active = cureq.h2state().activeStreams.count(sid) > 0; std::cerr << "[H2-DISPATCH] sid=" << sid << " path=" << dbg_path << " activeAlready=" << had_active << std::endl; // Store POST body in RecvData so HttpForm::parse() can access it if (!reqBody.empty()) { tempreq.RecvData.append(reqBody.data(), reqBody.size()); Loading Loading @@ -502,6 +513,19 @@ void libhttppp::HttpEvent::_dispatchH2Stream(HttpRequest &cureq, if (ss->totalSent >= content_length) { cureq.h2state().peerStreamWindows.erase(sid); } else { // Guard: don't overwrite an active streaming response // for the same stream ID — that would destroy the old // tempreq while ResponseEvent may still reference it. if (cureq.h2state().activeStreams.count(sid) > 0) { std::cerr << "[H2-DISPATCH] WARNING: sid=" << sid << " already has an active stream, skipping" << std::endl; // Send RST_STREAM to signal the duplicate was rejected uint8_t rst[4] = {0, 0, 0, 0x08}; // CANCEL out += h2BuildFrame(H2_FRAME_RST_STREAM, 0, sid, std::string(reinterpret_cast<char*>(rst), 4)); return; } // Store for resumption on WINDOW_UPDATE cureq.h2state().activeStreams[sid] = ss; // Immediately kick off the first data fetch — don't wait Loading Loading
src/httpd.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -371,6 +371,17 @@ void libhttppp::HttpEvent::_dispatchH2Stream(HttpRequest &cureq, HttpRequest &tempreq = *tempreq_ptr; tempreq.parseH2(decoded, sid); // Log dispatch for debugging std::string dbg_path; for (auto &hf : decoded) { if (hf.name == ":path") { dbg_path = hf.value; break; } } bool had_active = cureq.h2state().activeStreams.count(sid) > 0; std::cerr << "[H2-DISPATCH] sid=" << sid << " path=" << dbg_path << " activeAlready=" << had_active << std::endl; // Store POST body in RecvData so HttpForm::parse() can access it if (!reqBody.empty()) { tempreq.RecvData.append(reqBody.data(), reqBody.size()); Loading Loading @@ -502,6 +513,19 @@ void libhttppp::HttpEvent::_dispatchH2Stream(HttpRequest &cureq, if (ss->totalSent >= content_length) { cureq.h2state().peerStreamWindows.erase(sid); } else { // Guard: don't overwrite an active streaming response // for the same stream ID — that would destroy the old // tempreq while ResponseEvent may still reference it. if (cureq.h2state().activeStreams.count(sid) > 0) { std::cerr << "[H2-DISPATCH] WARNING: sid=" << sid << " already has an active stream, skipping" << std::endl; // Send RST_STREAM to signal the duplicate was rejected uint8_t rst[4] = {0, 0, 0, 0x08}; // CANCEL out += h2BuildFrame(H2_FRAME_RST_STREAM, 0, sid, std::string(reinterpret_cast<char*>(rst), 4)); return; } // Store for resumption on WINDOW_UPDATE cureq.h2state().activeStreams[sid] = ss; // Immediately kick off the first data fetch — don't wait Loading