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.
 
 
 

100 lines
2.3 KiB

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/goamz/goamz/s3"
  5. "io"
  6. "os"
  7. "path/filepath"
  8. "strconv"
  9. )
  10. type Storage interface {
  11. Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error)
  12. Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error
  13. }
  14. type LocalStorage struct {
  15. Storage
  16. basedir string
  17. }
  18. func NewLocalStorage(basedir string) (*LocalStorage, error) {
  19. return &LocalStorage{basedir: basedir}, nil
  20. }
  21. func (s *LocalStorage) Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error) {
  22. path := filepath.Join(s.basedir, token, filename)
  23. // content type , content length
  24. if reader, err = os.Open(path); err != nil {
  25. return
  26. }
  27. var fi os.FileInfo
  28. if fi, err = os.Lstat(path); err != nil {
  29. }
  30. contentLength = uint64(fi.Size())
  31. contentType = ""
  32. return
  33. }
  34. func (s *LocalStorage) Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error {
  35. var f io.WriteCloser
  36. var err error
  37. path := filepath.Join(s.basedir, token)
  38. if err = os.Mkdir(path, 0700); err != nil && !os.IsExist(err) {
  39. return err
  40. }
  41. if f, err = os.OpenFile(filepath.Join(path, filename), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600); err != nil {
  42. fmt.Printf("%s", err)
  43. return err
  44. }
  45. defer f.Close()
  46. if _, err = io.Copy(f, reader); err != nil {
  47. return err
  48. }
  49. return nil
  50. }
  51. type S3Storage struct {
  52. Storage
  53. bucket *s3.Bucket
  54. }
  55. func NewS3Storage() (*S3Storage, error) {
  56. bucket, err := getBucket()
  57. if err != nil {
  58. return nil, err
  59. }
  60. return &S3Storage{bucket: bucket}, nil
  61. }
  62. func (s *S3Storage) Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error) {
  63. key := fmt.Sprintf("%s/%s", token, filename)
  64. // content type , content length
  65. response, err := s.bucket.GetResponse(key)
  66. contentType = ""
  67. contentLength, err = strconv.ParseUint(response.Header.Get("Content-Length"), 10, 0)
  68. reader = response.Body
  69. return
  70. }
  71. func (s *S3Storage) Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error {
  72. key := fmt.Sprintf("%s/%s", token, filename)
  73. err := s.bucket.PutReader(key, reader, int64(contentLength), contentType, s3.Private, s3.Options{})
  74. return err
  75. }