Skip to content

Instantly share code, notes, and snippets.

@ego008
Last active September 20, 2024 09:14
Show Gist options
  • Save ego008/12a0ffe02294ae5fafcac704b5172e54 to your computer and use it in GitHub Desktop.
Save ego008/12a0ffe02294ae5fafcac704b5172e54 to your computer and use it in GitHub Desktop.
Multiple host reverse proxy in Go
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
)
var (
hostTarget = map[string]string{
"app1.domain.com": "http://192.168.1.2/owncloud",
"app2.domain.com": "http://192.168.1.2:8080",
"app3.domain.com": "http://192.168.1.2:8888",
}
hostProxy map[string]*httputil.ReverseProxy = map[string]*httputil.ReverseProxy{}
)
type baseHandle struct{}
func (h *baseHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
host := r.Host
if fn, ok := hostProxy[host]; ok {
fn.ServeHTTP(w, r)
return
}
if target, ok := hostTarget[host]; ok {
remoteUrl, err := url.Parse(target)
if err != nil {
log.Println("target parse fail:", err)
return
}
proxy := httputil.NewSingleHostReverseProxy(remoteUrl)
hostProxy[host] = proxy
proxy.ServeHTTP(w, r)
return
}
w.Write([]byte("403: Host forbidden " + host))
}
func main() {
h := &baseHandle{}
http.Handle("/", h)
server := &http.Server{
Addr: ":8082",
Handler: h,
}
log.Fatal(server.ListenAndServe())
}
@sydney-ng
Copy link

sydney-ng commented Dec 8, 2020

to prevent Golang compiler from giving you a panic error, change line 16 to hostProxy = make(map[string]*httputil.ReverseProxy)

@gocs
Copy link

gocs commented Apr 17, 2021

I'm new to reverse proxy. how do I test these?

@cauefcr
Copy link

cauefcr commented Jul 26, 2021

small diff, change line 16 to:

	hostProxy map[string]*httputil.ReverseProxy = map[string]*httputil.ReverseProxy{}

@cawoodm
Copy link

cawoodm commented Oct 24, 2021

New to Golang here - how does this line work? It should kill the process shouldn't it?

log.Fatal(server.ListenAndServe())

@gocs
Copy link

gocs commented Oct 27, 2021

New to Golang here - how does this line work? It should kill the process shouldn't it?

log.Fatal(server.ListenAndServe())

It should just listen and serve just like http.ListenAndServe(). It should serve http handlers, run indefinitely, and stop from either a graceful shutdown or an unexpected error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment