Torrent: Ranged requests so torrents work
This commit is contained in:
parent
3167ab7ff0
commit
9f7e6b6eea
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"time"
|
"time"
|
||||||
|
@ -82,6 +83,18 @@ func (b LocalfsBackend) Get(key string) (metadata backends.Metadata, f io.ReadCl
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b LocalfsBackend) ServeFile(key string, w http.ResponseWriter, r *http.Request) (err error) {
|
||||||
|
_, err = b.Head(key)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := path.Join(b.filesPath, key)
|
||||||
|
http.ServeFile(w, r, filePath)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (b LocalfsBackend) writeMetadata(key string, metadata backends.Metadata) error {
|
func (b LocalfsBackend) writeMetadata(key string, metadata backends.Metadata) error {
|
||||||
metaPath := path.Join(b.metaPath, key)
|
metaPath := path.Join(b.metaPath, key)
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package s3
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
@ -79,6 +80,43 @@ func (b S3Backend) Get(key string) (metadata backends.Metadata, r io.ReadCloser,
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b S3Backend) ServeFile(key string, w http.ResponseWriter, r *http.Request) (err error) {
|
||||||
|
var result *s3.GetObjectOutput
|
||||||
|
|
||||||
|
if r.Header.Get("Range") != "" {
|
||||||
|
result, err = b.svc.GetObject(&s3.GetObjectInput{
|
||||||
|
Bucket: aws.String(b.bucket),
|
||||||
|
Key: aws.String(key),
|
||||||
|
Range: aws.String(r.Header.Get("Range")),
|
||||||
|
})
|
||||||
|
|
||||||
|
w.WriteHeader(206)
|
||||||
|
w.Header().Set("Content-Range", *result.ContentRange)
|
||||||
|
w.Header().Set("Content-Length", strconv.FormatInt(*result.ContentLength, 10))
|
||||||
|
w.Header().Set("Accept-Ranges", "bytes")
|
||||||
|
|
||||||
|
} else {
|
||||||
|
result, err = b.svc.GetObject(&s3.GetObjectInput{
|
||||||
|
Bucket: aws.String(b.bucket),
|
||||||
|
Key: aws.String(key),
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if aerr, ok := err.(awserr.Error); ok {
|
||||||
|
if aerr.Code() == s3.ErrCodeNoSuchKey || aerr.Code() == "NotFound" {
|
||||||
|
err = backends.NotFoundErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(w, result.Body)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func mapMetadata(m backends.Metadata) map[string]*string {
|
func mapMetadata(m backends.Metadata) map[string]*string {
|
||||||
return map[string]*string{
|
return map[string]*string{
|
||||||
"Expiry": aws.String(strconv.FormatInt(m.Expiry.Unix(), 10)),
|
"Expiry": aws.String(strconv.FormatInt(m.Expiry.Unix(), 10)),
|
||||||
|
|
|
@ -3,6 +3,7 @@ package backends
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,6 +14,7 @@ type StorageBackend interface {
|
||||||
Get(key string) (Metadata, io.ReadCloser, error)
|
Get(key string) (Metadata, io.ReadCloser, error)
|
||||||
Put(key string, r io.Reader, expiry time.Time, deleteKey, accessKey string) (Metadata, error)
|
Put(key string, r io.Reader, expiry time.Time, deleteKey, accessKey string) (Metadata, error)
|
||||||
PutMetadata(key string, m Metadata) error
|
PutMetadata(key string, m Metadata) error
|
||||||
|
ServeFile(key string, w http.ResponseWriter, r *http.Request) error
|
||||||
Size(key string) (int64, error)
|
Size(key string) (int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
fileserve.go
11
fileserve.go
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -61,15 +60,11 @@ func fileServeHandler(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Method != "HEAD" {
|
if r.Method != "HEAD" {
|
||||||
_, reader, err := storageBackend.Get(fileName)
|
|
||||||
if err != nil {
|
|
||||||
oopsHandler(c, w, r, RespAUTO, "Unable to open file.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer reader.Close()
|
|
||||||
|
|
||||||
if _, err = io.CopyN(w, reader, metadata.Size); err != nil {
|
storageBackend.ServeFile(fileName, w, r)
|
||||||
|
if err != nil {
|
||||||
oopsHandler(c, w, r, RespAUTO, err.Error())
|
oopsHandler(c, w, r, RespAUTO, err.Error())
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue