diff --git a/docs/en/config/transports/splithttp.md b/docs/en/config/transports/splithttp.md
index 8da83dbfd..a94c1fefb 100644
--- a/docs/en/config/transports/splithttp.md
+++ b/docs/en/config/transports/splithttp.md
@@ -4,12 +4,9 @@
Uses HTTP chunked-transfer encoding for download, and multiple HTTP requests for upload.
-Can be deployed on CDNs that do not support WebSocket, but there is still one requirement:
-
-**The CDN must support HTTP chunked transfer encoding in a streaming fashion**,
-no response buffering. The transport will send the `X-Accel-Buffering: no` and
-`Content-Type: text/event-stream` response headers, but only some CDNs respect this.
-If the connection hangs, most likely this part does not work.
+Can be deployed on CDNs that do not support WebSocket. However, **the CDN must
+support HTTP chunked transfer encoding in a streaming fashion**, no response
+buffering.
This transport serves the same purpose as Meek (support non-WS CDN). It has the
above streaming requirement to the CDN so that download can be much faster than
@@ -65,6 +62,42 @@ unstable, or if the server is using too much memory.
The value on the client must not be higher than on the server. Otherwise,
connectivity issues will occur.
+## HTTP versions
+
+*Added in 1.8.21: HTTP/3 support*
+
+SplitHTTP supports `http/1.1`, `h2` and `h3` ALPN values. If the value is not
+set, `h2` (prior-knowledge) is assumed when TLS is enabled, and `http/1.1`
+without TLS. If the value is set to `h3`, the client will attempt to connect as
+HTTP/3, so UDP instead of TCP.
+
+The server listens to HTTP/1.1 and h2 by default, but if `h3` ALPN is set on
+the server, it will listen as HTTP/3.
+
+Please note that nginx, Caddy and all CDN will almost certainly translate
+client requests to a different HTTP version for forwarding, and so the server
+may have to be configured with a different ALPN value than the client. If you
+use a CDN, it is very unlikely that `h3` is a correct value for the server,
+even if the client speaks `h3`.
+
+## Troubleshooting
+
+* If a connection hangs, the CDN may not support streaming downloads. You can
+ use `curl -Nv https://example.com/abcdef` to initiate a download and see for
+ yourself (see protocol details).
+
+ If you do not see `200 OK` and a response body of `ok`, then the CDN is
+ buffering the response body. Please ensure that all HTTP middleboxes along
+ the path between client and server observe `X-Accel-Buffering: no` from their
+ origin server. If your chain is `xray -> nginx -> CDN -> xray`, nginx may
+ strip this response header and you have to re-add it.
+
+## Browser Dialer
+
+
+
+If uTLS is not enough, SplitHTTP's TLS can be handled by a browser using [Browser Dialer](../features/browser_dialer.md)
+
## Protocol details
See [#3412](https://github.com/XTLS/Xray-core/pull/3412) and
@@ -72,9 +105,14 @@ See [#3412](https://github.com/XTLS/Xray-core/pull/3412) and
and revision of the protocol. Here is a summary, and the minimum needed to be
compatible:
-1. `GET /` opens the download. The server immediately responds
- with `200 OK` and `Transfer-Encoding: chunked`, and immediately sends a
- two-byte payload to force HTTP middleboxes into flushing headers.
+1. `GET /` opens the download. The server immediately responds with `200
+ OK`, and immediately sends the string `ok`
+ (arbitrary length, such as `ooook`) to force HTTP middleboxes into flushing
+ headers.
+
+ The server will send the `X-Accel-Buffering: no` and `Content-Type:
+ text/event-stream` headers to force CDN into not buffering the response
+ body. In HTTP/1.1 it may also send `Transfer-Encoding: chunked`.
2. Client uploads using `POST //`. `seq` starts at `0` and can be
used like TCP seq number, and multiple "packets" may be sent concurrently.
@@ -86,8 +124,11 @@ compatible:
hardcoded to 30 seconds) If not, the session will be terminated.
3. The `GET` request is kept open until the tunneled connection has to be
- terminated. Either server or client can close. How this actually works
- depends on the HTTP version.
+ terminated. Either server or client can close.
+
+ How this actually works depends on the HTTP version. For example, in
+ HTTP/1.1 it is only possible to disrupt chunked-transfer by closing the TCP
+ connection, in other versions the stream is closed or aborted.
Recommendations:
@@ -103,16 +144,3 @@ Recommendations:
* HTTP/1.1 and h2 should be supported by server and client, and it should be
expected that the CDN will translate arbitrarily between versions. A HTTP/1.1
server may indirectly end up talking to a h2 client, and vice versa.
-
- In order to keep the implementation simple, SplitHTTP client in Xray assumes
- h2 prior knowledge if TLS is enabled. You can also manually specify ALPN as
- `http/1.1` or `h3` to initiate requests using the corresponding HTTP version.
-
- The SplitHTTP server in Xray supports all common combinations as expected:
- HTTP/1.1 with or without TLS, h2 and h2c, however no h3.
-
-## Browser Dialer
-
-
-
-If uTLS is not enough, SplitHTTP's TLS can be handled by a browser using [Browser Dialer](../features/browser_dialer.md)