diff --git a/api.go b/api.go index 4358d9c..e94079a 100644 --- a/api.go +++ b/api.go @@ -61,8 +61,8 @@ func main() { } // Specific routes - r.Host(`{node:pwd[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}}-{port:[0-9]*}.{tld:.*}`).HandlerFunc(proxyMultiplexer) - r.Host(`{node:pwd[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}}.{tld:.*}`).HandlerFunc(proxyMultiplexer) + r.Host(`{host:.*}{node:pwd[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}}-{port:[0-9]*}.{tld:.*}`).HandlerFunc(proxyMultiplexer) + r.Host(`{host:.*}{node:pwd[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}}.{tld:.*}`).HandlerFunc(proxyMultiplexer) r.HandleFunc("/ping", handlers.Ping).Methods("GET") r.HandleFunc("/sessions/{sessionId}", handlers.GetSession).Methods("GET") r.Handle("/sessions/{sessionId}/instances", http.HandlerFunc(handlers.NewInstance)).Methods("POST") @@ -110,7 +110,7 @@ func main() { ssl := mux.NewRouter() sslProxyHandler := handlers.NewSSLDaemonHandler() - ssl.Host(`{node:pwd[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}}-2375.{tld:.*}`).Handler(sslProxyHandler) + ssl.Host(`{host:.*}{node:pwd[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}_[0-9]{1,3}}-2375.{tld:.*}`).Handler(sslProxyHandler) log.Println("Listening TLS on port " + config.SSLPortNumber) s := &http.Server{Addr: "0.0.0.0:" + config.SSLPortNumber, Handler: ssl} diff --git a/handlers/reverseproxy.go b/handlers/reverseproxy.go index 49f6520..e1ff270 100644 --- a/handlers/reverseproxy.go +++ b/handlers/reverseproxy.go @@ -13,6 +13,41 @@ import ( "github.com/gorilla/mux" ) +func getTargetInfo(vars map[string]string, req *http.Request) (string, string, string) { + node := vars["node"] + port := vars["port"] + host := vars["host"] + hostPort := strings.Split(req.Host, ":") + + // give priority to the URL host port + if len(hostPort) > 1 && hostPort[1] != config.PortNumber { + port = hostPort[1] + } else if port == "" { + port = "80" + } + + if strings.HasPrefix(node, "pwd") { + // Node is actually an ip, need to convert underscores by dots. + ip := strings.Replace(strings.TrimPrefix(node, "pwd"), "_", ".", -1) + + if net.ParseIP(ip) == nil { + // Not a valid IP, so treat this is a hostname. + } else { + node = ip + } + } + + if len(host) > 0 { + // Remove last "." from host + host = strings.TrimSuffix(host, ".") + } else { + host = req.Host + } + + return node, port, host + +} + func NewMultipleHostReverseProxy() *httputil.ReverseProxy { var transport http.RoundTripper = &http.Transport{ Proxy: http.ProxyFromEnvironment, @@ -29,27 +64,7 @@ func NewMultipleHostReverseProxy() *httputil.ReverseProxy { } director := func(req *http.Request) { v := mux.Vars(req) - node := v["node"] - port := v["port"] - hostPort := strings.Split(req.Host, ":") - - // give priority to the URL host port - if len(hostPort) > 1 && hostPort[1] != config.PortNumber { - port = hostPort[1] - } else if port == "" { - port = "80" - } - - if strings.HasPrefix(node, "pwd") { - // Node is actually an ip, need to convert underscores by dots. - ip := strings.Replace(strings.TrimPrefix(node, "pwd"), "_", ".", -1) - - if net.ParseIP(ip) == nil { - // Not a valid IP, so treat this is a hostname. - } else { - node = ip - } - } + node, port, host := getTargetInfo(v, req) if port == "443" { // Only proxy http for now @@ -59,6 +74,7 @@ func NewMultipleHostReverseProxy() *httputil.ReverseProxy { req.URL.Scheme = "http" } + req.Host = host req.URL.Host = fmt.Sprintf("%s:%s", node, port) } diff --git a/handlers/websocket_reverseproxy.go b/handlers/websocket_reverseproxy.go index e4bd17e..e8bed71 100644 --- a/handlers/websocket_reverseproxy.go +++ b/handlers/websocket_reverseproxy.go @@ -3,11 +3,8 @@ package handlers import ( "crypto/tls" "fmt" - "net" "net/http" - "strings" - "github.com/franela/play-with-docker/config" "github.com/gorilla/mux" "github.com/yhat/wsutil" ) @@ -18,27 +15,8 @@ func NewMultipleHostWebsocketReverseProxy() *wsutil.ReverseProxy { } director := func(req *http.Request) { v := mux.Vars(req) - node := v["node"] - port := v["port"] - hostPort := strings.Split(req.Host, ":") - // give priority to the URL host port - if len(hostPort) > 1 && hostPort[1] != config.PortNumber { - port = hostPort[1] - } else if port == "" { - port = "80" - } - - if strings.HasPrefix(node, "pwd") { - // Node is actually an ip, need to convert underscores by dots. - ip := strings.Replace(strings.TrimPrefix(node, "pwd"), "_", ".", -1) - - if net.ParseIP(ip) == nil { - // Not a valid IP, so treat this is a hostname. - } else { - node = ip - } - } + node, port, host := getTargetInfo(v, req) if port == "443" { // Only proxy http for now @@ -47,6 +25,7 @@ func NewMultipleHostWebsocketReverseProxy() *wsutil.ReverseProxy { // Only proxy http for now req.URL.Scheme = "ws" } + req.Host = host req.URL.Host = fmt.Sprintf("%s:%s", node, port) }