英文:
How to get "virtualhost" functionality in Go?
问题
使用Nginx/Django创建虚拟主机就像编写适当的配置一样简单。
对于Go,我找到了这个https://codereview.appspot.com/4070043,我了解到我必须使用ServeMux
,但是如何实现呢?
我的意思是我必须为所有项目创建一个二进制文件,还是我必须创建一个“路由器”服务器,根据主机名路由请求?如何用“Go”的方式实现呢?
英文:
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?
答案1
得分: 25
你是正确的,你将使用ServeMux。ServeMux的godoc中有关于如何使用它的详细信息。
在标准的http包中,有一个DefaultServeMux,可以使用顶级的Handle函数来操作它。例如,一个简单的虚拟主机应用程序可能如下所示:
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的请求都会命中第二个处理程序,而对其他主机的请求都会命中第一个处理程序。
英文:
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.
答案2
得分: 3
这是使用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 web服务器,甚至是其他传统的web服务器,如nginx。它们中的每一个都可以在相同的IP和另一个端口中,或者在另一个IP和任何端口中。如果您希望这样做,将请求转发到不同的物理服务器也没有关系。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论