Golang: how to read response body of ReverseProxy?

fannheyward picture fannheyward · Jul 21, 2015 · Viewed 13.2k times · Source
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?

Answer

Ainar-G picture Ainar-G · Jul 21, 2015

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.