TCP handler and "Client sent an HTTP request to an HTTPS server"

So, I’ve been a bit back and forth with configuring one of my deployments with regards to who should do TLS termination. After landing on terminating it myself, I am no longer able to send requests through the fly network. If I pass requests internally or change the external port to something else than 443, it works just fine; but now I just run into:

$ curl -k -v https://my-app.fly.dev:443
*   Trying 1.2.3.4:443...
* Connected to my-app.fly.dev (1.2.3.4) port 443 (#0)
> GET / HTTP/1.1
> Host: my-app.fly.dev:443
> User-Agent: curl/7.83.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 400 Bad Request
<
Client sent an HTTP request to an HTTPS server

Relevant part of config:

[[services]]
  internal_port = 443
  protocol = "tcp"

  [[services.ports]]
  handlers = []
  port = 443

Responding to myself: getting coffee seemed to help; perhaps there is a timeout somewhere.

Your fly app cannot terminate *.fly.dev, only fly servers can.

In case where https with tls is offloaded to fly servers, your fly app would have to handle plaintext http/1.1 and h2c (http2 cleartext), depending on ALPNs set in fly.toml: Fly Proxy H/2 Details

In case where your fly app terminates tls, you’d could front your app with haproxy / nginx / caddy / your-own-code that can handle such a setup. To run multiple processes in a single fly app, ref this doc entry.

Here’s a golang fly app that I co-wrote that does both, offloads tls to fly servers on ports 1853 / 1443, and terminates tls on ports 443 and 853 (ref), and here’s a nodejs app doing it as two separate fly apps (1, 2) (one that terminates tls itself, the other that offloads it to fly servers).

1 Like