Skip to content

Instantly share code, notes, and snippets.

@ego008
Last active August 24, 2025 12:18
Show Gist options
  • Select an option

  • Save ego008/12a0ffe02294ae5fafcac704b5172e54 to your computer and use it in GitHub Desktop.

Select an option

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

sydney-ng commented Dec 8, 2020

Copy link
Copy Markdown

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

@gocs

gocs commented Apr 17, 2021

Copy link
Copy Markdown

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

@cauefcr

cauefcr commented Jul 26, 2021

Copy link
Copy Markdown

small diff, change line 16 to:

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

@cawoodm

cawoodm commented Oct 24, 2021

Copy link
Copy Markdown

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

log.Fatal(server.ListenAndServe())

@gocs

gocs commented Oct 27, 2021

Copy link
Copy Markdown

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