diff options
| -rw-r--r-- | object.go | 26 | ||||
| -rw-r--r-- | tests/object_test.go | 15 |
2 files changed, 31 insertions, 10 deletions
@@ -203,33 +203,47 @@ func (o *Object) Upload(content io.Reader, opts *RequestOptions) error { return nil } -//TODO add support for strings.Reader below +type readerWithLen interface { + //Returns the number of bytes in the unread portion of the buffer. + //Implemented by bytes.Reader, bytes.Buffer and strings.Reader. + Len() int +} func tryComputeContentLength(content io.Reader, headers ObjectHeaders) { h := headers.SizeBytes() if h.Exists() { return } - switch r := content.(type) { - case *bytes.Buffer: - h.Set(uint64(r.Len())) - case *bytes.Reader: + + if content == nil { + h.Set(0) + } else if r, ok := content.(readerWithLen); ok { h.Set(uint64(r.Len())) } } +//This covers both bytes.Reader and strings.Reader in a way that is compatible +//with earlier versions of Go that don't have strings.Reader yet. +type likeBytesReader interface { + io.WriterTo + io.Seeker +} + func tryComputeEtag(content io.Reader, headers ObjectHeaders) { h := headers.Etag() if h.Exists() { return } switch r := content.(type) { + case nil: + sum := md5.Sum(nil) + h.Set(hex.EncodeToString(sum[:])) case *bytes.Buffer: //bytes.Buffer has a method that returns the unread portion of the buffer, //so this one is easy sum := md5.Sum(r.Bytes()) h.Set(hex.EncodeToString(sum[:])) - case *bytes.Reader: + case likeBytesReader: //bytes.Reader does not have such a method, but it is an io.Seeker, so we //can read the entire thing and then seek back to where we started hash := md5.New() diff --git a/tests/object_test.go b/tests/object_test.go index b42294a..1bbf953 100644 --- a/tests/object_test.go +++ b/tests/object_test.go @@ -23,6 +23,7 @@ import ( "io" "io/ioutil" "net/http" + "strings" "testing" "github.com/majewsky/schwift" @@ -75,14 +76,20 @@ func TestObjectUpload(t *testing.T) { expectSuccess(t, err) expectObjectContent(t, obj, objectExampleContent) - //test upload with opaque io.Reader + //test upload with strings.Reader obj = c.Object("upload3") + err = obj.Upload(strings.NewReader(string(objectExampleContent)), nil) + expectSuccess(t, err) + expectObjectContent(t, obj, objectExampleContent) + + //test upload with opaque io.Reader + obj = c.Object("upload4") err = obj.Upload(opaqueReader{bytes.NewReader(objectExampleContent)}, nil) expectSuccess(t, err) expectObjectContent(t, obj, objectExampleContent) //test upload with io.Writer - obj = c.Object("upload4") + obj = c.Object("upload5") err = obj.UploadWithWriter(nil, func(w io.Writer) error { _, err := w.Write(objectExampleContent) return err @@ -91,13 +98,13 @@ func TestObjectUpload(t *testing.T) { expectObjectContent(t, obj, objectExampleContent) //test upload with empty reader (should create zero-byte-sized object) - obj = c.Object("upload5") + obj = c.Object("upload6") err = obj.Upload(eofReader{}, nil) expectSuccess(t, err) expectObjectContent(t, obj, nil) //test upload without reader (should create zero-byte-sized object) - obj = c.Object("upload6") + obj = c.Object("upload7") err = obj.Upload(nil, nil) expectSuccess(t, err) expectObjectContent(t, obj, nil) |
