Golang's http.FileSystem Implementation for AWS S3
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.

94 lines
1.8 KiB

package s3fs
import (
"bytes"
"errors"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
)
type file struct {
fs s3FileSystem
key string
reader *bytes.Reader
info os.FileInfo
}
func (fs s3FileSystem) NewFile(key string) (http.File, error) {
f := file{
fs: fs,
key: key,
}
// validate if the key/folder exists
if key == "/" || key == "." {
f.key = ""
f.info = fileinfo{
fs: &fs,
isDir: true,
key: "",
modTime: time.Now(),
size: 0,
}
return f, nil
}
// if it does not return with error
i, err := getInfo(fs.bucket, strings.TrimLeft(fs.prefix+key, "/"))
if err != nil {
return nil, os.ErrNotExist
}
f.info = i
if i.IsDir() {
return f, nil
}
s3ObjectOutput, err := s3svc.GetObject(&s3.GetObjectInput{
Bucket: aws.String(fs.bucket),
Key: aws.String(strings.TrimLeft(fs.prefix+key, "/")),
})
if err != nil {
return nil, err
}
defer s3ObjectOutput.Body.Close()
b, err := ioutil.ReadAll(s3ObjectOutput.Body)
if err != nil {
return nil, err
}
f.reader = bytes.NewReader(b)
// f.reader = s3ObjectOutput.Body
if err != nil {
return nil, os.ErrNotExist
}
return f, nil
}
func (f file) Close() error {
return nil
}
func (f file) Read(p []byte) (int, error) {
if f.reader != nil {
return f.reader.Read(p)
}
return 0, errors.New("invalid reader")
}
func (f file) Readdir(count int) ([]os.FileInfo, error) {
if f.key == "" || f.key == "/" {
return listObjects(f.fs.bucket, strings.TrimLeft(f.fs.prefix+f.key, "/"), "/")
}
return listObjects(f.fs.bucket, strings.TrimLeft(f.fs.prefix+f.key, "/")+"/", "/")
}
func (f file) Seek(offset int64, whence int) (int64, error) {
return f.reader.Seek(offset, whence)
}
func (f file) Stat() (os.FileInfo, error) {
return f.info, nil
}