storage/filesystem: atomically check for IfNoneMatch
Using a separate os.Stat() call may result in a race where another request handler running concurrently creates the file in-between the os.Stat() call and the os.Create() call. Use O_EXCL to avoid this situation.
This commit is contained in:
parent
a3bfd56bf9
commit
228384530e
@ -425,13 +425,16 @@ func (b *filesystemBackend) PutAddressObject(ctx context.Context, objPath string
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO handle IfMatch
|
flags := os.O_RDWR | os.O_CREATE | os.O_TRUNC
|
||||||
if _, err := os.Stat(localPath); !os.IsNotExist(err) && opts.IfNoneMatch {
|
if opts.IfNoneMatch {
|
||||||
return "", carddav.NewPreconditionError(carddav.PreconditionNoUIDConflict)
|
flags |= os.O_EXCL
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.Create(localPath)
|
// TODO handle IfMatch
|
||||||
if err != nil {
|
f, err := os.OpenFile(localPath, flags, 0666)
|
||||||
|
if os.IsExist(err) {
|
||||||
|
return "", carddav.NewPreconditionError(carddav.PreconditionNoUIDConflict)
|
||||||
|
} else if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
@ -602,13 +605,16 @@ func (b *filesystemBackend) PutCalendarObject(ctx context.Context, objPath strin
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO handle IfMatch
|
flags := os.O_RDWR | os.O_CREATE | os.O_TRUNC
|
||||||
if _, err := os.Stat(localPath); !os.IsNotExist(err) && opts.IfNoneMatch {
|
if opts.IfNoneMatch {
|
||||||
return "", caldav.NewPreconditionError(caldav.PreconditionNoUIDConflict)
|
flags |= os.O_EXCL
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.Create(localPath)
|
// TODO handle IfMatch
|
||||||
if err != nil {
|
f, err := os.OpenFile(localPath, flags, 0666)
|
||||||
|
if os.IsExist(err) {
|
||||||
|
return "", caldav.NewPreconditionError(caldav.PreconditionNoUIDConflict)
|
||||||
|
} else if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
@ -620,5 +626,4 @@ func (b *filesystemBackend) PutCalendarObject(ctx context.Context, objPath strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
return objPath, nil
|
return objPath, nil
|
||||||
return "", nil
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user