doushi8231
doushi8231
2013-01-05 10:14

如何在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?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • duanbianweng5353 duanbianweng5353 8年前

    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.

    点赞 评论 复制链接分享
  • dragonfly9527 dragonfly9527 7年前

    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.

    点赞 评论 复制链接分享