Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read response body of ReverseProxy

Tags:

package main  import (     "net/http"     "net/http/httputil"     "net/url" )  func main() {     target := &url.URL{Scheme: "http", Host: "www.google.com"}     proxy := httputil.NewSingleHostReverseProxy(target)      http.Handle("/google", proxy)     http.ListenAndServe(":8099", nil) } 

Reverse Proxy is works. How can I get the response body?

like image 419
fannheyward Avatar asked Jul 21 '15 09:07

fannheyward


2 Answers

now httputil/reverseproxy, support than, see source

 type ReverseProxy struct {         ...          // ModifyResponse is an optional function that         // modifies the Response from the backend         // If it returns an error, the proxy returns a StatusBadGateway error.         ModifyResponse func(*http.Response) error     }    func rewriteBody(resp *http.Response) (err error) {     b, err := ioutil.ReadAll(resp.Body) //Read html     if err != nil {         return  err     }     err = resp.Body.Close()     if err != nil {         return err     }     b = bytes.Replace(b, []byte("server"), []byte("schmerver"), -1) // replace html     body := ioutil.NopCloser(bytes.NewReader(b))     resp.Body = body     resp.ContentLength = int64(len(b))     resp.Header.Set("Content-Length", strconv.Itoa(len(b)))     return nil }  // ... target, _ := url.Parse("http://example.com") proxy := httputil.NewSingleHostReverseProxy(target) proxy.ModifyResponse = rewriteBody 
like image 88
陈煜熙 Avatar answered Dec 05 '22 12:12

陈煜熙


httputil.ReverseProxy has a Transport field. You can use it to modify the response. For example:

type transport struct {     http.RoundTripper }  func (t *transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {     resp, err = t.RoundTripper.RoundTrip(req)     if err != nil {         return nil, err     }     b, err := ioutil.ReadAll(resp.Body)     if err != nil {         return nil, err     }     err = resp.Body.Close()     if err != nil {         return nil, err     }     b = bytes.Replace(b, []byte("server"), []byte("schmerver"), -1)     body := ioutil.NopCloser(bytes.NewReader(b))     resp.Body = body     resp.ContentLength = int64(len(b))     resp.Header.Set("Content-Length", strconv.Itoa(len(b)))     return resp, nil }  // ... proxy := httputil.NewSingleHostReverseProxy(target) proxy.Transport = &transport{http.DefaultTransport} 

Playground example of the whole thing: http://play.golang.org/p/b0S5CbCMrI.

like image 32
Ainar-G Avatar answered Dec 05 '22 11:12

Ainar-G