Skip to main content

Send HTTP clients to HTTPS

Once a host answers HTTPS, clients that still call it over plain HTTP should be sent to the HTTPS address. redirect answers such a request itself instead of passing it on to your backend. The answer is a redirect status with a Location header. This guide adds the redirect to orders-api. At the end, a client that calls orders-api over plain HTTP is sent to the same address over HTTPS.

Before you start​

  • HTTPS that answers for the host: a certificate for api.example.com, from Serve HTTPS with your certificate. redirect only sends clients to HTTPS; it does not make HTTPS work.
  • How your clients reach the gateway. Behind a load balancer that ends HTTPS and sends the gateway plain HTTP, the gateway sees every request as plain HTTP, even one the client sent over HTTPS, and would send it to HTTPS again and again. There, do the redirect on the load balancer and leave this plugin off.
  • The gateway's HTTPS port is 9443 until whoever runs the gateway publishes HTTPS on the standard HTTPS port, so the Location in the answers below carries :9443.
  • This guide starts from orders-api as Route requests to a backend leaves it, with no other plugin. A plugin from another guide that this page does not name can change the answers below; remove it first or work on a copy of the route.
  • The requests below call /orders/3201?page=2.
  • The host name of your gateway. In the console it is the first part of the Address line on a route's Overview tab, api.example.com in this page's examples; replace it in every request below.
  • The Editor or Environment administrator role in this environment.

Steps​

1. Choose redirect​

Open orders-api under Routes, select its Plugins tab, then Add plugin at the top right of the tab. Open the General category, or type redirect in the search box. Select redirect, then Configure.

2. Choose the HTTPS redirect and add the plugin​

Choose Redirect to HTTPS, one choice that also turns on HTTP to HTTPS. Leave Status code, Append query string and Encode URI as they are. With the HTTPS redirect, the status code is fixed and the query string is kept on its own.

Select Add plugin at the bottom of the panel. The plugin is saved like this:

The Add redirect panel with the HTTP to HTTPS switch on and the status code chosen.
redirect · as the console saves it
{
"http_to_https": true
}

From now on, every request to orders-api over plain HTTP is answered with a redirect instead of reaching your backend.

Check it​

Call the route over HTTPS, and the request passes as before. Then send the same path over plain HTTP. In this request, the gateway host is the host name and port the gateway answers plain HTTP on.

curl -i 'http://<gateway host>/orders/3201?page=2' \
-H 'Host: api.example.com'
Over plain HTTP
A request over plain HTTP to api.example.com is answered 301 with Location: https://api.example.com:9443/orders/3201?page=2: the same host, path and query string over HTTPS, on the gateway's own HTTPS port.
Over plain HTTP, as a POST
A POST over plain HTTP is answered 308 instead, with the same Location.
Over HTTPS
A request that arrives over HTTPS passes untouched: over HTTPS to api.example.com it reaches your backend and is answered 200.
Behind a load balancer that ends HTTPS
A header X-Forwarded-Proto set to https changes nothing: a request that reaches the gateway over plain HTTP is still answered 301. Behind a load balancer that ends HTTPS and sends the gateway plain HTTP, a client that already called over HTTPS is therefore sent to HTTPS again.
If the route also carries key-auth
On a route that also carries key-auth, key-auth answers first: a request over plain HTTP without a key is answered 401 with {"message":"Missing API key in request"}, not redirected, and one with a valid key is answered 301.

What to know​

  • The client is sent to the same host, path and query string over HTTPS, on the gateway's own HTTPS port. A request for /orders/3201?page=2 is sent to https://api.example.com:9443/orders/3201?page=2.
  • A GET is answered 301 and a POST 308, so the client repeats the POST at the new address.
  • A header X-Forwarded-Proto set to https by a load balancer changes nothing. The gateway goes by how the request reached it.
  • If the route also carries key-auth from Require an API key, key-auth answers first. A request over plain HTTP without a key is answered 401, not redirected, and one with a valid key is redirected only after its key has crossed the network unencrypted. Give clients the https:// address from the start.
  • Turning Append query string on beside HTTP to HTTPS is refused when you save: the HTTPS address already carries the query string.
  • To send clients of a path that moved to the new path instead, choose Redirect to a URI and set the URI to the new path, /v2/orders for example. The reference page shows it under More scenarios.
G8 dev