title: Repeating an http.Request multiple times inside a reverse proxy
body: <p>I'm implementing a <a href="https://golang.org/pkg/net/http/#RoundTripper" rel="nofollow noreferrer">http.RoundTripper</a> in Go, and as part of <a href="https://golang.org/pkg/net/http/httputil/#ReverseProxy" rel="nofollow noreferrer">httputil.ReverseProxy</a> implementation.</p>
  
  <p>I need to buffer an incoming request, and repeat it several times, depending on the response I get from the backend. To do this, I use <a href="https://golang.org/pkg/net/http/#Request.Write" rel="nofollow noreferrer">request.Write</a> and <a href="https://golang.org/pkg/net/http/#ReadRequest" rel="nofollow noreferrer">http.ReadRequest</a>. (I am actually not sure if this is a good idea, if there are any better ways, I'm interested.)</p>
  
  <p>After deserializing request from <code>[]byte</code> with <a href="https://golang.org/pkg/net/http/#ReadRequest" rel="nofollow noreferrer">http.ReadRequest</a> and repeat it using the http.DefaultTransport’s roundtripper, I get this printed in my stderr:</p>
  
  <pre><code>2019/08/01 14:35:51 http: proxy error: unsupported protocol scheme ""
  </code></pre>
  
  <p>So it looks like for some reason I need to set <code>req.URL</code> again after deserializing to make it work.</p>
  
  <p>Here's roughly how my code looks like:</p>
  
  <pre class="lang-golang prettyprint-override"><code>func (s *myServer) RoundTrip(origReq *http.Request) (*http.Response, error) {
      var b bytes.Buffer
      if err := origReq.Write(&amp;b); err != nil {
          return nil, errors.Wrap(err,"failed to buffer request")
      }
      for retries := 0; retries &lt; s.maxRetries; retries++{
          req, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(b.Bytes()))) // probably can be simplified
          if err != nil {
              return nil, errors.Wrap(err,"failed to un-buffer request")
          }
          req.URL = origReq.URL // &lt;-- why is this necessary?
  
          resp, err := http.DefaultTransport.RoundTrip(req)
          if err != nil {
              return resp, err
          }
          if needRepeat(resp) {
              continue
          }
          return resp, nil
      }
  }
  </code></pre>