mirror of
https://github.com/hashicorp/vault.git
synced 2025-12-15 22:41:50 +01:00
physical/file: Handle file duplication case while updating
This commit is contained in:
parent
1a620fd5c0
commit
12f76f9e60
@ -52,8 +52,11 @@ func (b *FileBackend) Delete(path string) error {
|
||||
basePath, fileName := b.path(path)
|
||||
fullPath := filepath.Join(basePath, "_"+fileName)
|
||||
|
||||
// For backwards compatibility, try to delete the file without base64 URL
|
||||
// encoding the file name. If such a file does not exist, it could mean
|
||||
// that the file name is encoded. Try deleting the file with the encoded
|
||||
// file name.
|
||||
err := os.Remove(fullPath)
|
||||
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
fullPath = filepath.Join(basePath, "_"+base64.URLEncoding.EncodeToString([]byte(fileName)))
|
||||
err = os.Remove(fullPath)
|
||||
@ -109,8 +112,9 @@ func (b *FileBackend) Get(k string) (*Entry, error) {
|
||||
basePath, fileName := b.path(k)
|
||||
fullPath := filepath.Join(basePath, "_"+fileName)
|
||||
|
||||
// If non-encoded file name is a valid storage entry, read it out.
|
||||
// Otherwise, encode the file name and look for the storage entry.
|
||||
f, err := os.Open(fullPath)
|
||||
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
fullPath = filepath.Join(basePath, "_"+base64.URLEncoding.EncodeToString([]byte(fileName)))
|
||||
f, err = os.Open(fullPath)
|
||||
@ -133,19 +137,39 @@ func (b *FileBackend) Get(k string) (*Entry, error) {
|
||||
}
|
||||
|
||||
func (b *FileBackend) Put(entry *Entry) error {
|
||||
if entry == nil {
|
||||
return fmt.Errorf("nil entry")
|
||||
}
|
||||
|
||||
var err error
|
||||
basePath, fileName := b.path(entry.Key)
|
||||
|
||||
fileName = base64.URLEncoding.EncodeToString([]byte(fileName))
|
||||
// New storage entries will have their file names base64 URL encoded. If a
|
||||
// file with a non-encoded file name exists, it indicates that this is an
|
||||
// update operation. To avoid duplication of storage entries, delete the
|
||||
// old entry first.
|
||||
fullPath := filepath.Join(basePath, "_"+fileName)
|
||||
if _, err = os.Stat(fullPath); !os.IsNotExist(err) {
|
||||
err = b.Delete(entry.Key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to remove old entry: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
b.l.Lock()
|
||||
defer b.l.Unlock()
|
||||
|
||||
// Make the parent tree
|
||||
if err := os.MkdirAll(basePath, 0755); err != nil {
|
||||
if err = os.MkdirAll(basePath, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fullPath := filepath.Join(basePath, "_"+fileName)
|
||||
// base64 URL encode the file name to make all the characters compatible by
|
||||
// the host OS (specially Windows). However, the basePath can contain
|
||||
// disallowed characters. Encoding all the directory names and the file
|
||||
// name is an over kill, and encoding all at once will flatten the file
|
||||
// system, which *may* not be desire.
|
||||
fullPath = filepath.Join(basePath, "_"+base64.URLEncoding.EncodeToString([]byte(fileName)))
|
||||
|
||||
// JSON encode the entry and write it
|
||||
f, err := os.OpenFile(
|
||||
@ -188,6 +212,8 @@ func (b *FileBackend) List(prefix string) ([]string, error) {
|
||||
for i, name := range names {
|
||||
if name[0] == '_' {
|
||||
names[i] = name[1:]
|
||||
// If the file name is encoded, decode it to retain the list output
|
||||
// meaningful.
|
||||
nameDecodedBytes, err := base64.URLEncoding.DecodeString(names[i])
|
||||
if err == nil {
|
||||
names[i] = string(nameDecodedBytes)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user