假设这个代码
handler := http.HandleFunc("/usedport", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(strings.Split(r.RemoteAddr,":")[1]))
})
l, err = net.Listen("tcp", ":8080")
一切顺利。我们致电
http://127.0.0.1:8080/usedport
并得到 8080
的答复
但是...例如,如果在 docker 级别重新映射端口
docker run --rm -v $(pwd)/mybin:/mybin -p 8081:8080 ubuntu /mybin
我们仍在收听 8080,但通话看起来像
http://127.0.0.1:8081/usedport
答案是 8081
但是我想确切地知道请求使用了哪个侦听器端口,所以我仍然希望得到 8080 的答案。
在调查过程中,我似乎可以从 http.Request 访问 *http.Server -
r.Context().Value(http.ServerContextKey).(*http.Server)
但是听众信息是私人的。
唯一的解决方法始终是同步公开和映射的端口,如下所示:
docker run --rm -v $(pwd)/mybin:/mybin -p 8081:8081 ubuntu /mybin --port 8081
但看起来并不好。是访问有关用于获取请求的端口信息的规范或至少合法的方式。
服务器的端口始终是不变的,无法使用 Docker 进行更改。 Docker 只处理端口映射。通常,您使用环境变量来设置端口。在这种情况下,您的示例将如下所示:
port := os.Getenv("PORT")
http.HandleFunc("/usedport", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(port))
})
l, err := net.Listen("tcp", fmt.Sprintf(":%s", port))
Docker 命令为:
docker run --rm -e PORT=8080 -v $(pwd)/mybin:/mybin -p 8081:8081 ubuntu /mybin
-e PORT=8080
设置 Docker 容器内的 PORT
环境变量。