I want to serve two or more web applications running in a VM (different ports and some time in different directory under the same port) from the host machine and because I need the user to be logged before he can access those apps I can not use a static proxy like Nginx or Apache.
So here is my situation :
192.168.1.1 : is the host ip
192.168.1.2 : is the VM ip
Inside the VM I have this :
192.168.1.2/owncloud : owncloud address
192.168.1.2:8080 : an other app
192.168.1.2:8888 : 3rd app
I want to have this :
192.168.1.1/app1 --> 192.168.1.2/owncloud
192.168.1.1/app2 --> 192.168.1.2:8080
192.168.1.1/app2 --> 192.168.1.2:8888
I have tried to use golang httputil.ReverseProxy to achieve this routing but with no much success: my code is based on this work : gist
package main
import(
"log"
"net/url"
"net/http"
"net/http/httputil"
)
func main() {
remote, err := url.Parse("http://192.168.1.2:8080")
if err != nil {
panic(err)
}
proxy := httputil.NewSingleHostReverseProxy(remote)
http.HandleFunc("/app2", handler(proxy))
err = http.ListenAndServe(":80", nil)
if err != nil {
panic(err)
}
}
func handler(p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
log.Println(r.URL)
r.URL.Path = "/"
p.ServeHTTP(w, r)
}
}
Edit :
I have changed the vm ip address: 192.168.1.2 not 192.168.1.1
Make a map like this
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",
}
Use httputil.ReverseProxy
build your handler
type baseHandle struct{}
func (h *baseHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
host := r.Host
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)
proxy.ServeHTTP(w, r)
return
}
w.Write([]byte("403: Host forbidden " + host))
}
ListenAndServe
h := &baseHandle{}
http.Handle("/", h)
server := &http.Server{
Addr: ":8080",
Handler: h,
}
log.Fatal(server.ListenAndServe())
You can cached httputil.ReverseProxy
in global map, all in file above.
Here is a SSLDocker project seen to match with you best.