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

 -- Jan Koester <jan.koester@tuxist.de>  Wed, 21 May 2026 12:00:00 +0200

libhttppp (20260515+5) unstable; urgency=medium

  * Rebuild

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 15 May 2026 12:00:00 +0200

libhttppp (20260514+4) unstable; urgency=medium

  * HttpD: improve "invalid certfile" error message — include certificate CN
    and system_time for diagnosing clock skew in containers

 -- Jan Koester <jan.koester@tuxist.de>  Wed, 14 May 2026 14:00:00 +0200

libhttppp (20260505+3) unstable; urgency=medium

  * HttpClient: add null guard for _cltsock in _recvNonBlocking() to
    prevent SIGSEGV when readBodyChunkNonBlocking() is called on a
    client whose socket has been closed or was never connected

 -- Jan Koester <jan.koester@tuxist.de>  Mon, 05 May 2026 17:30:00 +0200

libhttppp (20260505+2) unstable; urgency=high

  * Rebuild against libnetplus 20260505+12 (fixes crash "free(): invalid
    pointer" in quic::~quic() — child connections double-closing parent
    socket fd; flow control double-counting; stream resurrection;
    sendStreamData silent data loss; uni-stream dispatch with incomplete
    data; FIN-only frame not sent on wire)

 -- Jan Koester <jan.koester@tuxist.de>  Mon, 05 May 2026 16:30:00 +0200

libhttppp (20260502+1) unstable; urgency=medium

  * Rebuild against libnetplus 20260502+1 (QUIC performance improvements)

 -- Jan Koester <jan.koester@tuxist.de>  Sat, 02 May 2026 12:00:00 +0200

libhttppp (20260424+9) unstable; urgency=medium

  * Flush H2 SendData after each stream dispatch to prevent serialised
    preview responses from timing out on multiplexed connections

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 24 Apr 2026 00:00:00 +0200

libhttppp (20260423+8) unstable; urgency=medium

  * Add missing #include <netplus/crypto/tls.h> for TlsSessionCache

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 23 Apr 2026 00:00:00 +0200

libhttppp (20260410+7) unstable; urgency=medium

  * Use CertificateBundle::loadFromFile() for automatic PEM/DER/P12 detection
  * Add optional sslpassword parameter to HttpD constructor for PKCS#12 support

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 10 Apr 2026 00:00:00 +0200

libhttppp (20260409+6) unstable; urgency=medium

  * Rebuild against libnetplus 20260409+14 (BLOCKSIZE 65536)

 -- Jan Koester <jan.koester@tuxist.de>  Wed, 09 Apr 2026 00:00:00 +0200

libhttppp (20260409+5) unstable; urgency=medium

  * Add getHost() method to HttpRequest (reads host / :authority header)

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 09 Apr 2026 00:00:00 +0200

libhttppp (20260408+4) unstable; urgency=medium

  * New release

 -- Jan Koester <jan.koester@tuxist.de>  Wed, 08 Apr 2026 00:00:00 +0200

libhttppp (20260407+3) unstable; urgency=medium

  * New release

 -- Jan Koester <jan.koester@tuxist.de>  Tue, 07 Apr 2026 00:00:00 +0200

libhttppp (20260404+2) unstable; urgency=medium

  * Remove all debug std::cerr logging from Http2RequestEvent/ResponseEvent
    to eliminate data races on _ZSt4cerr across worker threads

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 00:00:00 +0000

libhttppp (20260404+1) unstable; urgency=medium

  * Add streaming body callbacks: onH2StreamHeaders, onH3StreamHeaders,
    onH2DataChunk, onH3DataChunk for incremental body processing
  * Add sendH2StreamResponse / sendH3StreamResponse helpers
  * H2 DATA frames routed to onH2DataChunk when streaming=true
  * H3 incremental frame parsing with onH3DataChunk support

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 00:00:00 +0200

libhttppp (20260404) unstable; urgency=medium

  * Make RequestEvent/ResponseEvent/ConnectEvent/DisconnectEvent(con&)
    virtual in HttpEvent to allow subclass overrides

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 00:00:00 +0200

libhttppp (20260401) unstable; urgency=medium

  * Initial Debian packaging with multiarch support.

 -- Jan Koester <jan.koester@tuxist.de>  Wed, 01 Apr 2026 00:00:00 +0200
