Skip to content

Commit b8bc3a9

Browse files
committed
Remove bytecopy from GetBody
req.Body is already populated, and this, even on the first call, will write the payload again. Also adds a test guarding against the bug. Closes #130
1 parent 41e24cc commit b8bc3a9

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

client/request.go

-3
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,6 @@ func (r *request) buildHTTP(mediaType, basePath string, producers map[string]run
213213
return nil, err
214214
}
215215

216-
if _, err := r.buf.Write(b.Bytes()); err != nil {
217-
return nil, err
218-
}
219216
return ioutil.NopCloser(&b), nil
220217
}
221218

client/request_test.go

+81
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,14 @@ import (
1818
"bytes"
1919
"encoding/json"
2020
"encoding/xml"
21+
"errors"
22+
"io"
2123
"io/ioutil"
2224
"mime"
2325
"mime/multipart"
26+
"net/http"
27+
"net/http/httptest"
28+
"net/url"
2429
"os"
2530
"path/filepath"
2631
"strings"
@@ -29,6 +34,7 @@ import (
2934
"github.com/go-openapi/runtime"
3035
"github.com/go-openapi/strfmt"
3136
"github.com/stretchr/testify/assert"
37+
"github.com/stretchr/testify/require"
3238
)
3339

3440
var testProducers = map[string]runtime.Producer{
@@ -509,3 +515,78 @@ func TestBuildRequest_BuildHTTP_EscapedPath(t *testing.T) {
509515
assert.Equal(t, runtime.JSONMime, req.Header.Get(runtime.HeaderContentType))
510516
}
511517
}
518+
519+
type testReqFn func(*testing.T, *http.Request)
520+
521+
type testRoundTripper struct {
522+
tr http.RoundTripper
523+
testFn testReqFn
524+
testHarness *testing.T
525+
}
526+
527+
func (t *testRoundTripper) RoundTrip(req *http.Request) (resp *http.Response, err error) {
528+
t.testFn(t.testHarness, req)
529+
return t.tr.RoundTrip(req)
530+
}
531+
532+
func TestGetBodyCallsBeforeRoundTrip(t *testing.T) {
533+
534+
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
535+
rw.WriteHeader(http.StatusCreated)
536+
rw.Write([]byte("test result"))
537+
}))
538+
defer server.Close()
539+
hu, _ := url.Parse(server.URL)
540+
541+
client := http.DefaultClient
542+
transport := http.DefaultTransport
543+
544+
client.Transport = &testRoundTripper{
545+
tr: transport,
546+
testHarness: t,
547+
testFn: func(t *testing.T, req *http.Request) {
548+
// Read the body once before sending the request
549+
body, err := req.GetBody()
550+
require.NoError(t, err)
551+
bodyContent, err := ioutil.ReadAll(io.Reader(body))
552+
require.EqualValues(t, req.ContentLength, len(bodyContent))
553+
require.EqualValues(t, "\"test body\"\n", string(bodyContent))
554+
555+
// Read the body a second time before sending the request
556+
body, err = req.GetBody()
557+
require.NoError(t, err)
558+
bodyContent, err = ioutil.ReadAll(io.Reader(body))
559+
require.EqualValues(t, req.ContentLength, len(bodyContent))
560+
require.EqualValues(t, "\"test body\"\n", string(bodyContent))
561+
},
562+
}
563+
564+
rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
565+
return req.SetBodyParam("test body")
566+
})
567+
568+
operation := &runtime.ClientOperation{
569+
ID: "getSites",
570+
Method: "POST",
571+
PathPattern: "/",
572+
Params: rwrtr,
573+
Client: client,
574+
Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
575+
if response.Code() == http.StatusCreated {
576+
var result string
577+
if err := consumer.Consume(response.Body(), &result); err != nil {
578+
return nil, err
579+
}
580+
return result, nil
581+
}
582+
return nil, errors.New("Unexpected error code")
583+
}),
584+
}
585+
586+
openAPIClient := New(hu.Host, "/", []string{"http"})
587+
res, err := openAPIClient.Submit(operation)
588+
589+
require.NoError(t, err)
590+
actual := res.(string)
591+
require.EqualValues(t, "test result", actual)
592+
}

0 commit comments

Comments
 (0)