Browse Source

proxy: Reuse a bytes buffer as proxy request body.

The call to transport.RoundTrip closes the request body regardless of
the value of request.Closed. This causes subsequent calls to RoundTrip
using the same request body to fail.

Fixes #2895
Ryan Bourgeois 10 years ago
parent
commit
4e85f932e0
1 changed files with 20 additions and 1 deletions
  1. 20 1
      proxy/reverse.go

+ 20 - 1
proxy/reverse.go

@@ -15,8 +15,10 @@
 package proxy
 package proxy
 
 
 import (
 import (
+	"bytes"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
+	"io/ioutil"
 	"log"
 	"log"
 	"net"
 	"net"
 	"net/http"
 	"net/http"
@@ -55,6 +57,21 @@ func (p *reverseProxy) ServeHTTP(rw http.ResponseWriter, clientreq *http.Request
 	proxyreq := new(http.Request)
 	proxyreq := new(http.Request)
 	*proxyreq = *clientreq
 	*proxyreq = *clientreq
 
 
+	var (
+		proxybody []byte
+		err       error
+	)
+
+	if clientreq.Body != nil {
+		proxybody, err = ioutil.ReadAll(clientreq.Body)
+		if err != nil {
+			msg := fmt.Sprintf("proxy: failed to read request body: %v", err)
+			e := httptypes.NewHTTPError(http.StatusInternalServerError, msg)
+			e.WriteTo(rw)
+			return
+		}
+	}
+
 	// deep-copy the headers, as these will be modified below
 	// deep-copy the headers, as these will be modified below
 	proxyreq.Header = make(http.Header)
 	proxyreq.Header = make(http.Header)
 	copyHeader(proxyreq.Header, clientreq.Header)
 	copyHeader(proxyreq.Header, clientreq.Header)
@@ -93,9 +110,11 @@ func (p *reverseProxy) ServeHTTP(rw http.ResponseWriter, clientreq *http.Request
 	}
 	}
 
 
 	var res *http.Response
 	var res *http.Response
-	var err error
 
 
 	for _, ep := range endpoints {
 	for _, ep := range endpoints {
+		if proxybody != nil {
+			proxyreq.Body = ioutil.NopCloser(bytes.NewBuffer(proxybody))
+		}
 		redirectRequest(proxyreq, ep.URL)
 		redirectRequest(proxyreq, ep.URL)
 
 
 		res, err = p.transport.RoundTrip(proxyreq)
 		res, err = p.transport.RoundTrip(proxyreq)