mirror of
https://github.com/gmemstr/sliproad.git
synced 2024-09-19 16:11:11 +01:00
Implement SendFile() and ObjectInfo() for S3.
Also removed a now useless parameter for file providers, which used to be for writing directly to the HTTP response.
This commit is contained in:
parent
22e1df4bc7
commit
550e722a53
|
@ -140,7 +140,7 @@ func (bp *BackblazeProvider) GetDirectory(path string) Directory {
|
||||||
return finalDir
|
return finalDir
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bp *BackblazeProvider) SendFile(path string, w io.Writer) (stream io.Reader, contenttype string, err error) {
|
func (bp *BackblazeProvider) SendFile(path string) (stream io.Reader, contenttype string, err error) {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
// Get bucket name >:(
|
// Get bucket name >:(
|
||||||
bucketIdPayload := fmt.Sprintf(`{"accountId": "%s", "bucketId": "%s"}`, bp.Name, bp.Bucket)
|
bucketIdPayload := fmt.Sprintf(`{"accountId": "%s", "bucketId": "%s"}`, bp.Name, bp.Bucket)
|
||||||
|
|
|
@ -45,7 +45,7 @@ func (dp *DiskProvider) GetDirectory(path string) Directory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dp *DiskProvider) SendFile(path string, writer io.Writer) (stream io.Reader, contenttype string, err error) {
|
func (dp *DiskProvider) SendFile(path string) (stream io.Reader, contenttype string, err error) {
|
||||||
rp := strings.Join([]string{dp.Location,path}, "/")
|
rp := strings.Join([]string{dp.Location,path}, "/")
|
||||||
f, err := os.Open(rp)
|
f, err := os.Open(rp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -38,7 +38,7 @@ type FileInfo struct {
|
||||||
type FileProviderInterface interface {
|
type FileProviderInterface interface {
|
||||||
Setup(args map[string]string) (ok bool)
|
Setup(args map[string]string) (ok bool)
|
||||||
GetDirectory(path string) (directory Directory)
|
GetDirectory(path string) (directory Directory)
|
||||||
SendFile(path string, writer io.Writer) (stream io.Reader, contenttype string, err error)
|
SendFile(path string) (stream io.Reader, contenttype string, err error)
|
||||||
SaveFile(file io.Reader, filename string, path string) (ok bool)
|
SaveFile(file io.Reader, filename string, path string) (ok bool)
|
||||||
ObjectInfo(path string) (exists bool, isDir bool, location string)
|
ObjectInfo(path string) (exists bool, isDir bool, location string)
|
||||||
CreateDirectory(path string) (ok bool)
|
CreateDirectory(path string) (ok bool)
|
||||||
|
@ -58,7 +58,7 @@ func (f FileProvider) GetDirectory(path string) Directory {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteFile will bypass http.ServeContent() and instead write directly to the response.
|
// RemoteFile will bypass http.ServeContent() and instead write directly to the response.
|
||||||
func (f FileProvider) SendFile(path string, writer io.Writer) (stream io.Reader, contenttype string, err error) {
|
func (f FileProvider) SendFile(path string) (stream io.Reader, contenttype string, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
46
files/s3.go
46
files/s3.go
|
@ -3,6 +3,10 @@ package files
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"mime"
|
||||||
|
"path/filepath"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
// I _really_ don't want to deal with AWS API stuff by hand.
|
// I _really_ don't want to deal with AWS API stuff by hand.
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
|
@ -10,6 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var svc s3.S3
|
var svc s3.S3
|
||||||
|
var sess *session.Session
|
||||||
|
|
||||||
type S3Provider struct {
|
type S3Provider struct {
|
||||||
FileProvider
|
FileProvider
|
||||||
|
@ -40,6 +45,15 @@ func (s *S3Provider) GetDirectory(path string) Directory {
|
||||||
|
|
||||||
dir := Directory{}
|
dir := Directory{}
|
||||||
for _, item := range resp.Contents {
|
for _, item := range resp.Contents {
|
||||||
|
ik := *item.Key
|
||||||
|
// Why is this here? AWS returns a complete list of files, including
|
||||||
|
// files within subdirectories (prefixed with the dir name). So we can
|
||||||
|
// ignore directories altogether -- I would prefer to display them but
|
||||||
|
// not sure what the best method of distinguishing them in ObjectInfo()
|
||||||
|
// would be.
|
||||||
|
if ik[len(ik)-1:] == "/" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
file := FileInfo{
|
file := FileInfo{
|
||||||
IsDirectory: false,
|
IsDirectory: false,
|
||||||
Name: *item.Key,
|
Name: *item.Key,
|
||||||
|
@ -51,8 +65,23 @@ func (s *S3Provider) GetDirectory(path string) Directory {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteFile will bypass http.ServeContent() and instead write directly to the response.
|
// RemoteFile will bypass http.ServeContent() and instead write directly to the response.
|
||||||
func (s *S3Provider) SendFile(path string, writer io.Writer) (stream io.Reader, contenttype string, err error) {
|
func (s *S3Provider) SendFile(path string) (stream io.Reader, contenttype string, err error) {
|
||||||
return
|
req, err := svc.GetObject(&s3.GetObjectInput{
|
||||||
|
Bucket: &s.Bucket,
|
||||||
|
Key: &path,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return stream, contenttype, err
|
||||||
|
}
|
||||||
|
|
||||||
|
contenttype = mime.TypeByExtension(filepath.Ext(path))
|
||||||
|
if contenttype == "" {
|
||||||
|
var buf [512]byte
|
||||||
|
n, _ := io.ReadFull(req.Body, buf[:])
|
||||||
|
contenttype = http.DetectContentType(buf[:n])
|
||||||
|
}
|
||||||
|
|
||||||
|
return req.Body, contenttype, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveFile will save a file with the contents of the io.Reader at the path specified.
|
// SaveFile will save a file with the contents of the io.Reader at the path specified.
|
||||||
|
@ -64,7 +93,20 @@ func (s *S3Provider) SaveFile(file io.Reader, filename string, path string) bool
|
||||||
// Should return whether the path exists, if the path is a directory, and if it lives on disk.
|
// Should return whether the path exists, if the path is a directory, and if it lives on disk.
|
||||||
// (see constants defined: `FILE_IS_REMOTE` and `FILE_IS_LOCAL`)
|
// (see constants defined: `FILE_IS_REMOTE` and `FILE_IS_LOCAL`)
|
||||||
func (s *S3Provider) ObjectInfo(path string) (bool, bool, string) {
|
func (s *S3Provider) ObjectInfo(path string) (bool, bool, string) {
|
||||||
|
if path == "" {
|
||||||
return true, true, ""
|
return true, true, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := svc.GetObject(&s3.GetObjectInput{
|
||||||
|
Bucket: &s.Bucket,
|
||||||
|
Key: &path,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return false, false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, false, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateDirectory will create a directory on services that support it.
|
// CreateDirectory will create a directory on services that support it.
|
||||||
|
|
|
@ -50,7 +50,7 @@ func handleProvider() handler {
|
||||||
w.Write(data)
|
w.Write(data)
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
stream, contenttype, err := provider.SendFile(filename, w)
|
stream, contenttype, err := provider.SendFile(filename)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &httpError{
|
return &httpError{
|
||||||
|
|
Loading…
Reference in a new issue