【问题标题】:How to get "virtualhost" functionality in Go?如何在 Go 中获得“虚拟主机”功能?
【发布时间】:2012-12-19 16:44:43
【问题描述】:

使用 Nginx/Django 创建虚拟主机就像编写适当的配置一样简单。

对于 Go,我发现了这个 https://codereview.appspot.com/4070043,我知道我必须使用 ServeMux,但如何实现它?

我的意思是我的所有项目都必须有 1 个二进制文件,或者我必须创建一些“路由器”服务器来根据主机名路由请求?如何“走”路?

【问题讨论】:

    标签: go virtualhost


    【解决方案1】:

    这是另一个如何使用 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)
        }
    }
    

    在这种情况下,每个“虚拟主机”可以是任何 http 服务器,如其他 golang net.http 网络服务器,甚至其他常规网络服务器,如 nginx。它们中的每一个都可以在同一个 ip 和另一个端口中,或者在另一个 ip 和任何端口中。如果您愿意,是否转发到不同的物理服务器都没有关系。

    【讨论】:

      【解决方案2】:

      您将使用 ServeMux 是正确的。 godoc for ServeMux 有一些关于如何使用它的详细信息。

      在标准的 http 包中,有可以使用顶级 Handle 函数操作的 DefaultServeMux。例如,一个简单的虚拟主机应用程序可能如下所示:

      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)
      }
      

      在本例中,对 qa.example.com 的所有请求都将命中第二个处理程序,而对其他主机的所有请求都将命中第一个处理程序。

      【讨论】:

      • 我很好奇他关于所需二进制文件数量的问题的第二部分。您是否需要将所有单独的虚拟主机项目编译成一个二进制文件以供 ServeMux 正确复用?我能想到的唯一其他方法是使用 os 包执行其他 go 二进制文件,这似乎是错误的。
      • 与此相关:如何在同一个go程序中运行两个web服务器:stackoverflow.com/questions/21183183/…
      • @MorganFreeman 要使用我在此处概述的方法,您将执行在单个主机上提供服务的单个 Go 二进制文件。所有虚拟化主机名都必须解析为运行二进制文件的主机。
      • 对 qa.example.com/ 的请求对我不起作用。还有什么我应该做的吗?我在 hosts 文件中添加了这个:127.0.0.1 qa.example.com 但仍然不起作用
      • @zuzuleinen 检查您收到的请求中的 r.Host,并确保它显示“qa.example.com”——如果不是,则说明其他问题(例如客户端使用 HTTP 1.0)。你也可以试试 gorilla mux 的 Host() 匹配器。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-14
      • 1970-01-01
      • 2020-07-17
      • 2011-01-23
      • 2021-08-30
      • 2016-05-17
      • 2021-09-03
      相关资源
      最近更新 更多