I have a simple proxy that listens to HTTP and HTTPS connections on the same port.
However I'm seeing weird TLS handshake errors that seem to be caused by the Heroku router:
heroku[router]: sock=backend at=error code=H18 desc="Server Request Interrupted" method=GET path="/favicon.ico" host=banana.camp request_id=f56144c8-e480-476a-90b8-429b490f1ff5 fwd="24.67.185.77" dyno=web.1 connect=0ms service=1ms status=503 bytes=7 protocol=https
http: TLS handshake error from 10.81.159.108:19578: tls: first record does not look like a TLS handshake
http: TLS handshake error from 172.17.117.25:36924: EOF
Is there any way to fix or ignore them? Any clues are greatly appreciated.
Thanks!
func InitServer() error {
m := autocert.Manager{
Cache: autocert.DirCache(*StorageDir),
Prompt: autocert.AcceptTOS,
HostPolicy: func(ctx context.Context, host string) error {
return nil
},
}
errchan := make(chan error)
s := &http.Server{
Addr: ":" + os.Getenv("PORT"),
TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
Handler: ServeHTTP(),
}
go (func() {
errchan <- http.ListenAndServe(":"+os.Getenv("PORT"), m.HTTPHandler(nil))
})()
errchan <- s.ListenAndServeTLS("", "")
return <-errchan
}
func ServeHTTP() http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if upstreams, ok := Hosts[req.Host]; ok {
forwarder, _ := forward.New(forward.PassHostHeader(true))
loadbalancer, _ := roundrobin.New(forwarder)
for _, upstream := range upstreams {
if url, err := url.Parse(upstream); err == nil {
loadbalancer.UpsertServer(url)
} else {
log.Fatal("InitHostsList: ", err)
}
}
loadbalancer.ServeHTTP(res, req)
return
}
http.Error(res, "The request service couldn't be found here", http.StatusNotImplemented)
})
}
You can't listen to both http and https on the same port, and those log-errors are cases when you have http clients try to connect to the app.
By default, the golang http server only supports listening to http or https traffic on a given port (not both). To listen to https traffic, you need to use http.ListenAndServeTLS
.
If you are directing both http and https traffic at at point configured for only one, you will end up seeing errors.
There are third-party solution (like cmux) that support hosting both secure and insecure traffic on the same port. Not as easy as separating the ports, but if it's something you want to do, they have an example configuration in the README.
TLS termination is handled by the Heroku router and can't be done at the app level ¯_(ツ)_/¯