2016年4月11日 星期一

讀取 http Body 而不會造成 proxy error: http: ContentLength=xx with Body length 0

如果想要看http request內容,看完以後再決定要不要代理到後端服務。要開一個 Proxy 的方法如下:

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。




沒有留言: