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.
170 lines
3.4 KiB
170 lines
3.4 KiB
package localfs
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"os"
|
|
"path"
|
|
|
|
"github.com/andreimarcu/linx-server/backends"
|
|
"github.com/andreimarcu/linx-server/torrent"
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/aws/session"
|
|
"github.com/aws/aws-sdk-go/service/s3"
|
|
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
|
"github.com/zeebo/bencode"
|
|
)
|
|
|
|
type S3Backend struct {
|
|
bucket string
|
|
svc *S3
|
|
}
|
|
|
|
func (b S3Backend) Delete(key string) error {
|
|
input := &s3.DeleteObjectInput{
|
|
Bucket: aws.String(b.bucket),
|
|
Key: aws.String(key),
|
|
}
|
|
_, err := b.svc.DeleteObject(input)
|
|
return os.Remove(path.Join(b.bucket, key))
|
|
}
|
|
|
|
func (b S3Backend) Exists(key string) (bool, error) {
|
|
input := &s3.HeadObjectInput{
|
|
Bucket: aws.String(b.bucket),
|
|
Key: aws.String(key),
|
|
}
|
|
_, err := b.svc.HeadObject(input)
|
|
return err == nil, err
|
|
}
|
|
|
|
func (b S3Backend) Get(key string) ([]byte, error) {
|
|
input := &s3.GetObjectInput{
|
|
Bucket: aws.String(b.bucket),
|
|
Key: aws.String(key),
|
|
}
|
|
result, err := b.svc.GetObject(input)
|
|
if err != nil {
|
|
return []byte{}, err
|
|
}
|
|
defer result.Body.Close()
|
|
|
|
return ioutil.ReadAll(result.Body)
|
|
}
|
|
|
|
func (b S3Backend) Put(key string, r io.Reader) (int64, error) {
|
|
uploader := s3manager.NewUploaderWithClient(b.svc)
|
|
input := &s3manager.UploadInput{
|
|
Bucket: aws.String(b.bucket),
|
|
Key: aws.String(key),
|
|
Body: r,
|
|
}
|
|
result, err := uploader.Upload(input)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return -1, nil
|
|
}
|
|
|
|
func (b S3Backend) Open(key string) (backends.ReadSeekCloser, error) {
|
|
input := &s3.GetObjectInput{
|
|
Bucket: aws.String(b.bucket),
|
|
Key: aws.String(key),
|
|
}
|
|
result, err := b.svc.GetObject(input)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return result.Body, nil
|
|
}
|
|
|
|
func (b S3Backend) ServeFile(key string, w http.ResponseWriter, r *http.Request) {
|
|
input := &s3.GetObjectInput{
|
|
Bucket: aws.String(b.bucket),
|
|
Key: aws.String(key),
|
|
}
|
|
result, err := b.svc.GetObject(input)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer result.Body.Close()
|
|
|
|
http.ServeContent(w, r, key, *result.LastModified, result.Body)
|
|
return nil
|
|
}
|
|
|
|
func (b S3Backend) Size(key string) (int64, error) {
|
|
input := &s3.HeadObjectInput{
|
|
Bucket: aws.String(b.bucket),
|
|
Key: aws.String(key),
|
|
}
|
|
result, err := b.svc.HeadObject(input)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return *result.ContentLength, nil
|
|
}
|
|
|
|
func (b S3Backend) GetTorrent(fileName string, url string) (t torrent.Torrent, err error) {
|
|
input := &s3.GetObjectTorrentInput{
|
|
Bucket: aws.String(b.bucket),
|
|
Key: aws.String(fileName),
|
|
}
|
|
result, err := b.svc.GetObjectTorrent(input)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer result.Body.Close()
|
|
|
|
data, err := ioutil.ReadAll(result.Body)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
err = bencode.DecodeBytes(data, &t)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
t.Info.Name = fileName
|
|
t.UrlList = []string{url}
|
|
return
|
|
}
|
|
|
|
func (b S3Backend) List() ([]string, error) {
|
|
var output []string
|
|
input := &s3.ListObjectsInput{
|
|
bucket: aws.String(b.bucket),
|
|
}
|
|
|
|
results, err := b.svc.ListObjects(input)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
|
|
for _, object := range results.Contents {
|
|
output = append(output, *object.Key)
|
|
}
|
|
|
|
return output, nil
|
|
}
|
|
|
|
func NewS3Backend(bucket string, region string, endpoint string) S3Backend {
|
|
awsConfig := &aws.Config{}
|
|
if region != "" {
|
|
awsConfig.Region = aws.String(region)
|
|
}
|
|
if endpoint != "" {
|
|
awsConfig.Endpoint = aws.String(endpoint)
|
|
}
|
|
|
|
sess := session.Must(session.NewSession(awsConfig))
|
|
svc := s3.New(sess)
|
|
return S3Backend{bucket: bucket, svc: svc}
|
|
}
|