From 2a2cfe2626540664b2a4115c6a6f4177a49dbbbc Mon Sep 17 00:00:00 2001 From: mmmray <142015632+mmmray@users.noreply.github.com> Date: Tue, 18 Jun 2024 08:48:02 +0200 Subject: [PATCH] splithttp updates --- docs/config/transports/splithttp.md | 55 +------------------------- docs/en/config/transports/splithttp.md | 50 ++++++++++++++++++++++- 2 files changed, 49 insertions(+), 56 deletions(-) diff --git a/docs/config/transports/splithttp.md b/docs/config/transports/splithttp.md index e333d76c4..e9bcca490 100644 --- a/docs/config/transports/splithttp.md +++ b/docs/config/transports/splithttp.md @@ -1,56 +1,3 @@ # SplitHTTP -::: tip -Help me I don't know chinese. -::: - -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 are still some requirements: - -- The CDN must support HTTP chunked transfer encoding in a streaming fashion, - no response buffering. The transport will send the `X-Accel-Buffering: no` - response header, but only some CDNs respect this. - - If the connection hangs, most likely this part does not work. - -- The CDN must disable caching, or caching should include the query string in cache key. - -Download performance should be similar to WebSocket, but upload is limited. - -Like WebSocket transport, SplitHTTP parses the `X-Forwarded-For` header for logging. - -## SplitHttpObject - -The `SplitHttpObject` corresponds to the `splithttpSettings` section under transport configurations. - -```json -{ - "path": "/", - "host": "xray.com", - "headers": { - "key": "value" - } -} -``` - -> `path`: string - -HTTP path used by the connection. Defaults to `"/"`. - -> `host`: string - -HTTP Host sent by the connection. Empty by default. If this value is empty on the server, the host header sent by clients will not be validated. - -If the `Host` header has been defined on the server in any way, the server will validate if the `Host` header matches. - -The current priority of the `Host` header sent by clients: `host` > `headers` > `address` - -> `headers`: map \{string: string\} - -Customized HTTP headers defined in key-value pairs. Defaults to empty. - -## Known issues - -ALPN negotiation is currently not correctly implemented. HTTPS connections -always assume HTTP/2 prior knowledge. +TODO diff --git a/docs/en/config/transports/splithttp.md b/docs/en/config/transports/splithttp.md index e4ecee761..ff02de63e 100644 --- a/docs/en/config/transports/splithttp.md +++ b/docs/en/config/transports/splithttp.md @@ -46,7 +46,53 @@ The current priority of the `Host` header sent by clients: `host` > `headers` > Customized HTTP headers defined in key-value pairs. Defaults to empty. +> `maxUploadSize` + +The largest possible chunk to upload. Defaults to 1 MB. This should be less +than the max request body size your CDN allows. Decrease this if the client +prints HTTP 413 errors. Increase this to improve upload bandwidth. + +> `maxConcurrentUploads` + +The number of concurrent uploads to run. Defaults to 10. Connections are reused +wherever possible, but you may want to lower this value if the connection is +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. + ## Known issues -ALPN negotiation is currently not correctly implemented. HTTPS connections -always assume HTTP/2 prior knowledge. +* ALPN negotiation is currently not correctly implemented. HTTPS connections + always assume HTTP/2 prior knowledge. + +## Protocol details + +See [PR](https://github.com/XTLS/Xray-core/pull/3412) for extensive discussion +and revision of the protocol. Here is a summary, and the minimum needed to be +compatible: + +1. `GET /?session=UUID` starts a new "virtual" stream connection. 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. + +2. Once the client has read all of this, it can start uploading using `POST + /?session=UUID?seq=0`. `seq` can be used like TCP seq number, and multiple + "packets" may be sent concurrently. The server has to reassemble the + "packets" live. The sequence number never resets for simplicity reasons. + +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. + +Recommendations: + +* Do not assume any custom headers are transferred correctly by the CDN. This + transport is built for CDN who do not support WebSocket, these CDN tend to + not be very modern (or good). + +* It should be assumed there is no streaming upload within a HTTP request, so + the size of a packet should be chosen to optimize between latency, + throughput, and any size limits imposed by the CDN (just like TCP, nagle's + algorithm and MTU...)