如果根据不同的域名,选择不同的handler

现有的教程中,都是根据不同的路径,选择不同的handle,如何根据不同的域名,选择不同的handle呢?

//有很多个,handel1,handle2....
type routeHandler struct{}

func (h *routeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if strings.HasSuffix(r.Host, "host1.com") {
    //如何处理handle1?
    }
    if strings.HasSuffix(r.Host, "*.host2.com") {
    //如何处理handle2?
    }
}

go func() {
    ts := time.Duration(*timeouts) * time.Second
    routes := &routeHandler{}
    //之前代码是ListenAndServe(*http_addr, handel1, ts)
    //之前代码是ListenAndServe(*http_addr, handel2, ts)
    //只能处理一个handle,这里希望根据域名调用不同的handle
    ListenAndServe(*http_addr, routes, ts)
}()
………………
func ListenAndServe(addr string, handler http.Handler, timeout time.Duration) error {
    server := &http.Server{
        Addr:        addr,
        Handler:     handler,
        ReadTimeout: timeout,
    }
    return server.ListenAndServe()
}

共 8 个回复


stevewang

你创建多个http.Server对象不就好了。

# 0

Zhangyc310

同一个端口,怎么创建?

# 1

stevewang

不同域名解析成不同的ip,或者不同端口映射到同一个端口。

# 2

Zhangyc310

不同的ip、不同的端口映射,不行。。。

# 3

Zhangyc310

只能是先进入一个routeHandler,然后跳转到handle1handle2
可以做到吗?

# 4

rockman

使用Host-specific pattern for ServeMux

Host Multiple Domains in a Single Golang HTTP Server

To host multiple domains in a single Golang HTTP server, we need to use Host-specific pattern for ServeMux:

Patterns may optionally begin with a host name, restricting matches to URLs on that host only. Host-specific patterns take precedence over general patterns, so that a handler might register for the two patterns “/codesearch” and “codesearch.google.com/“ without also taking over requests for “http://www.google.com/“.

// For Example:
func main() {
    http.HandleFunc("a.com/", helloA)
    http.HandleFunc("sub.a.com/", helloSubA)
    http.HandleFunc("b.com/", helloB)

    if err := http.ListenAndServe(":80", nil); err != nil {
        log.Fatal(err)
    }
}

Example

References

原文链接:
Host Multiple Domains in a Single Golang HTTP Server)

# 5

stevewang

你自己实现一个http.Handler就可以:

package main

import(
    "fmt"
    "net/http"
    "strings"
)

type HostMux struct {
    muxes map[string]*http.ServeMux
}

func (this *HostMux) GetMux(host string) *http.ServeMux {
    mux, ok := this.muxes[host]
    if !ok {
        mux = http.NewServeMux()
        this.muxes[host] = mux
    }
    return mux
}

func (this *HostMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    host := r.Host
    if index := strings.IndexByte(r.Host, ':'); index > 0 {
        host = host[:index]
    }
    mux, ok := this.muxes[host]
    if ok {
        mux.ServeHTTP(w, r)
    }
}

func hello1(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello1")
}

func hello2(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello2")
}

func main() {
    mux := &HostMux{
        muxes: make(map[string]*http.ServeMux),
    }
    mux.GetMux("localhost").HandleFunc("/hello", hello1)
    mux.GetMux("127.0.0.1").HandleFunc("/hello", hello2)
    http.ListenAndServe(":6061", mux)
}

访问http://localhost:6061/hellohttp://127.0.0.1:6061/hello跳转到不同处理函数。

# 6

Zhangyc310

高手,非常感谢!

# 7