# Change a web proxy's origin

> Point a web proxy at a different server or address, change its protocol and port, and manage its certificate.

Source: https://www.coritan.com/docs/proxies/web-proxies/change-the-origin/

In the dashboard:

- /dashboard/proxies/web/…/origin: https://www.coritan.com/dashboard/proxies/web

A web proxy's **Origin** tab sets where the edge sends requests for the name: the origin host and port, the protocol, TLS to the origin, the PROXY protocol, additional origins, path prefixes, custom request headers and the two limits. The **Certificate** card on the **Overview** tab requests and renews the certificate that the edge serves for the name.

## Before you begin

- The web proxy is on your [Edge Proxy](https://www.coritan.com/dashboard/proxies/web) list. A web proxy that a proxied DNS record created is not on the list, and its origin follows the record's **Content** ([Web proxies and DNS records](/docs/proxies/web-proxies/#web-proxies-and-dns-records)).
- The new origin answers on its port from the internet. The edge refuses private and reserved addresses.

## Change the origin

1. In the dashboard, go to [Edge Proxy](https://www.coritan.com/dashboard/proxies/web) and select the web proxy.
2. Select the **Origin** tab.
3. Change the **Origin host**, the **Port** or the **Origin protocol** ([Origin protocols](/docs/proxies/web-proxies/#origin-protocols)). Turn on **Connect to the origin over TLS** when the origin serves HTTPS on that port.
4. Turn on **PROXY protocol to origin** only when the origin expects a PROXY protocol header. An origin that does not expect it fails every request.
5. Under **Paths, headers and extra origins**, change the path prefixes, the custom request headers, the additional origins and the two limits ([Advanced options](/docs/proxies/web-proxies/create-a-web-proxy/#advanced-options)). To drop an additional origin or a header, select **Remove origin** or **Remove header** on its row.
6. Select **Save origin**.

While the form holds changes, the caption under it reads `Unsaved changes. The edge picks them up within a few seconds of saving.` **Reset** puts back the saved values.

The **Web application firewall**, **Force HTTPS**, **WebSockets** and **Development mode** switches are on the **Overview** tab ([Change a web proxy's settings](/docs/proxies/web-proxies/settings/)).

## Point the web proxy at one of your servers

The **Origin** tab takes an address. To send the name to a server hosted here without looking up the server's address, forward the name to the server again:

1. In the dashboard, go to [Edge Proxy](https://www.coritan.com/dashboard/proxies) and select **New proxy…**.
2. Choose **Website or app**, then **A server hosted here**.
3. Enter the web proxy's name as the **Domain** and choose the **Server**.
4. Turn off **Request a certificate automatically** when the web proxy already has an active certificate.
5. Select **Create proxy**.

Coritan replaces the origin host and port with the server's address and port, and keeps every other setting. If the old origin used TLS, turn off **Connect to the origin over TLS** on the **Origin** tab unless the server serves HTTPS on its port. For a domain's own web proxy, such as `example.com`, the website's **Proxy** tab does the same ([Repoint the domain at one of your servers](/docs/websites/proxy/#repoint-the-domain-at-one-of-your-servers)).

## Request or renew the certificate

The **Certificate** card on the web proxy's **Overview** tab shows the certificate that the edge serves for the name.

- When the web proxy has no certificate, or its last issuance failed, or its certificate has expired, select **Request certificate** ([Request a certificate for a web proxy](/docs/websites/ssl/issue-a-certificate/#request-a-certificate-for-a-web-proxy)).
- While the certificate authority validates the name, the card shows **Issuance in progress** and checks again every few seconds. It stops checking after three minutes, so reload the page to see the result.
- When the certificate is active, select **Renew now** to renew it before Coritan does ([Renew or revoke a certificate](/docs/websites/ssl/renew-or-revoke-a-certificate/)).
- The caption at the foot of the card says how many certificates the registered domain can still get this week ([Issuance limit](/docs/websites/ssl/#issuance-limit)).

## Result

- Saving the origin shows `Origin updated.`, and the edge uses the new origin within a few seconds. The **Route** card on the **Overview** tab lists the new **Origins**.
- Requesting a certificate shows `Certificate requested for www.example.com.`, and renewing one shows `Renewal of the certificate for www.example.com started.` The **Certificate** card shows the new certificate once the authority issues it.

## Troubleshooting

The **Origin** tab checks its fields as the form that creates a web proxy does, with the same messages ([Troubleshooting](/docs/proxies/web-proxies/create-a-web-proxy/#troubleshooting)).

Visitors get an error page that names `Origin TLS failed`
: **Connect to the origin over TLS** is on, and the origin does not present a valid certificate for the origin host. Give the origin a certificate from a public certificate authority for that name, or turn TLS off and use the origin's plain HTTP port.

Every request fails after you turn on **PROXY protocol to origin**
: The origin does not expect a PROXY protocol header. Turn the switch off, or set the origin's web server to accept PROXY protocol version 2 on that port.

Visitors get an error page that names `Connection refused` or `Connect timed out`
: Nothing answers on the new port, or a firewall in front of the origin drops connections from the internet. Check the **Port**, then check the origin's firewall ([Troubleshoot proxies and join addresses](/docs/proxies/troubleshooting/)).

**The last issuance failed**
: The certificate authority could not validate the name, and the card gives its reason. The name must resolve to the edge, or be in a DNS zone that Coritan hosts ([Issue an SSL/TLS certificate](/docs/websites/ssl/issue-a-certificate/#troubleshooting)).

`No fields to update`
: The API call held no field that it knows, or only `null` values. Send at least one field with a value.

`upstream_protocol must be h1, h2, h2c, or auto (got 'h3')`
: Send one of the four values in [Origin protocols](/docs/proxies/web-proxies/#origin-protocols).

`backend 203.0.113.11: location must be a 3 or 4 letter airport code such as fra`
: An additional origin's `location` holds something other than three or four letters. Send an airport code, such as `fra`, or leave `location` out.

`backend 203.0.113.11: region must be a 2 to 5 letter region code such as WEU`
: An additional origin's `region` is not a region code. Use a code from [Region codes](/docs/websites/load-balancing/reference/#region-codes), or leave `region` out.

## Related

- [How web proxies work](/docs/proxies/web-proxies/)
- [Create a web proxy](/docs/proxies/web-proxies/create-a-web-proxy/)
- [Change a web proxy's settings](/docs/proxies/web-proxies/settings/)
- [How SSL/TLS certificates work](/docs/websites/ssl/)

## With the API

Change a web proxy with `PATCH /api/v1/proxy/routes/{route_id}`. Send only the fields you change: a field you leave out, or send as `null`, keeps its value.

```bash
curl -X PATCH https://api.coritan.com/api/v1/proxy/routes/31 \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "upstream_host": "origin.example.net",
    "upstream_port": 443,
    "upstream_ssl": true,
    "upstream_protocol": "auto",
    "upstream_backends": [
      {"host": "203.0.113.11", "port": 443, "ssl": true}
    ]
  }'
```

```json
{"message": "Route updated"}
```

The edge uses the change within a few seconds. The call takes these fields. The default is the value a new web proxy gets when [Create a web proxy](/docs/proxies/web-proxies/create-a-web-proxy/#with-the-api) leaves the field out.

| Field | Values | Default | What it sets |
|---|---|---|---|
| `upstream_host` | An IP address or a hostname | None | The origin host, with no scheme and no port. |
| `upstream_port` | `1`–`65535` | `80` | The origin's port. |
| `upstream_ssl` | `true` or `false` | `false` | TLS from the edge to the origin. |
| `upstream_protocol` | `h1`, `h2`, `h2c` or `auto` | `h1` | How the edge talks to the origin ([Origin protocols](/docs/proxies/web-proxies/#origin-protocols)). |
| `send_proxy_protocol` | `true` or `false` | `false` | A PROXY protocol version 2 header at the start of each connection to the origin. |
| `grpc_enabled` | `true` or `false` | `false` | gRPC and gRPC-Web requests go to the origin over HTTP/2. |
| `force_https` | `true` or `false` | `true` | A `301` redirect from plain HTTP to HTTPS. |
| `websocket_enabled` | `true` or `false` | `true` | WebSocket connections pass through to the origin. |
| `waf_enabled` | `true` or `false` | `true` | The web application firewall checks requests. |
| `max_body_size_mb` | `1`–`100` | `100` | The largest request body, in MB. |
| `timeout_seconds` | `1`–`120` | `60` | How long the edge waits for the origin to answer, in seconds. |
| `strip_path_prefix` | A path, such as `/api` | None | The path the edge removes from the start of the request path. |
| `upstream_path_prefix` | A path, such as `/v2` | None | The path the edge adds in front of the request path. |
| `custom_headers` | An object, or a list of `name` and `value` pairs | None | Headers the edge adds to every request it forwards. |
| `upstream_backends` | A list of origins | None | The additional origins. |
| `redirect_to` | A URL, such as `https://www.example.com` | None | A whole-domain redirect ([Redirect the whole domain](/docs/proxies/web-proxies/redirect-rules/#redirect-the-whole-domain)). |
| `redirect_status_code` | `301`, `302`, `307` or `308` | `301` | The whole-domain redirect's status code. |
| `redirect_preserve_path` | `true` or `false` | `true` | Whether the whole-domain redirect keeps the request path. |
| `redirect_preserve_query` | `true` or `false` | `true` | Whether the whole-domain redirect keeps the query string. |
| `development_mode` | `true` or `false` | `false` | Diagnostics on the edge's error pages ([Use development mode while you debug](/docs/proxies/web-proxies/settings/#use-development-mode-while-you-debug)). |
| `development_mode_minutes` | `0`–`1440` | `180` | How long development mode stays on. `0` keeps it on until you turn it off. |
| `error_page` | An object | None | The web proxy's own error page ([Customise the error page](/docs/proxies/web-proxies/custom-error-page/#with-the-api)). |

Only the change call takes `development_mode`, `development_mode_minutes` and `error_page`. A value outside its range, such as a `timeout_seconds` of `300`, answers `422`.

Some fields take a special value or a special shape:

- In `strip_path_prefix` and `upstream_path_prefix`, Coritan adds a missing leading slash and removes a trailing one, so `api/` is saved as `/api`. An empty string or `/` removes the prefix.
- `custom_headers` takes an object, such as `{"X-Forwarded-Site": "www"}`, or a list such as `[{"name": "X-Forwarded-Site", "value": "www"}]`. The value replaces every header the web proxy had, and `{}` removes them all.
- Each entry in `upstream_backends` takes a `host`, a `port` (`80` when left out), `ssl` (`false` when left out) and a `protocol` (the web proxy's `upstream_protocol` when left out). The list replaces every additional origin the web proxy had, and `[]` removes them all.
- An empty `redirect_to` removes the whole-domain redirect.
- With `grpc_enabled` on and `upstream_protocol` set to `h1`, Coritan saves the protocol as `auto`, because gRPC needs HTTP/2. With it off, the edge forwards a gRPC request as an ordinary request. The dashboard has no switch for it.

An additional origin can also say where it runs, so that each edge location tries the nearest origins first. `location` is the airport code of the place, in lowercase, such as `fra`. `region` is its region code, such as `WEU` ([Region codes](/docs/websites/load-balancing/reference/#region-codes)); add it when the place is not one of Coritan's locations. When any additional origin has a `location`, an edge location tries the origins in its own location first, then those in its own region, then the rest, nearest region first. The origin host names no place, so the edge tries it after every origin that does.

```json
{
  "upstream_backends": [
    {"host": "203.0.113.11", "port": 443, "ssl": true, "location": "fra"},
    {"host": "203.0.113.12", "port": 443, "ssl": true, "location": "iad", "region": "ENAM"}
  ]
}
```

Request a certificate for the web proxy's name with `POST /api/v1/proxy/routes/{route_id}/ssl`. It takes no body:

```bash
curl -X POST https://api.coritan.com/api/v1/proxy/routes/31/ssl \
  -H "Authorization: Bearer $CORITAN_TOKEN"
```

```json
{"message": "SSL certificate issuance requested", "domain": "www.example.com"}
```

The web proxy's `ssl_mode` becomes `pending`. Follow the order through the `certificate` that [Read web proxies with the API](/docs/proxies/web-proxies/#read-web-proxies-with-the-api) returns, and renew a certificate with the calls in [Renew or revoke a certificate](/docs/websites/ssl/renew-or-revoke-a-certificate/#with-the-api). A web proxy that is not on your account answers `404` with `Route not found`.

## API

- `PATCH /api/v1/proxy/routes/{route_id}`: Update a proxy route you own (https://www.coritan.com/docs/api/reference/client/reverse-proxy/#op-patch-api-v1-proxy-routes-route-id)
- `POST /api/v1/proxy/routes/{route_id}/ssl`: Request SSL certificate issuance for a proxy route you own (https://www.coritan.com/docs/api/reference/client/reverse-proxy/#op-post-api-v1-proxy-routes-route-id-ssl)
