director := func(req *http.Request) { req = r req.URL.Scheme = "http" req.URL.Host = "localhost:2379"} proxy := &httputil.ReverseProxy{Director: director} proxy.ServeHTTP(w, r)
在Proxy之前,如果要讀取request body,需要使用ReadAll來把Body讀出來,像這樣子
body,err:=ioutil.ReadAll(reader)
ReadAll返回了資料以後,Body的索引也都會改變。這時去呼叫Proxy的程序則會產生這樣的錯誤: http: proxy error: http: ContentLength=153 with Body length 0
下面的方式是可以讀取Body,而且又不影響到Proxy運作:
b := bytes.NewBuffer(make([]byte, 0)) reader := io.TeeReader(r.Body, b) body,err:=ioutil.ReadAll(reader) if err != nil { Error(err) return}
r.Body = ioutil.NopCloser(b)
為了讓Proxy能夠繼續運作,TeeReader從r.Body複製資料到b裡面並返回一個Reader。過程中不會有其他資料的複製。最後再把複製的資料b放回去r.Body。