i want get a Request , and use ParseForm to check some data , then send the same one to proxy , buy if i do that , we have a problem
error log like this
2020/05/26 15:34:47 http: proxy error: net/http: HTTP/1.x transport connection broken: http: ContentLength=32 with Body length 0
so I finally figured it out , ParseForm () well close Request .body
and this is work proxy code
url, _ := url.Parse(config.GetGameHost())
proxy := httputil.NewSingleHostReverseProxy(url)
r.URL.Host = url.Host
r.URL.Scheme = url.Scheme
r.Header.Set("X-Forwarded-Host", r.Header.Get("Host"))
r.Host = url.Host
proxy.ServeHTTP(w, r)
so , i think i need clone the deep clone request too get my data and send origin request too proxy i edit my code too this
nr := r.Clone(r.Context())
nr.ParseForm()
url, _ := url.Parse(config.GetGameHost())
proxy := httputil.NewSingleHostReverseProxy(url)
r.URL.Host = url.Host
r.URL.Scheme = url.Scheme
r.Header.Set("X-Forwarded-Host", r.Header.Get("Host"))
r.Host = url.Host
proxy.ServeHTTP(w, r)
and the error log show again
2020/05/26 15:49:29 http: proxy error: net/http: HTTP/1.x transport connection broken: http: ContentLength=32 with Body length 0
is the Clone() are not deep clone or i do wrong?
------------ this work------------
body, err := ioutil.ReadAll(r.Body)
if err != nil {
// ...
}
url, _ := url.Parse(config.GetGameHost())
r2 := r.Clone(r.Context())
r.Body = ioutil.NopCloser(bytes.NewReader(body))
r2.Body = ioutil.NopCloser(bytes.NewReader(body))
r.ParseForm()
proxy := httputil.NewSingleHostReverseProxy(url)
proxy.ServeHTTP(w, r2)
http.Request.Body can only be read once, a new body needs to be copied.
body,err := ioutil.ReadAll(r)
if err != nil {
// ...
}
r2 := r.Clone(r.Context())
// clone body
r.Body = ioutil.NopCloser(bytes.NewReader(body))
r2.Body = ioutil.NopCloser(bytes.NewReader(body))
// parse r1, proxy r2
r.ParseForm()
proxy.ServerHTTP(w, r2)
The body object defaults to net.Conn multi-layer encapsulation. Each time it uses the io.Reader interface to read 4kb, saving memory usage, it is generally used while reading from the network.
Therefore, the body can only be read from the network once. If you want the body object to be read repeatedly, you should read it all, save it, and use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With