Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get "virtualhost" functionality in Go?

Tags:

go

virtualhost

With Nginx/Django create virtualhosts is as easy as to write appropriate config.

For Go I found this https://codereview.appspot.com/4070043 and I understand that I have to use ServeMux but how to implement it?

I mean I must have 1 binary for all projects or I have to create some "router" server which will route requests depending on hostname? How to do it "Go"-way?

like image 619
shalakhin Avatar asked Jan 05 '13 10:01

shalakhin


2 Answers

Here is another example of how to provide the "virtual hosts" functionality using golang:

package main

import(
    "net/url"
    "net/http"
    "net/http/httputil"
)

func main() {
    vhost1, err := url.Parse("http://127.0.0.1:1980")
    if err != nil {
            panic(err)
    }
    proxy1 := httputil.NewSingleHostReverseProxy(vhost1)
    http.HandleFunc("publicdomain1.com/", handler(proxy1))

    vhost2, err := url.Parse("http://127.0.0.1:1981")
    if err != nil {
            panic(err)
    }
    proxy2 := httputil.NewSingleHostReverseProxy(vhost2)
    http.HandleFunc("publicdomain2.com/", handler(proxy2))

    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) {
            p.ServeHTTP(w, r)
    }
}

In this case each "virtual host" can be any http server, like other golang net.http web server or even other conventional web server like nginx. Each of them can be either in the same ip and in another port, or in another ip and any port. It doesn't matter if you are forwarding to a different physical server if you wish to do it.

like image 177
bigato Avatar answered Oct 19 '22 23:10

bigato


You are correct that you will use the ServeMux. The godoc for ServeMux has some detailed information about how to use it.

In the standard http package, there is the DefaultServeMux which can be manipulated using the top-level Handle functions. For example, a simple virtual host application might look like:

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, world!")
    })
    http.HandleFunc("qa.example.com/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, improved world!")
    })
    http.ListenAndServe(":8080", nil)
}

In this example, all requests to qa.example.com will hit the second handler, and all requests to other hosts will hit the first handler.

like image 24
Kyle Lemons Avatar answered Oct 20 '22 01:10

Kyle Lemons