chore: async xhttp RoundTrip to let some CDN/reverse proxy happy#2719
Merged
Conversation
…verse proxy The xhttp client's DialStreamOne, DialStreamUp, and DialPacketUp methods called transport.RoundTrip() synchronously, blocking until the full HTTP response headers were received. This caused a deadlock when behind CDNs (e.g. Cloudflare, CloudFront) or reverse proxies (e.g. Nginx) that buffer response headers until the origin server sends actual body data: 1. mihomo client waits for HTTP response headers from CDN 2. CDN waits for origin server to send response body 3. Origin server (Xray) waits for client to send VLESS handshake in the request body 4. Request body can't be written because conn hasn't been returned to the caller yet >> deadlock until timeout Fix: move RoundTrip into a background goroutine and use httptrace.GotConn to detect TCP connection establishment. Return the conn immediately once TCP is connected, using a new WaitReadCloser type to defer response body reading until the first Read() call. This matches the async pattern used by Xray-core's splithttp client implementation. Fixes MetaCubeX#2709
|
#2695 |
Author
|
#2695 问题的RTT就是没有异步等待导致的,但是还有一个30ms的首包等待我不敢乱动怕导致特征,希望有经验的人来看一下qwq |
|
引入异步就不出意外的爆了😂 |
Author
|
确实爆了,在debug,可能是stream-one那里其实应该是要等一下才对的 |
…th async download When download GET is async, upload POST may arrive at the server before GET creates the session. Using getSession (lookup-only) returns nil and responds 400. Switch to getOrCreateSession to allow either request to create the session on-demand, matching Xray-core's upsertSession behavior.
Author
|
@daiaji 麻烦再review一下,是异步导致服务端收到了预期之外的POST, |
也没啥别的办法,只能说在actions跑个全平台的测试了。😂 各个平台都有自己的XP是这样的。 要不等主理人来看看吧。 |
|
Win的小巧思这一块😂 |
Collaborator
|
改服务端倒是也可以,但是需要在 |
Author
在改了,马上commit |
Collaborator
|
你的 |
Author
|
没问题了合了? |
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix xhttp client deadlock when connecting through CDNs (Cloudflare, CloudFront) or reverse proxies (Nginx).
Fixes #2709
Problem
DialStreamOne,DialStreamUp, andDialPacketUpcalltransport.RoundTrip()synchronously, blocking until HTTP response headers arrive. Behind CDN/reverse proxy with response header buffering, this creates a 4-way deadlock:Result: connection hangs until timeout. Xray-core work because it use async patterns.
Fix
Move
RoundTripinto background goroutines, usehttptrace.GotConnto detect TCP establishment, and return conn immediately. A newWaitReadClosertype defers response body reading to the firstRead()call — matching Xray-core'ssplithttpasync approach.Testing
Built and tested locally against a real CloudFront + Xray-core server with
packet-upmode