Skip to content

Commit

Permalink
write out content length for http request (#405)
Browse files Browse the repository at this point in the history
Signed-off-by: Scott Nichols <snichols@vmware.com>
  • Loading branch information
n3wscott committed Mar 19, 2020
1 parent 213563f commit ecc0ec7
Showing 1 changed file with 57 additions and 4 deletions.
61 changes: 57 additions & 4 deletions v2/protocol/http/write_request.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package http

import (
"bytes"
"context"
"io"
"io/ioutil"
"net/http"
"strings"

"github.com/cloudevents/sdk-go/v2/binding"
"github.com/cloudevents/sdk-go/v2/binding/format"
Expand Down Expand Up @@ -32,8 +34,7 @@ type httpRequestWriter http.Request

func (b *httpRequestWriter) SetStructuredEvent(ctx context.Context, format format.Format, event io.Reader) error {
b.Header.Set(ContentType, format.MediaType())
b.Body = ioutil.NopCloser(event)
return nil
return b.setBody(event)
}

func (b *httpRequestWriter) Start(ctx context.Context) error {
Expand All @@ -44,8 +45,60 @@ func (b *httpRequestWriter) End(ctx context.Context) error {
return nil
}

func (b *httpRequestWriter) SetData(reader io.Reader) error {
b.Body = ioutil.NopCloser(reader)
func (b *httpRequestWriter) SetData(data io.Reader) error {
return b.setBody(data)
}

// setBody is a cherry-pick of the implementation in http.NewRequestWithContext
func (b *httpRequestWriter) setBody(body io.Reader) error {
rc, ok := body.(io.ReadCloser)
if !ok && body != nil {
rc = ioutil.NopCloser(body)
}
b.Body = rc
if body != nil {
switch v := body.(type) {
case *bytes.Buffer:
b.ContentLength = int64(v.Len())
buf := v.Bytes()
b.GetBody = func() (io.ReadCloser, error) {
r := bytes.NewReader(buf)
return ioutil.NopCloser(r), nil
}
case *bytes.Reader:
b.ContentLength = int64(v.Len())
snapshot := *v
b.GetBody = func() (io.ReadCloser, error) {
r := snapshot
return ioutil.NopCloser(&r), nil
}
case *strings.Reader:
b.ContentLength = int64(v.Len())
snapshot := *v
b.GetBody = func() (io.ReadCloser, error) {
r := snapshot
return ioutil.NopCloser(&r), nil
}
default:
// This is where we'd set it to -1 (at least
// if body != NoBody) to mean unknown, but
// that broke people during the Go 1.8 testing
// period. People depend on it being 0 I
// guess. Maybe retry later. See Issue 18117.
}
// For client requests, Request.ContentLength of 0
// means either actually 0, or unknown. The only way
// to explicitly say that the ContentLength is zero is
// to set the Body to nil. But turns out too much code
// depends on NewRequest returning a non-nil Body,
// so we use a well-known ReadCloser variable instead
// and have the http package also treat that sentinel
// variable to mean explicitly zero.
if b.GetBody != nil && b.ContentLength == 0 {
b.Body = http.NoBody
b.GetBody = func() (io.ReadCloser, error) { return http.NoBody, nil }
}
}
return nil
}

Expand Down

0 comments on commit ecc0ec7

Please sign in to comment.