Quantcast
Channel: Active questions tagged https - Stack Overflow
Viewing all articles
Browse latest Browse all 1501

How listen HTTPS and HTTP on same port depending on host with GO?

$
0
0

I'm writing a reverse proxy in go. I already have a basic setup working, but I want to be able to listen on a port and have it use TLS or not depending on the host. This is my current code:

var sitesManager *sites.SiteManager = sites.CreateSiteManager()func handleRequest(res http.ResponseWriter, req *http.Request) {    ctx := req.Context()    svrAddr := ctx.Value(http.LocalAddrContextKey).(net.Addr)    host := strings.Split(req.Host, ":")[0]    port := strings.Split(svrAddr.String(), ":")[1]    origin := host +":" + port    site, exists := sitesManager.GetSite(origin)    if !exists {        http.Error(res, "Site not found", http.StatusNotFound)        return    }    site.HandleRequest(res, req)}func main() {    manager := &autocert.Manager{        Cache:      autocert.DirCache("certsCache"),        Prompt:     autocert.AcceptTOS,        HostPolicy: sitesManager.HostPolicy(),    }    registerSite("example.com:80", &sites.RedirectSite{        Destination: "https://example.com",        HTTPS:       true,    },        manager)    registerSite("example.com:443", &sites.ReverseProxySite{        Destination: "http://localhost:8000",        HTTPS:       true,    }, manager)    handler := http.HandlerFunc(handleRequest)    err := http.ListenAndServe(":80", manager.HTTPHandler(handler))    if err != nil {        log.Fatalf("HTTPS server failed: %v", err)    }}func registerSite(origin string, site sites.Site, certManager *autocert.Manager) {    portString := strings.Split(origin, ":")[1]    port, _ := strconv.Atoi(portString)    portExists := sitesManager.IsPortRegistered(port)    defer sitesManager.RegisterSite(origin, site)    if portExists {        return    }    if site.ShouldUseTLS() {        go func() {            tlsServer := &http.Server{                Addr:      ":" + portString,                Handler:   http.HandlerFunc(handleRequest),                TLSConfig: certManager.TLSConfig(),            }            err := tlsServer.ListenAndServeTLS("", "")            if err != nil {                log.Fatalf("HTTPS server failed: %v", err)            }        }()    } else {        go func() {            err := http.ListenAndServe(":" + portString, http.HandlerFunc(handleRequest))            if err != nil {                log.Fatalf("HTTP server failed: %v", err)            }        }()    }}

The site manager is just contains a RWMutex and a few maps to handle routing and ensure that servers are started correctly.Right now something like this would not work correctly:

registerSite("example1.com:8000", &sites.ReverseProxySite{    Destination: "localhost:3000",    HTTPS:       false,}, manager)registerSite("example2.com:8000", &sites.ReverseProxySite{    Destination: "localhost:3001",    HTTPS:       true,}, manager)

Is it possible to listen on same port for both http and https?


Viewing all articles
Browse latest Browse all 1501

Trending Articles