H2 (HTTP/2) & H2C over Cloudflare CDN
Hi, I tried pass VLESS H2 & H2C over Cloudflare and failed, Is it limit of xray-core or my mistake? If you was able to do this please share your Inbound Thank you.
我的client会输出如下日志:
[Warning] [2211278889] transport/internet/http: failed to dial to tcp:some_domain:443 > Put "https://some_domain:443/path_xx": http2: Transport: cannot retry err [stream error: stream ID 35; PROTOCOL_ERROR; received from peer] after Request.Body was written; define Request.GetBody to avoid this error
我的client和server配置是参考 https://github.com/XTLS/Xray-examples/tree/main/VLESS-H2C-Caddy2 进行配置的
It is recommended to use gRPC instead of H2 if you want to pass VLESS through Cloudflare CDN. (Remember to turn on the switch in Cloudflare dashboard)
It seems something happens in Cloudflare when using H2 to do that, like the HTTP requests being repacked which may introduce some new inconsistency. Unlike gRPC and WebSocket which Cloudflare CDN treats them as stream requests and doesn't repack anything.
Or you can try tweak the HTTP method and some headers in the Xray-core config to try some lucks. Make sure the "HTTP/2 to origin server" is switched on in Cloudflare dashboard.
That is weird, Does repacking corrupt data?
No, no data is corrupted, but the mess in behaviors. The repacking can be seems as the "request reordering", because the CDN will try to cache some resources and request data for accelerating the browsing, unless you tell the CDN not to cache them.
If the CDN is told "this is a stream request" like using WebSocket (which should be deprecated in our use case) or gRPC, the CDN will just stream the request between the client and the source server without caching or reordering the requests.
Otherwise you'll have to setup the CDN explicitly not to cache some kinds of requests, or add some headers in the client/server requests/responds to indicate the CDN do not cache them but stream them.
And there is a extra problem: if CDN not configured properly and it tries to stream the request back to origin server, it may use HTTP/1.1 instead of HTTP/2 to talk with the origin server that only accept HTTP/2, thus breaking the connection because of the protocol mismatch. H2C is a rare case and not supported by most CDNs.
I tried to dig some old cases
This is the one in 2019: v2ray/v2ray-core/issues/1945
And this is the one in 2019 and still discussed recently: v2ray/v2ray-core/issues/1769 v2ray/v2ray-core/issues/1769