---
url: /apranik/configuration/transport/httpupgrade.md
---
# HTTPUpgrade

An overlay: the HTTP/1.1 upgrade handshake, then raw bytes with no WebSocket
framing. It passes CDNs that relay an upgraded connection without checking frames,
such as Cloudflare, and costs nothing after the handshake. Compatible with Xray's
and sing-box's. A [`tls`](tls.md) below it must set `"alpn": ["http/1.1"]`.

[![What ws and httpupgrade put on the wire](../../assets/diagrams/ws-vs-httpupgrade.excalidraw.svg)](../../assets/diagrams/ws-vs-httpupgrade.excalidraw.svg)

## Structure

:::tabs
\== Inbound

```json
{
  "type": "httpupgrade",
  "settings": {
    "path": "/up",
    "host": "cdn.example.com",
    "accept_websocket_key": true
  }
}
```

\== Outbound

```json
{
  "type": "httpupgrade",
  "settings": { "path": "/up", "host": "cdn.example.com", "pipeline": false }
}
```

:::

## Fields

### `path`

string
Default: /

The request path. A server ignores the query string and answers any other path
with `404`.

### `host`

string

Outbound: the `Host` header a CDN routes on; default the outbound's `server`.
Inbound: the only `Host` accepted; default any.

### `headers`

object of strings
outbound

Extra request headers. Without a `User-Agent`, a browser's is sent.

### `pipeline`

boolean
Default: false
outbound

Send the payload without waiting for the server's `101`, saving a round trip. Only
safe against an Apranik server. Xray's and sing-box's servers may drop those bytes (not tested).

### `original_source_ip`

object
inbound

Reads the client's address from a header the CDN adds. See
[Client address behind a proxy](original_source_ip.md).

### `accept_websocket_key`

boolean
Default: true
inbound

Accept a request carrying `Sec-WebSocket-Key`, as Xray does. `false` answers it
with `404`, as sing-box does.

### `handshake_timeout`

duration
Default: 10s

How long the upgrade may take.
