Reading from Reader several times

I create a simple proxy server that intercepts HTTP requests, captures the contents in response.Body, and then writes it back to the client. The problem is that as soon as I read the answer. Body, the record back to the client contains an empty body (everything else, like the headers, is written as expected).

Here's the current code:

func requestHandler(w http.ResponseWriter, r *http.Request) {
    client := &http.Client{}
    r.RequestURI = ""
    response, err := client.Do(r)
    defer response.Body.Close()
    if err != nil {
        log.Fatal(err)
    }
    content, _ := ioutil.ReadAll(response.Body)
    cachePage(response.Request.URL.String(), content)
    response.Write(w)
}

If I delete the lines content, _and cachePageit works fine. With strings turned on, queries are returned and the body is empty. Any idea how I can only get Bodyin http.Responseand write a complete answer to http.ResponseWriter?

+4
source share
3 answers

. , .

response.Write(w)

. , . , .

.

ReverseProxy .

func requestHandler(w http.ResponseWriter, r *http.Request) {

    // No need to make a client, use the default
    // client := &http.Client{} 

    r.RequestURI = ""
    response, err := http.DefaultClient.Do(r)

    // response can be nil, close after error check
    // defer response.Body.Close() 

    if err != nil {
        log.Fatal(err)
    }
    defer response.Body.Close() 

    // Check errors! Always.
    // content, _ := ioutil.ReadAll(response.Body)
    content, err := ioutil.ReadAll(response.Body)
    if err != nil {
         // handle error
    }
    cachePage(response.Request.URL.String(), content)

    // The Write method writes the response in wire format to w.
    // Because the server handles the wire format, you need to do
    // copy the individual pieces.
    // response.Write(w)

    // Copy headers
    for k, v := range response.Header {
       w.Header()[k] = v
    }
    // Copy status code
    w.WriteHeader(response.StatusCode)

    // Write the response body.
    w.Write(content)
}
+1

, io.ReadCloser

Dewy Broto (), :

content, _ := ioutil.ReadAll(response.Body)
response.Body = ioutil.NopCloser(bytes.NewReader(content))
response.Write(w)
+5

All Articles