Commit 0fd376c4 authored by Jan Koester's avatar Jan Koester
Browse files

te

parent dd0f6eb5
Loading
Loading
Loading
Loading
+12 −20
Changes for src/http/HttpProxyServer.cpp: 12 added lines, 20 removed lines.
Original line number Diff line number Diff line
@@ -117,14 +117,16 @@ HttpProxyController::HttpProxyController(std::vector<netplus::socket *> serverSo
                                          http::UpstreamConnectionPool &connectionPool,
                                          tls::AcmeChallengeStore *acmeChallenges,
                                          int idleTimeoutSeconds)
    // Keep H2 dispatch disabled for now. Enabling libhttppp's H2 offload pool in the deployed
    // stack makes an otherwise healthy proxied response remain queued after RequestEvent
    // returns, while synchronous H2 lets a frontend request burst occupy every listener worker
    // and prevents even new TLS handshakes. The constructor body therefore also removes h2
    // from TLS ALPN instead of merely leaving these requests synchronous. Clients use the
    // independently-offloaded H1 path initially and can still discover/use H3 via Alt-Svc.
    // H2 dispatch now runs through the same offload pool as H1 (see shouldOffloadH2Dispatch
    // below): both RequestEvent calls do real backend I/O, so both need off the shared
    // epoll/kqueue listener workers to avoid one bursty connection starving new TLS
    // handshakes. This was unsafe before libhttppp's H2 offload lambda gained its own
    // try/catch around RequestEvent (see httpd.cpp's _dispatchH2Stream) -- without it, a
    // backend exception left the stream queued forever with no HEADERS/DATA/RST_STREAM ever
    // sent. ALPN is left at HttpEvent's own default (prefer h2, fall back to http/1.1) below;
    // H3 stays independent via QUIC/Alt-Svc regardless.
    : libhttppp::HttpEvent(serverSockets, /*timeout=*/1000,
                            /*h2OffloadThreads=*/0,
                            /*h2OffloadThreads=*/(std::max<size_t>)(4, std::thread::hardware_concurrency() * 2),
                            idleTimeoutSeconds,
                            /*h1OffloadThreads=*/(std::max<size_t>)(4, std::thread::hardware_concurrency() * 2))
    , _listenerLabel(std::move(listenerLabel))
@@ -135,20 +137,10 @@ HttpProxyController::HttpProxyController(std::vector<netplus::socket *> serverSo
    , _loadBalancer(loadBalancer)
    , _connectionPool(connectionPool)
    , _acmeChallenges(acmeChallenges) {
    // HttpEvent advertises h2 by default on every TLS-over-TCP listener. Do not advertise a
    // protocol whose dispatch mode is intentionally disabled above: browsers otherwise choose
    // h2 and can starve the shared listener workers before their WebSocket connection is even
    // accepted. QUIC sockets are separate and retain their h3 ALPN configuration.
    for (auto *sock : serverSockets) {
        if (auto *tlsSock = dynamic_cast<netplus::ssl *>(sock)) {
            tlsSock->setAlpnSelectCallback([](const std::vector<std::string> &protocols) {
                for (const auto &protocol : protocols) {
                    if (protocol == "http/1.1") return protocol;
                }
                return std::string{};
            });
        }
}

bool HttpProxyController::shouldOffloadH2Dispatch(libhttppp::HttpRequest &, uint32_t) const {
    return true;
}

bool HttpProxyController::tryServeAcmeChallenge(libhttppp::HttpRequest &curreq,
+7 −0
Changes for src/http/HttpProxyServer.h: 7 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -56,6 +56,13 @@ public:
        return true;
    }

    // H2 analogue of the above: every route here does a real backend round-trip, so H2
    // streams need the same offload as H1 to avoid a bursty multiplexed connection
    // occupying every shared listener worker. Safe now that libhttppp's H2 offload lambda
    // has its own try/catch around RequestEvent (see httpd.cpp's _dispatchH2Stream) -- before
    // that fix, a backend exception left the stream queued forever with no response ever sent.
    bool shouldOffloadH2Dispatch(libhttppp::HttpRequest &, uint32_t) const override;

private:
    struct AuthOutcome {
        bool authenticated = false;