aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Majewsky <majewsky@gmx.net>2018-04-27 20:07:43 +0200
committerStefan Majewsky <majewsky@gmx.net>2018-04-27 20:07:43 +0200
commit55851ab5d1eb31f868ae45abdbdef152dd97b1ac (patch)
tree90ec997a28037bdf8ecb063e6aed1a9a02e11efd
parent30bbe06e039ae4e1de04c54ac82574afb81d5f69 (diff)
downloadgo-schwift-55851ab5d1eb31f868ae45abdbdef152dd97b1ac.tar.gz
tryCompute{ContentLength, Etag}: add special cases for strings.Reader, nil
-rw-r--r--object.go26
-rw-r--r--tests/object_test.go15
2 files changed, 31 insertions, 10 deletions
diff --git a/object.go b/object.go
index fb72aeb..8ef314a 100644
--- a/object.go
+++ b/object.go
@@ -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)