b2: Fix parsing of mod time when not in metadata

This files this error `Failed to parse mod time string "":
"src_last_modified_millis" not found in metadata`.
This commit is contained in:
Nick Craig-Wood 2016-03-22 10:26:37 +00:00
parent 0dc0052e93
commit 37543bd1d9
2 changed files with 28 additions and 28 deletions

View File

@ -751,28 +751,19 @@ func timeString(modTime time.Time) string {
} }
// parseTimeString converts a decimal string number of milliseconds // parseTimeString converts a decimal string number of milliseconds
// elapsed since January 1, 1970 UTC into a time.Time // elapsed since January 1, 1970 UTC into a time.Time and stores it in
func parseTimeString(timeString string) (result time.Time, err error) { // the modTime variable.
func (o *Object) parseTimeString(timeString string) (err error) {
if timeString == "" { if timeString == "" {
return result, fmt.Errorf("%q not found in metadata", timeKey) return nil
} }
unixMilliseconds, err := strconv.ParseInt(timeString, 10, 64) unixMilliseconds, err := strconv.ParseInt(timeString, 10, 64)
if err != nil { if err != nil {
return result, err fs.Debug(o, "Failed to parse mod time string %q: %v", timeString, err)
return err
} }
return time.Unix(unixMilliseconds/1E3, (unixMilliseconds%1E3)*1E6).UTC(), nil o.modTime = time.Unix(unixMilliseconds/1E3, (unixMilliseconds%1E3)*1E6).UTC()
} return nil
// ModTime returns the modification time of the object
//
// It attempts to read the objects mtime and if that isn't present the
// LastModified returned in the http headers
//
// SHA-1 will also be updated once the request has completed.
func (o *Object) ModTime() (result time.Time) {
// The error is logged in readFileMetadata
_ = o.readFileMetadata()
return o.modTime
} }
// readFileMetadata attempts to read the modified time and // readFileMetadata attempts to read the modified time and
@ -822,17 +813,26 @@ func (o *Object) readFileMetadata() error {
o.sha1 = response.SHA1 o.sha1 = response.SHA1
// Parse the result // Parse the result
timeString := response.Info[timeKey] err = o.parseTimeString(response.Info[timeKey])
parsed, err := parseTimeString(timeString)
if err != nil { if err != nil {
fs.Debug(o, "Failed to parse mod time string %q: %v", timeString, err)
return err return err
} }
o.modTime = parsed
return nil return nil
} }
// ModTime returns the modification time of the object
//
// It attempts to read the objects mtime and if that isn't present the
// LastModified returned in the http headers
//
// SHA-1 will also be updated once the request has completed.
func (o *Object) ModTime() (result time.Time) {
// The error is logged in readFileMetadata
_ = o.readFileMetadata()
return o.modTime
}
// SetModTime sets the modification time of the local fs object // SetModTime sets the modification time of the local fs object
func (o *Object) SetModTime(modTime time.Time) { func (o *Object) SetModTime(modTime time.Time) {
// Not possible with B2 // Not possible with B2
@ -920,12 +920,10 @@ func (o *Object) Open() (in io.ReadCloser, err error) {
} }
// Parse the time out of the headers if possible // Parse the time out of the headers if possible
timeString := resp.Header.Get(timeHeader) err = o.parseTimeString(resp.Header.Get(timeHeader))
parsed, err := parseTimeString(timeString)
if err != nil { if err != nil {
fs.Debug(o, "Failed to parse mod time string %q: %v", timeString, err) _ = resp.Body.Close()
} else { return nil, err
o.modTime = parsed
} }
if o.sha1 == "" { if o.sha1 == "" {
o.sha1 = resp.Header.Get(sha1Header) o.sha1 = resp.Header.Get(sha1Header)

View File

@ -149,10 +149,12 @@ func TestParseTimeString(t *testing.T) {
}{ }{
{"0", fstest.Time("1970-01-01T00:00:00.000000000Z"), ""}, {"0", fstest.Time("1970-01-01T00:00:00.000000000Z"), ""},
{"981173110123", fstest.Time("2001-02-03T04:05:10.123000000Z"), ""}, {"981173110123", fstest.Time("2001-02-03T04:05:10.123000000Z"), ""},
{"", time.Time{}, `"src_last_modified_millis" not found in metadata`}, {"", time.Time{}, ""},
{"potato", time.Time{}, `strconv.ParseInt: parsing "potato": invalid syntax`}, {"potato", time.Time{}, `strconv.ParseInt: parsing "potato": invalid syntax`},
} { } {
got, err := parseTimeString(test.in) o := Object{}
err := o.parseTimeString(test.in)
got := o.modTime
var gotError string var gotError string
if err != nil { if err != nil {
gotError = err.Error() gotError = err.Error()