You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

130 lines
2.8 KiB

  1. package storage
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "log"
  8. "os"
  9. "path/filepath"
  10. )
  11. type LocalStorage struct {
  12. Storage
  13. basedir string
  14. logger *log.Logger
  15. }
  16. func NewLocalStorage(basedir string, logger *log.Logger) (*LocalStorage, error) {
  17. return &LocalStorage{basedir: basedir, logger: logger}, nil
  18. }
  19. func (s *LocalStorage) Type() string {
  20. return "local"
  21. }
  22. func (s *LocalStorage) Get(token string, filename string) (reader io.ReadCloser, metadata Metadata, err error) {
  23. path := filepath.Join(s.basedir, token, filename)
  24. // content type , content length
  25. reader, err = os.Open(path)
  26. if err != nil {
  27. return nil, Metadata{}, err
  28. }
  29. metadata, err = s.Head(token, filename)
  30. if err != nil {
  31. return nil, Metadata{}, err
  32. }
  33. return reader, metadata, nil
  34. }
  35. func (s *LocalStorage) Head(token string, filename string) (metadata Metadata, err error) {
  36. path := filepath.Join(s.basedir, token, filename)
  37. fi, err := os.Open(path)
  38. if err != nil {
  39. return
  40. }
  41. err = json.NewDecoder(fi).Decode(&metadata)
  42. if err != nil {
  43. return Metadata{}, err
  44. }
  45. return metadata, nil
  46. }
  47. func (s *LocalStorage) Meta(token string, filename string, metadata Metadata) error {
  48. return s.putMetadata(token, filename, metadata)
  49. }
  50. func (s *LocalStorage) Put(token string, filename string, reader io.Reader, metadata Metadata) error {
  51. err := s.putMetadata(token, filename, metadata)
  52. if err != nil {
  53. return err
  54. }
  55. err = s.put(token, filename, reader)
  56. if err != nil {
  57. //Delete the metadata if the put failed
  58. _ = s.Delete(token, fmt.Sprintf("%s.metadata", filename))
  59. }
  60. return err
  61. }
  62. func (s *LocalStorage) Delete(token string, filename string) (err error) {
  63. metadata := filepath.Join(s.basedir, token, fmt.Sprintf("%s.metadata", filename))
  64. _ = os.Remove(metadata)
  65. path := filepath.Join(s.basedir, token, filename)
  66. err = os.Remove(path)
  67. return
  68. }
  69. func (s *LocalStorage) IsNotExist(err error) bool {
  70. if err == nil {
  71. return false
  72. }
  73. return os.IsNotExist(err)
  74. }
  75. func (s *LocalStorage) DeleteExpired() error {
  76. return nil
  77. }
  78. func (s *LocalStorage) put(token string, filename string, reader io.Reader) error {
  79. var f io.WriteCloser
  80. var err error
  81. path := filepath.Join(s.basedir, token)
  82. if err = os.MkdirAll(path, 0700); err != nil && !os.IsExist(err) {
  83. return err
  84. }
  85. if f, err = os.OpenFile(filepath.Join(path, filename), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600); err != nil {
  86. return err
  87. }
  88. defer f.Close()
  89. _, err = io.Copy(f, reader)
  90. return err
  91. }
  92. func (s *LocalStorage) putMetadata(token string, filename string, metadata Metadata) error {
  93. buffer := &bytes.Buffer{}
  94. if err := json.NewEncoder(buffer).Encode(metadata); err != nil {
  95. log.Printf("%s", err.Error())
  96. return err
  97. } else if err := s.put(token, filename, buffer); err != nil {
  98. log.Printf("%s", err.Error())
  99. return nil
  100. }
  101. return nil
  102. }