mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2026-10-11 08:48:14 +03:00
XHTTP: Beyond REALITY
https://github.com/XTLS/Xray-core/discussions/4113
This commit is contained in:
@@ -14,7 +14,7 @@ However, there are many drawbacks:
|
||||
|
||||
* The user has to launch a browser next to the Xray client just for opening the proxy connection.
|
||||
* The browser dialer must not be tunneled through the proxy itself, otherwise there is a loop. TUN users should be cautious.
|
||||
* The browser can only speak standard HTTP, which means that only [WebSocket](../../transports/websocket.md) and [XHTTP](../../transports/splithttp.md) are supported
|
||||
* The browser can only speak standard HTTP, which means that only [WebSocket](../../transports/websocket.md) and [XHTTP](https://github.com/XTLS/Xray-core/discussions/4113) are supported
|
||||
* [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) needs to be considered when making requests from one website (`localhost:8080`) to another (`proxy.example.com:443`)
|
||||
* The browser tunnels your traffic using JavaScript, so there is a significant performance penalty (or, battery drain)
|
||||
* The configuration to be used with browser dialer cannot use custom SNI or host headers. `SNI == host == address`. Custom HTTP headers and `tlsSettings` are ignored entirely.
|
||||
@@ -48,6 +48,6 @@ According to the browser's needs, the early data mechanism has been adjusted as
|
||||
|
||||
<Badge text="v1.8.19+" type="warning"/>
|
||||
|
||||
XHTTP supports QUIC, but the browser's own QUIC stack may be used as well. In Chrome this can be done through `chrome://flags`, in other browsers it may already be enabled or need a different flag.
|
||||
[XHTTP](https://github.com/XTLS/Xray-core/discussions/4113) supports QUIC, but the browser's own QUIC stack may be used as well. In Chrome this can be done through `chrome://flags`, in other browsers it may already be enabled or need a different flag.
|
||||
|
||||
In general, `tlsSettings` are completely ignored when Browser Dialer is used. Xray does not have any control over which HTTP version the browser selects.
|
||||
|
||||
+22
-23
@@ -10,17 +10,16 @@ Transports specify how to achieve stable data transmission. Both ends of a conne
|
||||
|
||||
```json
|
||||
{
|
||||
"network": "tcp",
|
||||
"network": "raw",
|
||||
"security": "none",
|
||||
"tlsSettings": {},
|
||||
"realitySettings": {},
|
||||
"tcpSettings": {},
|
||||
"kcpSettings": {},
|
||||
"wsSettings": {},
|
||||
"httpSettings": {},
|
||||
"grpcSettings": {},
|
||||
"httpupgradeSettings": {},
|
||||
"rawSettings": {},
|
||||
"xhttpSettings": {},
|
||||
"kcpSettings": {},
|
||||
"grpcSettings": {},
|
||||
"wsSettings": {},
|
||||
"httpupgradeSettings": {},
|
||||
"sockopt": {
|
||||
"mark": 0,
|
||||
"tcpMaxSeg": 1440,
|
||||
@@ -42,9 +41,13 @@ Transports specify how to achieve stable data transmission. Both ends of a conne
|
||||
}
|
||||
```
|
||||
|
||||
> `network`: "tcp" | "kcp" | "ws" | "http" | "grpc" | "httpupgrade" | "xhttp"
|
||||
> `network`: "raw" | "xhttp" | "kcp" | "grpc" | "ws" | "httpupgrade"
|
||||
|
||||
The underlying protocol of the transport used by the data stream of the connection, defaulting to `"tcp"`.
|
||||
The underlying protocol of the transport used by the data stream of the connection, defaulting to `"raw"`.
|
||||
|
||||
::: tip
|
||||
After v24.9.30, the TCP transport has been renamed to RAW to more closely match actual behavior. `"network": "raw"` and `"network": "tcp"`, `rawSettings` and `tcpSettings` are aliases for each other for compatibility.
|
||||
:::
|
||||
|
||||
> `security`: "none" | "tls" | "reality"
|
||||
|
||||
@@ -66,34 +69,30 @@ Configures REALITY. REALITY is a piece of advanced encryption technology develop
|
||||
REALITY is by far the most secure transport encryption solution, perfectly mimicking normal web browsing when observed. Enabling REALITY with appropriate XTLS Vision flow control schemes has the potential of reaching magnitudes of performance boosts.
|
||||
:::
|
||||
|
||||
> `tcpSettings`: [TcpObject](./transports/tcp.md)
|
||||
> `rawSettings`: [RawObject](./transports/raw.md)
|
||||
|
||||
Configures the current TCP connection. Valid only when TCP is used. Same schema as global.
|
||||
Configures the current RAW connection. Valid only when RAW is used. Same schema as global.
|
||||
|
||||
> `xhttpSettings`: [XHTTP: Beyond REALITY](https://github.com/XTLS/Xray-core/discussions/4113)
|
||||
|
||||
Configures XHTTP connections. Valid only when XHTTP is used. Same schema as global.
|
||||
|
||||
> `kcpSettings`: [KcpObject](./transports/mkcp.md)
|
||||
|
||||
Configures the current mKCP connection. Valid only when mKCP is used. Same schema as global.
|
||||
|
||||
> `wsSettings`: [WebSocketObject](./transports/websocket.md)
|
||||
|
||||
Configures the current WebSocket connection. Valid only when WebSocket is used. Same schema as global.
|
||||
|
||||
> `httpSettings`: [HttpObject](./transports/h2.md)
|
||||
|
||||
Configures the current HTTP/2 connection. Valid only when HTTP/2 is used. Same schema as global.
|
||||
|
||||
> `grpcSettings`: [GRPCObject](./transports/grpc.md)
|
||||
|
||||
Configures the current gRPC connection. Valid only when gRPC is used. Same schema as global.
|
||||
|
||||
> `wsSettings`: [WebSocketObject](./transports/websocket.md)
|
||||
|
||||
Configures the current WebSocket connection. Valid only when WebSocket is used. Same schema as global.
|
||||
|
||||
> `httpupgradeSettings`: [HttpUpgradeObject](./transports/httpupgrade.md)
|
||||
|
||||
Configures the current HTTPUpgrade connection. Valid only when HTTPUpgrade is used. Same schema as global.
|
||||
|
||||
> `xhttpSettings`: [XHttpObject](./transports/splithttp.md)
|
||||
|
||||
Configures XHTTP connections. Valid only when XHTTP is used. Same schema as global.
|
||||
|
||||
> `sockopt`: [SockoptObject](#sockoptobject)
|
||||
|
||||
Configures transparent proxies.
|
||||
|
||||
@@ -6,6 +6,10 @@ gRPC is based on the HTTP/2 protocol and can theoretically be relayed by other s
|
||||
|
||||
gRPC and HTTP/2 has built-in multiplexing, so it is not recommended to enable `mux.cool` when using gRPC or HTTP/2.
|
||||
|
||||
::: danger
|
||||
**It is recommended to switch to [XHTTP](https://github.com/XTLS/Xray-core/discussions/4113), whose advantages over gRPC are noted in the STREAM-UP/ONE section.**
|
||||
:::
|
||||
|
||||
::: warning ⚠⚠⚠
|
||||
|
||||
- gRPC doesn't support specifying the Host. Please enter the **correct domain name** in the outbound proxy address, or fill in `ServerName` in `(x)tlsSettings`, otherwise connection cannot be established.
|
||||
|
||||
@@ -1,82 +1,3 @@
|
||||
# HTTP/2
|
||||
|
||||
The transmission mode based on HTTP/2 fully implements the HTTP/2 standard and can be relayed by other HTTP servers (such as Nginx).
|
||||
|
||||
Based on the recommendations of HTTP/2, both the client and server must enable TLS to use this transmission mode normally.
|
||||
|
||||
HTTP/2 has built-in multiplexing, so it is not recommended to enable mux.cool when using HTTP/2.
|
||||
|
||||
::: tip
|
||||
The current version of the transmission mode based on HTTP/2 does not require TLS configuration for inbound (server-side).
|
||||
|
||||
This makes it possible to use a plaintext HTTP/2 protocol called h2c for communication between the gateway and Xray, with external gateway components handling the TLS layer conversation in special-purpose load-balancing deployment environments.
|
||||
:::
|
||||
|
||||
::: warning
|
||||
⚠️ If you are using fallback, please note the following:
|
||||
|
||||
- Please make sure that `h2` is included in `(x)tlsSettings.alpn`, otherwise HTTP/2 cannot complete TLS handshake.
|
||||
- HTTP/2 cannot perform path-based routing, so it is recommended to use SNI-based routing.
|
||||
:::
|
||||
|
||||
## HttpObject
|
||||
|
||||
`HttpObject` corresponds to the `httpSettings` in the [Transport Protocol](../transport.md),
|
||||
|
||||
```json
|
||||
{
|
||||
"host": ["xray.com"],
|
||||
"path": "/random/path",
|
||||
"read_idle_timeout": 10,
|
||||
"health_check_timeout": 15,
|
||||
"method": "PUT",
|
||||
"headers": {
|
||||
"Header": ["value"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `host`: \[string\]
|
||||
|
||||
A string array, where each element is a domain name.
|
||||
|
||||
The client will randomly select a domain name from the list for communication, and the server will verify whether the domain name is in the list.
|
||||
|
||||
> `path`: string
|
||||
|
||||
The HTTP path starts with `/` and must be the same value between the client and server.
|
||||
|
||||
The default value is `/`
|
||||
|
||||
> `read_idle_timeout`: number
|
||||
|
||||
The connection health check is performed when no data has been received for a certain period of time, measured in seconds.
|
||||
|
||||
By default, the health check is **disabled**.
|
||||
|
||||
::: tip
|
||||
**Only need to be configured** in **`outbound`** (**client**).
|
||||
:::
|
||||
|
||||
::: tip
|
||||
Enabling health checks may help solve some "connection drop" issues.
|
||||
:::
|
||||
|
||||
> `health_check_timeout`: number
|
||||
|
||||
The timeout for the health check, measured in seconds. If the health check is not completed within this time period, it is considered to have failed.
|
||||
The default value is `15`
|
||||
|
||||
::: tip
|
||||
**Only need to be configured** in `outbound` **(client)**.
|
||||
:::
|
||||
|
||||
> `method`: string
|
||||
|
||||
HTTP request method. The default value is `PUT`
|
||||
|
||||
Please refer this [this](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) when configure.
|
||||
|
||||
> `headers`: map{ string: \[string\] }
|
||||
|
||||
Custom HTTP headers, defined as key-value pairs. Each key represents an HTTP header name and its corresponding value is an array.
|
||||
See [XHTTP: Beyond REALITY](https://github.com/XTLS/Xray-core/discussions/4113)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# HTTP
|
||||
|
||||
See [XHTTP: Beyond REALITY](https://github.com/XTLS/Xray-core/discussions/4113)
|
||||
@@ -4,6 +4,10 @@ A WebSocket-like transport protocol implementing the HTTP/1.1 upgrade and respon
|
||||
|
||||
Standalone usage is not recommended, but rather in conjunction with other security protocols like TLS.
|
||||
|
||||
::: danger
|
||||
**It is recommended to switch to [XHTTP](https://github.com/XTLS/Xray-core/discussions/4113) to avoid significant traffic characteristics such as HTTPUpgrade "ALPN is http/1.1".**
|
||||
:::
|
||||
|
||||
## HttpUpgradeObject
|
||||
|
||||
The `HttpUpgradeObject` corresponds to the `httpupgradeSettings` section under transport configurations.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# QUIC
|
||||
|
||||
See [XHTTP: Beyond REALITY](https://github.com/XTLS/Xray-core/discussions/4113)
|
||||
@@ -0,0 +1,148 @@
|
||||
# RAW
|
||||
|
||||
Renamed from what was once the TCP transport layer (the original name was ambiguous), the outbound RAW transport layer sends TCP and UDP data generated by proxy protocol wrappers directly, and the core doesn't use other transport layers (e.g., [XHTTP](https://github.com/XTLS/Xray-core/discussions/4113)) to carry its traffic.
|
||||
|
||||
It can be combined with various protocols in multiple ways.
|
||||
|
||||
## RawObject
|
||||
|
||||
`RawObject` corresponds to the `rawSettings` item in the Transport Protocol.
|
||||
|
||||
```json
|
||||
{
|
||||
"acceptProxyProtocol": false,
|
||||
"header": {
|
||||
"type": "none"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `acceptProxyProtocol`: true | false
|
||||
|
||||
Only used for inbound, indicating whether to accept the PROXY protocol.
|
||||
|
||||
The [PROXY protocol](https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt) is used to transmit the real source IP and port of the request. **If you are not familiar with it, please ignore this item.**
|
||||
|
||||
Common reverse proxy software (such as HAProxy and Nginx) can be configured to send it, and VLESS fallbacks xver can also send it.
|
||||
|
||||
When filled in as `true`, after the underlying TCP connection is established, the requesting party must first send PROXY protocol v1 or v2, otherwise the connection will be closed.
|
||||
|
||||
The default value is `false`
|
||||
|
||||
> `header`: [NoneHeaderObject](#noneheaderobject) | [HttpHeaderobject](#httpheaderobject)
|
||||
|
||||
Packet header obfuscation settings, the default value is `NoneHeaderObject`
|
||||
|
||||
::: tip
|
||||
HTTP obfuscation cannot be proxied by other HTTP servers (such as Nginx), but it can be proxied by VLESS fallbacks path.
|
||||
:::
|
||||
|
||||
### NoneHeaderObject
|
||||
|
||||
No header obfuscation
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "none"
|
||||
}
|
||||
```
|
||||
|
||||
> `type`: "none"
|
||||
|
||||
Disable header obfuscation.
|
||||
|
||||
### HttpHeaderObject
|
||||
|
||||
HTTP header obfuscation. The configuration must be the same between connecting inbound and outbound.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"request": {},
|
||||
"response": {}
|
||||
}
|
||||
```
|
||||
|
||||
> `type`: "http"
|
||||
|
||||
Enable HTTP header obfuscation.
|
||||
|
||||
> `request`: [HTTPRequestObject](#httprequestobject)
|
||||
|
||||
HTTP request template.
|
||||
|
||||
> `response`: [HTTPResponseObject](#httpresponseobject)
|
||||
|
||||
HTTP response template.
|
||||
|
||||
#### HTTPRequestObject
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.1",
|
||||
"method": "GET",
|
||||
"path": ["/"],
|
||||
"headers": {
|
||||
"Host": ["www.baidu.com", "www.bing.com"],
|
||||
"User-Agent": [
|
||||
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"
|
||||
],
|
||||
"Accept-Encoding": ["gzip, deflate"],
|
||||
"Connection": ["keep-alive"],
|
||||
"Pragma": "no-cache"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `version`: string
|
||||
|
||||
HTTP version, the default value is `"1.1"`
|
||||
|
||||
> `method`: string
|
||||
|
||||
The HTTP method, the default value is `"GET"`
|
||||
|
||||
> `path`: \[ string \]
|
||||
|
||||
paths, an array of strings. The default value is `["/"]`. When there are multiple values, a value is chosen randomly for each request.
|
||||
|
||||
> `headers`: map{ string, \[ string \]}
|
||||
|
||||
HTTP header, a key-value pair, each key represents the name of an HTTP header, and the corresponding value is an array.
|
||||
|
||||
Each request will include all the keys and randomly select a corresponding value. Please refer to the **default values** shown in the example above.
|
||||
|
||||
#### HTTPResponseObject
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.1",
|
||||
"status": "200",
|
||||
"reason": "OK",
|
||||
"headers": {
|
||||
"Content-Type": ["application/octet-stream", "video/mpeg"],
|
||||
"Transfer-Encoding": ["chunked"],
|
||||
"Connection": ["keep-alive"],
|
||||
"Pragma": "no-cache"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `version`: string
|
||||
|
||||
HTTP version, default is `"1.1"`
|
||||
|
||||
> `status`: string
|
||||
|
||||
HTTP status, default is `"200"`
|
||||
|
||||
> `reason`: string
|
||||
|
||||
HTTP status description, default value is `"OK"`
|
||||
|
||||
> `headers`: map {string, \[ string \]}
|
||||
|
||||
HTTP header, a key-value pair, each key represents the name of an HTTP header, and the corresponding value is an array.
|
||||
|
||||
Each request will include all the keys and randomly select a corresponding value. Please refer to the **default values** shown in the example above.
|
||||
@@ -1,234 +1,3 @@
|
||||
# XHTTP (SplitHTTP)
|
||||
# SplitHTTP
|
||||
|
||||
<Badge text="v1.8.16+" type="warning"/>
|
||||
|
||||
Uses HTTP chunked-transfer encoding for download, and multiple HTTP requests for upload.
|
||||
|
||||
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
|
||||
(v2fly) Meek, close to WebSocket performance. The upload is also optimized, but
|
||||
still much more limited than WebSocket.
|
||||
|
||||
Like WebSocket transport, XHTTP parses the `X-Forwarded-For` header for logging.
|
||||
|
||||
## XHttpObject
|
||||
|
||||
The `XHttpObject` corresponds to the `xhttpSettings` section under transport configurations.
|
||||
|
||||
```json
|
||||
{
|
||||
"path": "/",
|
||||
"host": "xray.com",
|
||||
"headers": {
|
||||
"key": "value"
|
||||
},
|
||||
"scMaxEachPostBytes": 1000000,
|
||||
"scMaxConcurrentPosts": 100,
|
||||
"scMinPostsIntervalMs": 30,
|
||||
"noSSEHeader": false,
|
||||
"xPaddingBytes": "100-1000",
|
||||
"xmux": {
|
||||
"maxConcurrency": 0,
|
||||
"maxConnections": 0,
|
||||
"cMaxReuseTimes": 0,
|
||||
"cMaxLifetimeMs": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `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.
|
||||
|
||||
> `scMaxEachPostBytes`: int | string
|
||||
|
||||
The maximum size of upload chunks, in bytes. Defaults to 1MB.
|
||||
|
||||
The size set by the client must be lower than this value, otherwise when the
|
||||
POST request is sent larger than the value set by the server, the request will
|
||||
be rejected.
|
||||
|
||||
This value should be smaller than the maximum request body allowed by the CDN
|
||||
or other HTTP reverse proxy, otherwise an HTTP 413 error will be thrown.
|
||||
|
||||
It can also be in the form of a string `"1000000-2000000"`. The core will
|
||||
randomly select a value within the range each time to reduce fingerprints.
|
||||
|
||||
> `scMaxConcurrentPosts`: int | string
|
||||
|
||||
The number of concurrent uploads to run. Defaults to 100 on the client, and
|
||||
200 on the server.
|
||||
|
||||
The value on the client must not be higher than on the server. Otherwise,
|
||||
connectivity issues will occur. In practice, the upload concurrency is also
|
||||
limited by `minUploadIntervalMs`, so the actual concurrency on the client side
|
||||
will be much lower.
|
||||
|
||||
It can also be in the form of a string `"100-200"`, and the core will randomly
|
||||
select a value within the range each time to reduce fingerprints.
|
||||
|
||||
> `scMinPostsIntervalMs`: int | string
|
||||
|
||||
(Client-only) How much time to pass between upload requests at a minimum.
|
||||
Defaults to `30` (milliseconds).
|
||||
|
||||
It can also be in the form of a string `"10-50"`, and the core will randomly
|
||||
select a value within the range each time to reduce fingerprints.
|
||||
|
||||
> `noSSEHeader`
|
||||
|
||||
(Server-only) Do not send the `Content-Type: text/event-stream` response
|
||||
header. Defaults to false (the header will be sent)
|
||||
|
||||
> `xPaddingBytes`
|
||||
|
||||
*Added in 1.8.24*
|
||||
|
||||
Control the padding of requests and responses. Defaults to `"100-1000"`,
|
||||
meaning that each GET and POST will be padded with a random amount of bytes in
|
||||
that range.
|
||||
|
||||
A value of `-1` disables padding entirely.
|
||||
|
||||
You can lower this to save bandwidth or increase it to improve censorship
|
||||
resistance. Too much padding may cause the CDN to reject traffic.
|
||||
|
||||
> `xmux`: [XmuxObject](#xmuxobject)
|
||||
|
||||
## XmuxObject
|
||||
|
||||
<Badge text="v24.9.19+" type="warning"/>
|
||||
|
||||
Allows users to control the multiplexing behavior in h2 and h3. If not set, the default behavior is to multiplex all requests to one TCP/QUIC connection.
|
||||
|
||||
```json
|
||||
{
|
||||
"maxConcurrency": 0,
|
||||
"maxConnections": 0,
|
||||
"cMaxReuseTimes": 0,
|
||||
"cMaxLifetimeMs": 0
|
||||
}
|
||||
```
|
||||
|
||||
Since the default is unlimited reuse, `xmux` actually limits this. It's not recommended to enable `mux.cool` at the same time.
|
||||
|
||||
Terminology: *Streams* will reuse physical connections, as in, one connection can hold many streams. In other places, streams are called sub-connections, they are the same thing.
|
||||
|
||||
> `maxConcurrency`: int | string
|
||||
|
||||
Default 0 = infinite. The maximum number of streams reused in each connection. After the number of streams in the connection reaches this value, the core will create more connections to accommodate more streams, similar to the concurrency of mux.cool. Mutually exclusive with `maxConnections`.
|
||||
|
||||
> `maxConnections`: int | string
|
||||
|
||||
Default 0 = infinite. The maximum number of connections to open. Every stream will open a new connection until this value is reached, only then connections will be reused. Mutually exclusive with `maxConcurrency`.
|
||||
|
||||
> `cMaxReuseTimes`: int | string
|
||||
|
||||
Default 0 = infinite. A connection can be reused at most several times. When this value is reached, the core will not allocate streams to the connection. It will be disconnected after the last internal stream is closed.
|
||||
|
||||
> `cMaxLifetimeMs`: int | string
|
||||
|
||||
Default 0 = infinite. How long can a connection "survive" at most? When the connection is open for more than this value, the core will not redistribute streams to the connection, and it will be disconnected after the last internal stream is closed.
|
||||
|
||||
## HTTP versions
|
||||
|
||||
*Added in 1.8.21: HTTP/3 support*
|
||||
|
||||
XHTTP 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, XHTTP'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
|
||||
[#3462](https://github.com/XTLS/Xray-core/pull/3462) for extensive discussion
|
||||
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 immediately sends the string `ok`
|
||||
(arbitrary length, such as `ooook`) to force HTTP middleboxes into flushing
|
||||
headers.
|
||||
|
||||
The server will send these headers:
|
||||
|
||||
* `X-Accel-Buffering: no` to prevent response buffering in nginx and CDN
|
||||
* `Content-Type: text/event-stream` to prevent response buffering in some
|
||||
CDN, can be disabled with `noSSEHeader`
|
||||
* `Transfer-Encoding: chunked` in HTTP/1.1 only
|
||||
* `Cache-Control: no-store` to disable any potential response caching.
|
||||
|
||||
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.
|
||||
The server has to reassemble the "packets" live. The sequence number never
|
||||
resets for simplicity reasons.
|
||||
|
||||
The client may open upload and download in any order, either one starts a
|
||||
session. However, eventually `GET` needs to be opened (current deadline is
|
||||
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. 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:
|
||||
|
||||
* 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...)
|
||||
|
||||
* 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.
|
||||
See [XHTTP: Beyond REALITY](https://github.com/XTLS/Xray-core/discussions/4113)
|
||||
|
||||
@@ -1,148 +1,3 @@
|
||||
# TCP
|
||||
|
||||
TCP (Transmission Control Protocol) is currently one of the recommended transport protocols
|
||||
|
||||
It can be combined with various protocols in multiple ways.
|
||||
|
||||
## TcpObject
|
||||
|
||||
`TcpObject` corresponds to the `tcpSettings` item in the Transport Protocol.
|
||||
|
||||
```json
|
||||
{
|
||||
"acceptProxyProtocol": false,
|
||||
"header": {
|
||||
"type": "none"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `acceptProxyProtocol`: true | false
|
||||
|
||||
Only used for inbound, indicating whether to accept the PROXY protocol.
|
||||
|
||||
The [PROXY protocol](https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt) is used to transmit the real source IP and port of the request. **If you are not familiar with it, please ignore this item.**
|
||||
|
||||
Common reverse proxy software (such as HAProxy and Nginx) can be configured to send it, and VLESS fallbacks xver can also send it.
|
||||
|
||||
When filled in as `true`, after the underlying TCP connection is established, the requesting party must first send PROXY protocol v1 or v2, otherwise the connection will be closed.
|
||||
|
||||
The default value is `false`
|
||||
|
||||
> `header`: [NoneHeaderObject](#noneheaderobject) | [HttpHeaderobject](#httpheaderobject)
|
||||
|
||||
Packet header obfuscation settings, the default value is `NoneHeaderObject`
|
||||
|
||||
::: tip
|
||||
HTTP obfuscation cannot be proxied by other HTTP servers (such as Nginx), but it can be proxied by VLESS fallbacks path.
|
||||
:::
|
||||
|
||||
### NoneHeaderObject
|
||||
|
||||
No header obfuscation
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "none"
|
||||
}
|
||||
```
|
||||
|
||||
> `type`: "none"
|
||||
|
||||
Disable header obfuscation.
|
||||
|
||||
### HttpHeaderObject
|
||||
|
||||
HTTP header obfuscation. The configuration must be the same between connecting inbound and outbound.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"request": {},
|
||||
"response": {}
|
||||
}
|
||||
```
|
||||
|
||||
> `type`: "http"
|
||||
|
||||
Enable HTTP header obfuscation.
|
||||
|
||||
> `request`: [HTTPRequestObject](#httprequestobject)
|
||||
|
||||
HTTP request template.
|
||||
|
||||
> `response`: [HTTPResponseObject](#httpresponseobject)
|
||||
|
||||
HTTP response template.
|
||||
|
||||
#### HTTPRequestObject
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.1",
|
||||
"method": "GET",
|
||||
"path": ["/"],
|
||||
"headers": {
|
||||
"Host": ["www.baidu.com", "www.bing.com"],
|
||||
"User-Agent": [
|
||||
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"
|
||||
],
|
||||
"Accept-Encoding": ["gzip, deflate"],
|
||||
"Connection": ["keep-alive"],
|
||||
"Pragma": "no-cache"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `version`: string
|
||||
|
||||
HTTP version, the default value is `"1.1"`
|
||||
|
||||
> `method`: string
|
||||
|
||||
The HTTP method, the default value is `"GET"`
|
||||
|
||||
> `path`: \[ string \]
|
||||
|
||||
paths, an array of strings. The default value is `["/"]`. When there are multiple values, a value is chosen randomly for each request.
|
||||
|
||||
> `headers`: map{ string, \[ string \]}
|
||||
|
||||
HTTP header, a key-value pair, each key represents the name of an HTTP header, and the corresponding value is an array.
|
||||
|
||||
Each request will include all the keys and randomly select a corresponding value. Please refer to the **default values** shown in the example above.
|
||||
|
||||
#### HTTPResponseObject
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.1",
|
||||
"status": "200",
|
||||
"reason": "OK",
|
||||
"headers": {
|
||||
"Content-Type": ["application/octet-stream", "video/mpeg"],
|
||||
"Transfer-Encoding": ["chunked"],
|
||||
"Connection": ["keep-alive"],
|
||||
"Pragma": "no-cache"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `version`: string
|
||||
|
||||
HTTP version, default is `"1.1"`
|
||||
|
||||
> `status`: string
|
||||
|
||||
HTTP status, default is `"200"`
|
||||
|
||||
> `reason`: string
|
||||
|
||||
HTTP status description, default value is `"OK"`
|
||||
|
||||
> `headers`: map {string, \[ string \]}
|
||||
|
||||
HTTP header, a key-value pair, each key represents the name of an HTTP header, and the corresponding value is an array.
|
||||
|
||||
Each request will include all the keys and randomly select a corresponding value. Please refer to the **default values** shown in the example above.
|
||||
See [RAW](./raw.md)
|
||||
|
||||
@@ -4,6 +4,10 @@ Uses standard WebSocket for data transmission.
|
||||
|
||||
WebSocket connections can be proxied by other web servers (like NGINX) or by VLESS fallback paths.
|
||||
|
||||
::: danger
|
||||
**It is recommended to switch to [XHTTP](https://github.com/XTLS/Xray-core/discussions/4113) to avoid significant traffic characteristics such as WebSocket "ALPN is http/1.1".**
|
||||
:::
|
||||
|
||||
::: tip
|
||||
WebSocket inbounds will parse the `X-Forwarded-For` header received, overriding the source address with a higher priority than the source address got from PROXY protocol.
|
||||
:::
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# XHTTP: Beyond REALITY
|
||||
|
||||
See [XHTTP: Beyond REALITY](https://github.com/XTLS/Xray-core/discussions/4113)
|
||||
Reference in New Issue
Block a user