HandleFunc 中的 http 主机和端口信息
http host and port information in HandleFunc
我正在尝试启动多个 http 服务器侦听同一包中的不同端口。在我的测试 HandleFunc 函数中,我需要打印我们的主机和服务请求的 http 服务器的信息端口。我该怎么做?
这是我的示例代码:
package main
import (
"encoding/json"
"flag"
"log"
"net/http"
"os"
"github.com/dineshgowda24/lb/backendserver/config"
)
func main() {
c := flag.String("c", "config/config.json", "Please specify conf.json")
flag.Parse()
file, err := os.Open(*c)
if err != nil {
log.Fatal("Unable to open config file")
}
defer file.Close()
decoder := json.NewDecoder(file)
config := bconfig.BackendConfiguration{}
err = decoder.Decode(&config)
if err != nil {
log.Fatal("Unable to decode conf.json file")
}
http.HandleFunc("/", handle)
for _, s := range config.Servers {
log.Printf("Started server at : %s : %s ", s.Host, s.Port)
go func(host, port string) {
if err := http.ListenAndServe(host+":"+port, nil); err != nil {
log.Printf("Unable to start server at : %s : %s ", host, port)
}
}(s.Host, s.Port)
}
select {}
}
//How to get info of the server which served the request ??
func handle(w http.ResponseWriter, r *http.Request) {
response := "I came from " //need to get server info
w.Write([]byte(response))
w.WriteHeader(http.StatusOK)
}
您可以使用 r.Host
从请求主机获取它。参考:https://golang.org/pkg/net/http/#Request
使用http.LocalAddrContextKey 从请求上下文中检索服务器地址。
在我的评论中,我建议使用 ServerContextKey,但并不总是设置 http.Server.Addr 字段,例如在使用 http.Server.Serve 时(以及扩展名 http.Serve)。以下示例演示了 LocalAddrContextKey 同时适用于 http.ListenAndServe 和 http.Serve:
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
srvAddr := ctx.Value(http.LocalAddrContextKey).(net.Addr)
fmt.Println(srvAddr)
})
ln, err := net.Listen("tcp", "127.0.0.1:3000")
if err != nil {
log.Fatal(err)
}
go func() { log.Fatal(http.Serve(ln, nil)) }()
go func() { log.Fatal(http.ListenAndServe("127.0.0.1:4000", nil)) }()
resp, err := http.Get("http://localhost:3000")
if err != nil {
log.Fatal(err)
}
resp.Body.Close()
resp, err = http.Get("http://localhost:4000")
if err != nil {
log.Fatal(err)
}
resp.Body.Close()
}
// Output:
// 127.0.0.1:3000
// 127.0.0.1:4000
我正在尝试启动多个 http 服务器侦听同一包中的不同端口。在我的测试 HandleFunc 函数中,我需要打印我们的主机和服务请求的 http 服务器的信息端口。我该怎么做?
这是我的示例代码:
package main
import (
"encoding/json"
"flag"
"log"
"net/http"
"os"
"github.com/dineshgowda24/lb/backendserver/config"
)
func main() {
c := flag.String("c", "config/config.json", "Please specify conf.json")
flag.Parse()
file, err := os.Open(*c)
if err != nil {
log.Fatal("Unable to open config file")
}
defer file.Close()
decoder := json.NewDecoder(file)
config := bconfig.BackendConfiguration{}
err = decoder.Decode(&config)
if err != nil {
log.Fatal("Unable to decode conf.json file")
}
http.HandleFunc("/", handle)
for _, s := range config.Servers {
log.Printf("Started server at : %s : %s ", s.Host, s.Port)
go func(host, port string) {
if err := http.ListenAndServe(host+":"+port, nil); err != nil {
log.Printf("Unable to start server at : %s : %s ", host, port)
}
}(s.Host, s.Port)
}
select {}
}
//How to get info of the server which served the request ??
func handle(w http.ResponseWriter, r *http.Request) {
response := "I came from " //need to get server info
w.Write([]byte(response))
w.WriteHeader(http.StatusOK)
}
您可以使用 r.Host
从请求主机获取它。参考:https://golang.org/pkg/net/http/#Request
使用http.LocalAddrContextKey 从请求上下文中检索服务器地址。
在我的评论中,我建议使用 ServerContextKey,但并不总是设置 http.Server.Addr 字段,例如在使用 http.Server.Serve 时(以及扩展名 http.Serve)。以下示例演示了 LocalAddrContextKey 同时适用于 http.ListenAndServe 和 http.Serve:
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
srvAddr := ctx.Value(http.LocalAddrContextKey).(net.Addr)
fmt.Println(srvAddr)
})
ln, err := net.Listen("tcp", "127.0.0.1:3000")
if err != nil {
log.Fatal(err)
}
go func() { log.Fatal(http.Serve(ln, nil)) }()
go func() { log.Fatal(http.ListenAndServe("127.0.0.1:4000", nil)) }()
resp, err := http.Get("http://localhost:3000")
if err != nil {
log.Fatal(err)
}
resp.Body.Close()
resp, err = http.Get("http://localhost:4000")
if err != nil {
log.Fatal(err)
}
resp.Body.Close()
}
// Output:
// 127.0.0.1:3000
// 127.0.0.1:4000