Update SplitHTTP documentation (#541)

This commit is contained in:
mmmray 2024-07-27 20:01:08 +02:00 committed by GitHub
parent 4a939eb328
commit be053a14b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -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
<Badge text="v1.8.17+" type="warning"/>
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 /<UUID>` 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 /<UUID>` 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 /<UUID>/<seq>`. `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
<Badge text="v1.8.17+" type="warning"/>
If uTLS is not enough, SplitHTTP's TLS can be handled by a browser using [Browser Dialer](../features/browser_dialer.md)