diff --git a/s3util/uploader.go b/s3util/uploader.go index 1a21511..49fa918 100644 --- a/s3util/uploader.go +++ b/s3util/uploader.go @@ -3,15 +3,17 @@ package s3util import ( "bytes" "encoding/xml" - "github.com/kr/s3" "fmt" "io" "net/http" "net/url" "strconv" + "strings" "sync" "syscall" "time" + + "github.com/kr/s3" ) // defined by amazon @@ -190,11 +192,14 @@ func (u *uploader) putPart(p *part) error { if resp.StatusCode != 200 { return newRespError(resp) } - s := resp.Header.Get("etag") // includes quote chars for some reason - if len(s) < 2 { - return fmt.Errorf("received invalid etag %q", s) + + s := resp.Header.Get("etag") + s = strings.Trim(s, `"`) // includes quote chars for some reason + if s == "" { + return fmt.Errorf("received empty etag") } - p.ETag = s[1 : len(s)-1] + p.ETag = s + return nil } diff --git a/s3util/uploader_test.go b/s3util/uploader_test.go index 77adbe8..ff32dd4 100644 --- a/s3util/uploader_test.go +++ b/s3util/uploader_test.go @@ -127,37 +127,44 @@ func TestEmptyEtag(t *testing.T) { t.Fatal("uploader panic", err) } }() - body := readClose{ - strings.NewReader(`foo`), - make(closeCounter, 100), - } - c := *DefaultConfig - c.Client = &http.Client{ - Transport: RoundTripperFunc(func(req *http.Request) (*http.Response, error) { - resp := &http.Response{ - StatusCode: 200, - Body: body, - Header: http.Header{ - "Etag": {""}, - }, - } - return resp, nil - }), - } - u, err := newUploader("https://s3.amazonaws.com/foo/bar", nil, &c) - if err != nil { - t.Fatal("unexpected err", err) - } - const size = minPartSize + minPartSize/3 - n, err := io.Copy(u, io.LimitReader(devZero, size)) - if err == nil || err.Error() != `received invalid etag ""` { - t.Fatalf("expected err: %q", err) - } - if n != minPartSize { - t.Fatalf("wrote %d bytes want %d", n, minPartSize) + + testEmptyEtag := func(emptyEtag string) { + body := readClose{ + strings.NewReader(`foo`), + make(closeCounter, 100), + } + c := *DefaultConfig + c.Client = &http.Client{ + Transport: RoundTripperFunc(func(req *http.Request) (*http.Response, error) { + resp := &http.Response{ + StatusCode: 200, + Body: body, + Header: http.Header{ + "Etag": []string{emptyEtag}, + }, + } + return resp, nil + }), + } + u, err := newUploader("https://s3.amazonaws.com/foo/bar", nil, &c) + if err != nil { + t.Fatal("unexpected err", err) + } + const size = minPartSize + minPartSize/3 + n, err := io.Copy(u, io.LimitReader(devZero, size)) + if err == nil || err.Error() != `received empty etag` { + t.Fatalf("expected err: %q", err) + } + if n != minPartSize { + t.Fatalf("wrote %d bytes want %d", n, minPartSize) + } + err = u.Close() + if err == nil || err.Error() != `received empty etag` { + t.Fatalf("expected err: %q", err) + } } - err = u.Close() - if err == nil || err.Error() != `received invalid etag ""` { - t.Fatalf("expected err: %q", err) + + for _, emptyEtag := range []string{"", `""`} { + testEmptyEtag(emptyEtag) } }