Loading debian/.debhelper/generated/libhttppp-dev/dh_installchangelogs.dch.trimmed +148 −0 Changes for debian/.debhelper/generated/libhttppp-dev/dh_installchangelogs.dch.trimmed: 148 added lines, 0 removed lines. Original line number Diff line number Diff line libhttppp (20261006+1) stable; urgency=medium * new upstream release -- Jan Koester <jan.koester@tuxist.de> Tue, 06 Oct 2026 18:53:05 +0200 libhttppp (20260731+13) unstable; urgency=high * HttpEvent: fix H2 offloaded streaming responses (e.g. mediadb previews) stalling permanently once the peer's initial flow-control window is exhausted, whenever the response was dispatched to the H2 offload pool (shouldOffloadH2Dispatch() == true, shipped in 20260731+12). A client's WINDOW_UPDATE for that stream could arrive and be processed before the background render finished, at which point peerStreamWindows had no entry yet for that stream id — the credit was silently discarded, and _finishH2Dispatch then unconditionally reset the window to the default once the render completed, permanently losing it. A well-behaved peer never repeats a grant it believes already landed, so any response body over ~64KB (the default window) hung forever with no timeout and no error. _dispatchH2Stream now seeds peerStreamWindows[sid] via try_emplace synchronously before handing the request to the offload pool (safe: all frame dispatch for a connection, including a later WINDOW_UPDATE, is serialized through the same connection event_mutex), and _finishH2Dispatch's two window-init sites use try_emplace instead of unconditional assignment so they no longer clobber credit gained in the meantime. New test: httpd_h2_window_credit_race_test.cpp. -- Jan Koester <jan.koester@tuxist.de> Fri, 31 Jul 2026 09:45:00 +0200 libhttppp (20260731+12) unstable; urgency=high * HttpEvent: fix H2 streaming responses (large images/video) stalling permanently after the first chunk whenever the upstream/handler had no more data ready yet — _finishH2Dispatch had no else branch (H2) and Http3StreamEvent's had an empty one, so if the app handler never called HttpResponse::send() nothing was ever sent back, not even an error; now sends RST_STREAM(INTERNAL_ERROR) for H2 and resetStream(H3_INTERNAL_ERROR) for H3 so the stream terminates deterministically instead of hanging the client forever. * Http2RequestEvent: the reprocess-count fairness cap (16 per call) could strand a >17th buffered simple request on one multiplexed connection with no way to ever get processed, since SendData was already flushed and empty by the time control returned to epoll. Now explicitly sets ResponsePending + calls requestWritablePoll when the cap is hit while more complete-frame data is still buffered. * HttpEvent: exported threadpool.h-based H2 dispatch offload infrastructure (con::ownerPollFd, netplus::lookupConnection(fd), netplus::requestWritablePoll(con&)) so a blocking per-request handler can run off the event-loop thread without blocking sibling streams on the same connection — root cause of the H2 "staircase" (streams on one connection served strictly sequentially instead of concurrently). New test: httpd_h2_concurrency_test.cpp. -- Jan Koester <jan.koester@tuxist.de> Fri, 31 Jul 2026 08:05:00 +0200 libhttppp (20260718+11) unstable; urgency=high * HttpUrl: track the original URL scheme (http/https) separately from _protocol, which the http3=true constructor flag permanently pins to HTTP3. Add HttpUrl::getOriginalProtocol() for the fallback decisions below, which need to know the actual scheme regardless of that flag. * HttpClient: fix HTTP/3 clients constructed against a non-QUIC endpoint (e.g. mediadb::Client(url, ..., /*http3=*/true) against a plain HTTP server) always failing outright instead of falling back to HTTP/1.1. tryHttp3First() correctly detected and cached the QUIC failure, but the ctor's own fallback-strategy check (getProtocol() == HTTPS, meant to tell "try HTTP/2 next" apart from "go cleartext") could never see HTTPS once http3=true had pinned that field to HTTP3, so cleartext targets always fell into the cleartext branch and called resetConnection() -- which re-derived the transport from that same permanently-HTTP3 field and re-entered the QUIC branch a second time. That second attempt runs quic::connect() in blocking mode with no surrounding try/catch, so it blocks for the full 5s handshake timeout and then throws instead of falling back, surfacing on every request as "HttpClient ctor connect failed: quic::completeHandshake: handshake timed out". resetConnection() and reconnect() now only take the QUIC branch when _vers == 3 (HTTP/3 is still what's wanted, not a downgraded fallback attempt), and choose between TLS and plain TCP based on the URL's original scheme instead of the pinned field. -- Jan Koester <jan.koester@tuxist.de> Sat, 18 Jul 2026 14:50:00 +0200 libhttppp (20260707+10) unstable; urgency=medium * HttpEvent::_resumeH2Streams: on a genuine upstream stall (emptyCount > 500) with the response short of the advertised Content-Length, send RST_STREAM(INTERNAL_ERROR) instead of END_STREAM. Ending the stream normally made the client accept the truncated body as a complete response (e.g. a corrupted image); aborting the stream now surfaces the failed transfer instead. -- Jan Koester <jan.koester@tuxist.de> Tue, 07 Jul 2026 12:11:54 +0200 libhttppp (20260704+9) unstable; urgency=high * HttpClient::GetStream: fix unbounded blocking while reading response headers — each call to the header-read loop restarted a fresh 10s timeout on every partial chunk, so a peer trickling a byte every few seconds could hold the loop (and the calling thread) open indefinitely. Now uses a single 10s deadline for the whole header, throwing HTTPException on expiry instead of resetting the clock per chunk. * HttpEvent::_resumeH2Streams: fix HTTP/2 streaming responses (video, large previews) spinning forever instead of failing when the upstream stalls. The stall counter (emptyCount, capped at 500) was reset to 0 every time by checking ss->tempreq's own ResponsePending flag — but tempreq is a synthetic per-stream request with no external writer of that flag; it was actually being set, on every empty read, by the app-level ResponseEvent handler we had just called (a "rearm me for a real connection" signal, not a "new data arrived" signal), so the check always read true and the counter could never advance. Combined with the epoll layer re-arming EPOLLOUT every such cycle (always ready, since nothing is being written), a stalled upstream produced an unconditional, zero-backoff CPU spin with no progress on the stream. emptyCount now increments unconditionally on empty reads, so the existing 500-attempt cap actually terminates a genuinely stalled stream with END_STREAM instead of hanging. -- Jan Koester <jan.koester@tuxist.de> Sat, 04 Jul 2026 06:02:49 +0200 libhttppp (20260629+8) unstable; urgency=medium * HTTPException: derive from std::exception and change what() to the standard "const char* noexcept" signature instead of returning a "const std::string&". Callers catching libhttppp::HTTPException by a generic "catch(std::exception&)" now work correctly, and the httpform, httpauth and httpclient examples were updated to use the new signature (httpauth/httpclient now catch std::exception instead of HTTPException so unrelated std:: exceptions are no longer left uncaught). * HttpClient: when an HTTP/3 connection attempt fails, probe HTTP/2 via ALPN before falling back to HTTP/1.1 instead of dropping straight to HTTP/1.1. If that HTTP/2 probe also fails to negotiate "h2", the constructor now throws HTTPException instead of silently retrying the connection over HTTP/1.1, since a silent downgrade masked negotiation failures that should be surfaced to the caller. -- Jan Koester <jan.koester@tuxist.de> Mon, 29 Jun 2026 12:00:00 +0200 libhttppp (20260605+7) unstable; urgency=medium * HttpD: decode HTTP/1.1 chunked request bodies on the server side. Reverse proxies such as Traefik downgrade HTTP/2 POSTs to HTTP/1.1 using Transfer-Encoding: chunked (no Content-Length); the server loop now de-chunks the body before dispatching RequestEvent and rewrites the Content-Length header, fixing form submissions that were forwarded with raw chunk framing and could not be parsed by the backend. -- Jan Koester <jan.koester@tuxist.de> Fri, 05 Jun 2026 12:00:00 +0200 libhttppp (20260521+6) unstable; urgency=medium * HttpD: add reloadCertificates() for runtime TLS certificate hot-reload Loading debian/.debhelper/generated/libhttppp-doc/dh_installchangelogs.dch.trimmed +148 −0 Changes for debian/.debhelper/generated/libhttppp-doc/dh_installchangelogs.dch.trimmed: 148 added lines, 0 removed lines. Original line number Diff line number Diff line libhttppp (20261006+1) stable; urgency=medium * new upstream release -- Jan Koester <jan.koester@tuxist.de> Tue, 06 Oct 2026 18:53:05 +0200 libhttppp (20260731+13) unstable; urgency=high * HttpEvent: fix H2 offloaded streaming responses (e.g. mediadb previews) stalling permanently once the peer's initial flow-control window is exhausted, whenever the response was dispatched to the H2 offload pool (shouldOffloadH2Dispatch() == true, shipped in 20260731+12). A client's WINDOW_UPDATE for that stream could arrive and be processed before the background render finished, at which point peerStreamWindows had no entry yet for that stream id — the credit was silently discarded, and _finishH2Dispatch then unconditionally reset the window to the default once the render completed, permanently losing it. A well-behaved peer never repeats a grant it believes already landed, so any response body over ~64KB (the default window) hung forever with no timeout and no error. _dispatchH2Stream now seeds peerStreamWindows[sid] via try_emplace synchronously before handing the request to the offload pool (safe: all frame dispatch for a connection, including a later WINDOW_UPDATE, is serialized through the same connection event_mutex), and _finishH2Dispatch's two window-init sites use try_emplace instead of unconditional assignment so they no longer clobber credit gained in the meantime. New test: httpd_h2_window_credit_race_test.cpp. -- Jan Koester <jan.koester@tuxist.de> Fri, 31 Jul 2026 09:45:00 +0200 libhttppp (20260731+12) unstable; urgency=high * HttpEvent: fix H2 streaming responses (large images/video) stalling permanently after the first chunk whenever the upstream/handler had no more data ready yet — _finishH2Dispatch had no else branch (H2) and Http3StreamEvent's had an empty one, so if the app handler never called HttpResponse::send() nothing was ever sent back, not even an error; now sends RST_STREAM(INTERNAL_ERROR) for H2 and resetStream(H3_INTERNAL_ERROR) for H3 so the stream terminates deterministically instead of hanging the client forever. * Http2RequestEvent: the reprocess-count fairness cap (16 per call) could strand a >17th buffered simple request on one multiplexed connection with no way to ever get processed, since SendData was already flushed and empty by the time control returned to epoll. Now explicitly sets ResponsePending + calls requestWritablePoll when the cap is hit while more complete-frame data is still buffered. * HttpEvent: exported threadpool.h-based H2 dispatch offload infrastructure (con::ownerPollFd, netplus::lookupConnection(fd), netplus::requestWritablePoll(con&)) so a blocking per-request handler can run off the event-loop thread without blocking sibling streams on the same connection — root cause of the H2 "staircase" (streams on one connection served strictly sequentially instead of concurrently). New test: httpd_h2_concurrency_test.cpp. -- Jan Koester <jan.koester@tuxist.de> Fri, 31 Jul 2026 08:05:00 +0200 libhttppp (20260718+11) unstable; urgency=high * HttpUrl: track the original URL scheme (http/https) separately from _protocol, which the http3=true constructor flag permanently pins to HTTP3. Add HttpUrl::getOriginalProtocol() for the fallback decisions below, which need to know the actual scheme regardless of that flag. * HttpClient: fix HTTP/3 clients constructed against a non-QUIC endpoint (e.g. mediadb::Client(url, ..., /*http3=*/true) against a plain HTTP server) always failing outright instead of falling back to HTTP/1.1. tryHttp3First() correctly detected and cached the QUIC failure, but the ctor's own fallback-strategy check (getProtocol() == HTTPS, meant to tell "try HTTP/2 next" apart from "go cleartext") could never see HTTPS once http3=true had pinned that field to HTTP3, so cleartext targets always fell into the cleartext branch and called resetConnection() -- which re-derived the transport from that same permanently-HTTP3 field and re-entered the QUIC branch a second time. That second attempt runs quic::connect() in blocking mode with no surrounding try/catch, so it blocks for the full 5s handshake timeout and then throws instead of falling back, surfacing on every request as "HttpClient ctor connect failed: quic::completeHandshake: handshake timed out". resetConnection() and reconnect() now only take the QUIC branch when _vers == 3 (HTTP/3 is still what's wanted, not a downgraded fallback attempt), and choose between TLS and plain TCP based on the URL's original scheme instead of the pinned field. -- Jan Koester <jan.koester@tuxist.de> Sat, 18 Jul 2026 14:50:00 +0200 libhttppp (20260707+10) unstable; urgency=medium * HttpEvent::_resumeH2Streams: on a genuine upstream stall (emptyCount > 500) with the response short of the advertised Content-Length, send RST_STREAM(INTERNAL_ERROR) instead of END_STREAM. Ending the stream normally made the client accept the truncated body as a complete response (e.g. a corrupted image); aborting the stream now surfaces the failed transfer instead. -- Jan Koester <jan.koester@tuxist.de> Tue, 07 Jul 2026 12:11:54 +0200 libhttppp (20260704+9) unstable; urgency=high * HttpClient::GetStream: fix unbounded blocking while reading response headers — each call to the header-read loop restarted a fresh 10s timeout on every partial chunk, so a peer trickling a byte every few seconds could hold the loop (and the calling thread) open indefinitely. Now uses a single 10s deadline for the whole header, throwing HTTPException on expiry instead of resetting the clock per chunk. * HttpEvent::_resumeH2Streams: fix HTTP/2 streaming responses (video, large previews) spinning forever instead of failing when the upstream stalls. The stall counter (emptyCount, capped at 500) was reset to 0 every time by checking ss->tempreq's own ResponsePending flag — but tempreq is a synthetic per-stream request with no external writer of that flag; it was actually being set, on every empty read, by the app-level ResponseEvent handler we had just called (a "rearm me for a real connection" signal, not a "new data arrived" signal), so the check always read true and the counter could never advance. Combined with the epoll layer re-arming EPOLLOUT every such cycle (always ready, since nothing is being written), a stalled upstream produced an unconditional, zero-backoff CPU spin with no progress on the stream. emptyCount now increments unconditionally on empty reads, so the existing 500-attempt cap actually terminates a genuinely stalled stream with END_STREAM instead of hanging. -- Jan Koester <jan.koester@tuxist.de> Sat, 04 Jul 2026 06:02:49 +0200 libhttppp (20260629+8) unstable; urgency=medium * HTTPException: derive from std::exception and change what() to the standard "const char* noexcept" signature instead of returning a "const std::string&". Callers catching libhttppp::HTTPException by a generic "catch(std::exception&)" now work correctly, and the httpform, httpauth and httpclient examples were updated to use the new signature (httpauth/httpclient now catch std::exception instead of HTTPException so unrelated std:: exceptions are no longer left uncaught). * HttpClient: when an HTTP/3 connection attempt fails, probe HTTP/2 via ALPN before falling back to HTTP/1.1 instead of dropping straight to HTTP/1.1. If that HTTP/2 probe also fails to negotiate "h2", the constructor now throws HTTPException instead of silently retrying the connection over HTTP/1.1, since a silent downgrade masked negotiation failures that should be surfaced to the caller. -- Jan Koester <jan.koester@tuxist.de> Mon, 29 Jun 2026 12:00:00 +0200 libhttppp (20260605+7) unstable; urgency=medium * HttpD: decode HTTP/1.1 chunked request bodies on the server side. Reverse proxies such as Traefik downgrade HTTP/2 POSTs to HTTP/1.1 using Transfer-Encoding: chunked (no Content-Length); the server loop now de-chunks the body before dispatching RequestEvent and rewrites the Content-Length header, fixing form submissions that were forwarded with raw chunk framing and could not be parsed by the backend. -- Jan Koester <jan.koester@tuxist.de> Fri, 05 Jun 2026 12:00:00 +0200 libhttppp (20260521+6) unstable; urgency=medium * HttpD: add reloadCertificates() for runtime TLS certificate hot-reload Loading debian/.debhelper/generated/libhttppp1/dh_installchangelogs.dch.trimmed +148 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes debian/.debhelper/generated/libhttppp1/installed-by-dh_install +1 −1 Changes for debian/.debhelper/generated/libhttppp1/installed-by-dh_install: 1 added line, 1 removed line. Original line number Diff line number Diff line debian/tmp/usr/lib/x86_64-linux-gnu/libhttppp.so.1 debian/tmp/usr/lib/x86_64-linux-gnu/libhttppp.so.1.0.0 debian/tmp/usr/lib/x86_64-linux-gnu/libhttppp.so.1.0.1 debian/.debhelper/generated/libhttppp1/triggers +1 −1 Changes for debian/.debhelper/generated/libhttppp1/triggers: 1 added line, 1 removed line. Original line number Diff line number Diff line # Triggers added by dh_makeshlibs/13.31~bpo13+1 # Triggers added by dh_makeshlibs/13.24.2 activate-noawait ldconfig Loading
debian/.debhelper/generated/libhttppp-dev/dh_installchangelogs.dch.trimmed +148 −0 Changes for debian/.debhelper/generated/libhttppp-dev/dh_installchangelogs.dch.trimmed: 148 added lines, 0 removed lines. Original line number Diff line number Diff line libhttppp (20261006+1) stable; urgency=medium * new upstream release -- Jan Koester <jan.koester@tuxist.de> Tue, 06 Oct 2026 18:53:05 +0200 libhttppp (20260731+13) unstable; urgency=high * HttpEvent: fix H2 offloaded streaming responses (e.g. mediadb previews) stalling permanently once the peer's initial flow-control window is exhausted, whenever the response was dispatched to the H2 offload pool (shouldOffloadH2Dispatch() == true, shipped in 20260731+12). A client's WINDOW_UPDATE for that stream could arrive and be processed before the background render finished, at which point peerStreamWindows had no entry yet for that stream id — the credit was silently discarded, and _finishH2Dispatch then unconditionally reset the window to the default once the render completed, permanently losing it. A well-behaved peer never repeats a grant it believes already landed, so any response body over ~64KB (the default window) hung forever with no timeout and no error. _dispatchH2Stream now seeds peerStreamWindows[sid] via try_emplace synchronously before handing the request to the offload pool (safe: all frame dispatch for a connection, including a later WINDOW_UPDATE, is serialized through the same connection event_mutex), and _finishH2Dispatch's two window-init sites use try_emplace instead of unconditional assignment so they no longer clobber credit gained in the meantime. New test: httpd_h2_window_credit_race_test.cpp. -- Jan Koester <jan.koester@tuxist.de> Fri, 31 Jul 2026 09:45:00 +0200 libhttppp (20260731+12) unstable; urgency=high * HttpEvent: fix H2 streaming responses (large images/video) stalling permanently after the first chunk whenever the upstream/handler had no more data ready yet — _finishH2Dispatch had no else branch (H2) and Http3StreamEvent's had an empty one, so if the app handler never called HttpResponse::send() nothing was ever sent back, not even an error; now sends RST_STREAM(INTERNAL_ERROR) for H2 and resetStream(H3_INTERNAL_ERROR) for H3 so the stream terminates deterministically instead of hanging the client forever. * Http2RequestEvent: the reprocess-count fairness cap (16 per call) could strand a >17th buffered simple request on one multiplexed connection with no way to ever get processed, since SendData was already flushed and empty by the time control returned to epoll. Now explicitly sets ResponsePending + calls requestWritablePoll when the cap is hit while more complete-frame data is still buffered. * HttpEvent: exported threadpool.h-based H2 dispatch offload infrastructure (con::ownerPollFd, netplus::lookupConnection(fd), netplus::requestWritablePoll(con&)) so a blocking per-request handler can run off the event-loop thread without blocking sibling streams on the same connection — root cause of the H2 "staircase" (streams on one connection served strictly sequentially instead of concurrently). New test: httpd_h2_concurrency_test.cpp. -- Jan Koester <jan.koester@tuxist.de> Fri, 31 Jul 2026 08:05:00 +0200 libhttppp (20260718+11) unstable; urgency=high * HttpUrl: track the original URL scheme (http/https) separately from _protocol, which the http3=true constructor flag permanently pins to HTTP3. Add HttpUrl::getOriginalProtocol() for the fallback decisions below, which need to know the actual scheme regardless of that flag. * HttpClient: fix HTTP/3 clients constructed against a non-QUIC endpoint (e.g. mediadb::Client(url, ..., /*http3=*/true) against a plain HTTP server) always failing outright instead of falling back to HTTP/1.1. tryHttp3First() correctly detected and cached the QUIC failure, but the ctor's own fallback-strategy check (getProtocol() == HTTPS, meant to tell "try HTTP/2 next" apart from "go cleartext") could never see HTTPS once http3=true had pinned that field to HTTP3, so cleartext targets always fell into the cleartext branch and called resetConnection() -- which re-derived the transport from that same permanently-HTTP3 field and re-entered the QUIC branch a second time. That second attempt runs quic::connect() in blocking mode with no surrounding try/catch, so it blocks for the full 5s handshake timeout and then throws instead of falling back, surfacing on every request as "HttpClient ctor connect failed: quic::completeHandshake: handshake timed out". resetConnection() and reconnect() now only take the QUIC branch when _vers == 3 (HTTP/3 is still what's wanted, not a downgraded fallback attempt), and choose between TLS and plain TCP based on the URL's original scheme instead of the pinned field. -- Jan Koester <jan.koester@tuxist.de> Sat, 18 Jul 2026 14:50:00 +0200 libhttppp (20260707+10) unstable; urgency=medium * HttpEvent::_resumeH2Streams: on a genuine upstream stall (emptyCount > 500) with the response short of the advertised Content-Length, send RST_STREAM(INTERNAL_ERROR) instead of END_STREAM. Ending the stream normally made the client accept the truncated body as a complete response (e.g. a corrupted image); aborting the stream now surfaces the failed transfer instead. -- Jan Koester <jan.koester@tuxist.de> Tue, 07 Jul 2026 12:11:54 +0200 libhttppp (20260704+9) unstable; urgency=high * HttpClient::GetStream: fix unbounded blocking while reading response headers — each call to the header-read loop restarted a fresh 10s timeout on every partial chunk, so a peer trickling a byte every few seconds could hold the loop (and the calling thread) open indefinitely. Now uses a single 10s deadline for the whole header, throwing HTTPException on expiry instead of resetting the clock per chunk. * HttpEvent::_resumeH2Streams: fix HTTP/2 streaming responses (video, large previews) spinning forever instead of failing when the upstream stalls. The stall counter (emptyCount, capped at 500) was reset to 0 every time by checking ss->tempreq's own ResponsePending flag — but tempreq is a synthetic per-stream request with no external writer of that flag; it was actually being set, on every empty read, by the app-level ResponseEvent handler we had just called (a "rearm me for a real connection" signal, not a "new data arrived" signal), so the check always read true and the counter could never advance. Combined with the epoll layer re-arming EPOLLOUT every such cycle (always ready, since nothing is being written), a stalled upstream produced an unconditional, zero-backoff CPU spin with no progress on the stream. emptyCount now increments unconditionally on empty reads, so the existing 500-attempt cap actually terminates a genuinely stalled stream with END_STREAM instead of hanging. -- Jan Koester <jan.koester@tuxist.de> Sat, 04 Jul 2026 06:02:49 +0200 libhttppp (20260629+8) unstable; urgency=medium * HTTPException: derive from std::exception and change what() to the standard "const char* noexcept" signature instead of returning a "const std::string&". Callers catching libhttppp::HTTPException by a generic "catch(std::exception&)" now work correctly, and the httpform, httpauth and httpclient examples were updated to use the new signature (httpauth/httpclient now catch std::exception instead of HTTPException so unrelated std:: exceptions are no longer left uncaught). * HttpClient: when an HTTP/3 connection attempt fails, probe HTTP/2 via ALPN before falling back to HTTP/1.1 instead of dropping straight to HTTP/1.1. If that HTTP/2 probe also fails to negotiate "h2", the constructor now throws HTTPException instead of silently retrying the connection over HTTP/1.1, since a silent downgrade masked negotiation failures that should be surfaced to the caller. -- Jan Koester <jan.koester@tuxist.de> Mon, 29 Jun 2026 12:00:00 +0200 libhttppp (20260605+7) unstable; urgency=medium * HttpD: decode HTTP/1.1 chunked request bodies on the server side. Reverse proxies such as Traefik downgrade HTTP/2 POSTs to HTTP/1.1 using Transfer-Encoding: chunked (no Content-Length); the server loop now de-chunks the body before dispatching RequestEvent and rewrites the Content-Length header, fixing form submissions that were forwarded with raw chunk framing and could not be parsed by the backend. -- Jan Koester <jan.koester@tuxist.de> Fri, 05 Jun 2026 12:00:00 +0200 libhttppp (20260521+6) unstable; urgency=medium * HttpD: add reloadCertificates() for runtime TLS certificate hot-reload Loading
debian/.debhelper/generated/libhttppp-doc/dh_installchangelogs.dch.trimmed +148 −0 Changes for debian/.debhelper/generated/libhttppp-doc/dh_installchangelogs.dch.trimmed: 148 added lines, 0 removed lines. Original line number Diff line number Diff line libhttppp (20261006+1) stable; urgency=medium * new upstream release -- Jan Koester <jan.koester@tuxist.de> Tue, 06 Oct 2026 18:53:05 +0200 libhttppp (20260731+13) unstable; urgency=high * HttpEvent: fix H2 offloaded streaming responses (e.g. mediadb previews) stalling permanently once the peer's initial flow-control window is exhausted, whenever the response was dispatched to the H2 offload pool (shouldOffloadH2Dispatch() == true, shipped in 20260731+12). A client's WINDOW_UPDATE for that stream could arrive and be processed before the background render finished, at which point peerStreamWindows had no entry yet for that stream id — the credit was silently discarded, and _finishH2Dispatch then unconditionally reset the window to the default once the render completed, permanently losing it. A well-behaved peer never repeats a grant it believes already landed, so any response body over ~64KB (the default window) hung forever with no timeout and no error. _dispatchH2Stream now seeds peerStreamWindows[sid] via try_emplace synchronously before handing the request to the offload pool (safe: all frame dispatch for a connection, including a later WINDOW_UPDATE, is serialized through the same connection event_mutex), and _finishH2Dispatch's two window-init sites use try_emplace instead of unconditional assignment so they no longer clobber credit gained in the meantime. New test: httpd_h2_window_credit_race_test.cpp. -- Jan Koester <jan.koester@tuxist.de> Fri, 31 Jul 2026 09:45:00 +0200 libhttppp (20260731+12) unstable; urgency=high * HttpEvent: fix H2 streaming responses (large images/video) stalling permanently after the first chunk whenever the upstream/handler had no more data ready yet — _finishH2Dispatch had no else branch (H2) and Http3StreamEvent's had an empty one, so if the app handler never called HttpResponse::send() nothing was ever sent back, not even an error; now sends RST_STREAM(INTERNAL_ERROR) for H2 and resetStream(H3_INTERNAL_ERROR) for H3 so the stream terminates deterministically instead of hanging the client forever. * Http2RequestEvent: the reprocess-count fairness cap (16 per call) could strand a >17th buffered simple request on one multiplexed connection with no way to ever get processed, since SendData was already flushed and empty by the time control returned to epoll. Now explicitly sets ResponsePending + calls requestWritablePoll when the cap is hit while more complete-frame data is still buffered. * HttpEvent: exported threadpool.h-based H2 dispatch offload infrastructure (con::ownerPollFd, netplus::lookupConnection(fd), netplus::requestWritablePoll(con&)) so a blocking per-request handler can run off the event-loop thread without blocking sibling streams on the same connection — root cause of the H2 "staircase" (streams on one connection served strictly sequentially instead of concurrently). New test: httpd_h2_concurrency_test.cpp. -- Jan Koester <jan.koester@tuxist.de> Fri, 31 Jul 2026 08:05:00 +0200 libhttppp (20260718+11) unstable; urgency=high * HttpUrl: track the original URL scheme (http/https) separately from _protocol, which the http3=true constructor flag permanently pins to HTTP3. Add HttpUrl::getOriginalProtocol() for the fallback decisions below, which need to know the actual scheme regardless of that flag. * HttpClient: fix HTTP/3 clients constructed against a non-QUIC endpoint (e.g. mediadb::Client(url, ..., /*http3=*/true) against a plain HTTP server) always failing outright instead of falling back to HTTP/1.1. tryHttp3First() correctly detected and cached the QUIC failure, but the ctor's own fallback-strategy check (getProtocol() == HTTPS, meant to tell "try HTTP/2 next" apart from "go cleartext") could never see HTTPS once http3=true had pinned that field to HTTP3, so cleartext targets always fell into the cleartext branch and called resetConnection() -- which re-derived the transport from that same permanently-HTTP3 field and re-entered the QUIC branch a second time. That second attempt runs quic::connect() in blocking mode with no surrounding try/catch, so it blocks for the full 5s handshake timeout and then throws instead of falling back, surfacing on every request as "HttpClient ctor connect failed: quic::completeHandshake: handshake timed out". resetConnection() and reconnect() now only take the QUIC branch when _vers == 3 (HTTP/3 is still what's wanted, not a downgraded fallback attempt), and choose between TLS and plain TCP based on the URL's original scheme instead of the pinned field. -- Jan Koester <jan.koester@tuxist.de> Sat, 18 Jul 2026 14:50:00 +0200 libhttppp (20260707+10) unstable; urgency=medium * HttpEvent::_resumeH2Streams: on a genuine upstream stall (emptyCount > 500) with the response short of the advertised Content-Length, send RST_STREAM(INTERNAL_ERROR) instead of END_STREAM. Ending the stream normally made the client accept the truncated body as a complete response (e.g. a corrupted image); aborting the stream now surfaces the failed transfer instead. -- Jan Koester <jan.koester@tuxist.de> Tue, 07 Jul 2026 12:11:54 +0200 libhttppp (20260704+9) unstable; urgency=high * HttpClient::GetStream: fix unbounded blocking while reading response headers — each call to the header-read loop restarted a fresh 10s timeout on every partial chunk, so a peer trickling a byte every few seconds could hold the loop (and the calling thread) open indefinitely. Now uses a single 10s deadline for the whole header, throwing HTTPException on expiry instead of resetting the clock per chunk. * HttpEvent::_resumeH2Streams: fix HTTP/2 streaming responses (video, large previews) spinning forever instead of failing when the upstream stalls. The stall counter (emptyCount, capped at 500) was reset to 0 every time by checking ss->tempreq's own ResponsePending flag — but tempreq is a synthetic per-stream request with no external writer of that flag; it was actually being set, on every empty read, by the app-level ResponseEvent handler we had just called (a "rearm me for a real connection" signal, not a "new data arrived" signal), so the check always read true and the counter could never advance. Combined with the epoll layer re-arming EPOLLOUT every such cycle (always ready, since nothing is being written), a stalled upstream produced an unconditional, zero-backoff CPU spin with no progress on the stream. emptyCount now increments unconditionally on empty reads, so the existing 500-attempt cap actually terminates a genuinely stalled stream with END_STREAM instead of hanging. -- Jan Koester <jan.koester@tuxist.de> Sat, 04 Jul 2026 06:02:49 +0200 libhttppp (20260629+8) unstable; urgency=medium * HTTPException: derive from std::exception and change what() to the standard "const char* noexcept" signature instead of returning a "const std::string&". Callers catching libhttppp::HTTPException by a generic "catch(std::exception&)" now work correctly, and the httpform, httpauth and httpclient examples were updated to use the new signature (httpauth/httpclient now catch std::exception instead of HTTPException so unrelated std:: exceptions are no longer left uncaught). * HttpClient: when an HTTP/3 connection attempt fails, probe HTTP/2 via ALPN before falling back to HTTP/1.1 instead of dropping straight to HTTP/1.1. If that HTTP/2 probe also fails to negotiate "h2", the constructor now throws HTTPException instead of silently retrying the connection over HTTP/1.1, since a silent downgrade masked negotiation failures that should be surfaced to the caller. -- Jan Koester <jan.koester@tuxist.de> Mon, 29 Jun 2026 12:00:00 +0200 libhttppp (20260605+7) unstable; urgency=medium * HttpD: decode HTTP/1.1 chunked request bodies on the server side. Reverse proxies such as Traefik downgrade HTTP/2 POSTs to HTTP/1.1 using Transfer-Encoding: chunked (no Content-Length); the server loop now de-chunks the body before dispatching RequestEvent and rewrites the Content-Length header, fixing form submissions that were forwarded with raw chunk framing and could not be parsed by the backend. -- Jan Koester <jan.koester@tuxist.de> Fri, 05 Jun 2026 12:00:00 +0200 libhttppp (20260521+6) unstable; urgency=medium * HttpD: add reloadCertificates() for runtime TLS certificate hot-reload Loading
debian/.debhelper/generated/libhttppp1/dh_installchangelogs.dch.trimmed +148 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes
debian/.debhelper/generated/libhttppp1/installed-by-dh_install +1 −1 Changes for debian/.debhelper/generated/libhttppp1/installed-by-dh_install: 1 added line, 1 removed line. Original line number Diff line number Diff line debian/tmp/usr/lib/x86_64-linux-gnu/libhttppp.so.1 debian/tmp/usr/lib/x86_64-linux-gnu/libhttppp.so.1.0.0 debian/tmp/usr/lib/x86_64-linux-gnu/libhttppp.so.1.0.1
debian/.debhelper/generated/libhttppp1/triggers +1 −1 Changes for debian/.debhelper/generated/libhttppp1/triggers: 1 added line, 1 removed line. Original line number Diff line number Diff line # Triggers added by dh_makeshlibs/13.31~bpo13+1 # Triggers added by dh_makeshlibs/13.24.2 activate-noawait ldconfig