使 httputil.ReverseProxy 正确转发响应流
Make httputil.ReverseProxy Foward Response Stream Correctly
我的主 web-server 中有反向代理,专用于某个 micro-service 并处理转发请求到其适当的 micro-service。
func newTrimPrefixReverseProxy(target *url.URL, prefix string) *httputil.ReverseProxy {
director := func(req *http.Request) {
// ... trims prefix from request path and prepends the path of the target url
}
return &httputil.ReverseProxy{Director: director}
}
这对于纯 JSON 响应非常有效,但我最近在尝试通过反向代理提供内容(流响应)时遇到了 运行 问题。提供内容的方式无关紧要,当直接访问服务而不是通过反向代理访问服务时,(视频)内容将按预期提供。
服务内容:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeContent(w, r, "video.mp4", time.Now().Add(time.Hour*24*365*12*9*-1), videoReadSeeker)
})
同样,videoReadSeeker 和内容的提供方式不是问题,问题是通过反向代理将我的响应按预期转发给请求者;当直接访问服务时,视频出现了,我可以尽情地刷它。
请注意,已收到内容数据的响应(http 状态,headers),但响应中的内容流 body 未收到。
如何确保反向代理按照内容的预期处理流式响应?
使用时是否得到相同的结果:
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
)
func main() {
u, err := url.Parse("http://localhost:8080/asdfasdf")
if err != nil {
log.Fatal("url.Parse: %v", err)
}
proxy := httputil.NewSingleHostReverseProxy(u)
log.Printf("Listening at :8081")
if err := http.ListenAndServe(":8081", proxy); err != nil {
log.Fatal("ListenAndServe: %v", err)
}
}
最终,这些是相同的幕后实现,但此处提供的主管确保某些预期的 headers 存在,您需要这些代理功能才能按预期运行。
我的主 web-server 中有反向代理,专用于某个 micro-service 并处理转发请求到其适当的 micro-service。
func newTrimPrefixReverseProxy(target *url.URL, prefix string) *httputil.ReverseProxy {
director := func(req *http.Request) {
// ... trims prefix from request path and prepends the path of the target url
}
return &httputil.ReverseProxy{Director: director}
}
这对于纯 JSON 响应非常有效,但我最近在尝试通过反向代理提供内容(流响应)时遇到了 运行 问题。提供内容的方式无关紧要,当直接访问服务而不是通过反向代理访问服务时,(视频)内容将按预期提供。
服务内容:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeContent(w, r, "video.mp4", time.Now().Add(time.Hour*24*365*12*9*-1), videoReadSeeker)
})
同样,videoReadSeeker 和内容的提供方式不是问题,问题是通过反向代理将我的响应按预期转发给请求者;当直接访问服务时,视频出现了,我可以尽情地刷它。
请注意,已收到内容数据的响应(http 状态,headers),但响应中的内容流 body 未收到。
如何确保反向代理按照内容的预期处理流式响应?
使用时是否得到相同的结果:
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
)
func main() {
u, err := url.Parse("http://localhost:8080/asdfasdf")
if err != nil {
log.Fatal("url.Parse: %v", err)
}
proxy := httputil.NewSingleHostReverseProxy(u)
log.Printf("Listening at :8081")
if err := http.ListenAndServe(":8081", proxy); err != nil {
log.Fatal("ListenAndServe: %v", err)
}
}
最终,这些是相同的幕后实现,但此处提供的主管确保某些预期的 headers 存在,您需要这些代理功能才能按预期运行。