Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

HTTP/2 to origin: GOAWAY closes the session at once and aborts streams at or below last_stream_id

已关闭
#13,779 0 条评论 0 个 reaction 已指派 1 人 在 GitHub 查看

维护者通常 2 天内回复

@bneradt 已经在做这个了。

开始于 2026年10月1日。

评估

这个 Issue 还没有评估数据。

描述

HTTP/2

Summary

When an HTTP/2 origin sends GOAWAY, ATS closes the session immediately. That aborts every stream at or below last_stream_id, even though RFC 9113 §6.8 says the peer may still finish them. Graceful drains (GOAWAY NO_ERROR with last_stream_id 2^31-1, or a real last id) therefore fail every request in flight on the connection. Requests with non-idempotent methods aren't retried, so each one goes to the client as 502 with ERR_CONNECT_FAIL.

Cause

Http2ConnectionState::rcv_goaway_frame on master:

this->rx_error_code = {ProxyErrorClass::SSN, static_cast<uint32_t>(goaway.error_code)};
this->session->get_proxy_session()->do_io_close();
  1. Every stream gets EOS from Http2Stream::initiating_close.
  2. For a stream still waiting for its response header, HttpSM::state_read_server_response_header handles VC_EVENT_EOS by going to handle_server_setup_error, then handle_post_failure when a request body is in flight.
  3. The state ends up CONNECTION_CLOSED. HttpTransact::is_request_retryable refuses to retry a non-idempotent method once server_request_hdr_bytes > 0, so the client gets a 502.

HTTP/1.1 has no equivalent drain signal, so an HTTP/1.1 POST hit by an abrupt close fails the same way. What's specific to HTTP/2 is that the origin announces it will finish these streams, and ATS throws them away.

Observed

On a 10.0.x build with HTTP/2 to origin enabled. rcv_goaway_frame closes the same way on master.

  • 502 ERR_CONNECT_FAIL with origin status 000 and zero retries, almost only on POST, PROPFIND, PUT, REPORT and DELETE.
  • It comes in bursts: 183 requests across several origin sessions ended within the same 100 ms, while other sessions to the same origin kept returning 200.
  • proxy.process.http2.session_die_default tracks proxy.process.http2.goaway_frames_in almost one-for-one (1,469 / 1,468 on one host). Both counters include client sessions as well as origin sessions.
  • Over HTTP/2 the sessions are long-lived and heavily multiplexed (thousands of transactions per session), so one drain fails dozens of requests at once.
  • A build without HTTP/2 session reuse in the same site and window, where each connection carried only a few requests, had 0 failures where about 5 were expected.

We haven't yet confirmed from a packet capture that every burst was a GOAWAY rather than a TCP close, but the handler behaves as described whichever it was.

Suggested fix

On GOAWAY from an origin:

  1. Mark the session as draining and take it out of the session pool, so no new streams go on it.
  2. Reset streams with id > last_stream_id and make them retryable (they were never processed).
  3. Let streams at or below last_stream_id run to completion, and close the session once the active stream count reaches 0 or a drain timeout passes.

The inbound (client) GOAWAY path could follow the same approach.

Related, and may be worth its own issue: ATS keeps opening new streams on an origin session that has answered nothing for many seconds. In the bursts above, sessions silent for about 16 s were still taking new streams until about 300 ms before they closed. A PING-based liveness check would limit how many requests one stalled session can take down.

主要语言
C++
星标
2k
派生
878
平均合并
3 天 16 小时
30 天内合并 PR
95

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

apache/trafficserver 的其他 Issue

查看 apache/trafficserver 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。