lotus/extern/sector-storage/stores/http_handler.go

156 lines
3.2 KiB
Go
Raw Normal View History

2020-03-23 11:40:02 +00:00
package stores
import (
"encoding/json"
2020-03-23 11:40:02 +00:00
"io"
"net/http"
"os"
"github.com/gorilla/mux"
logging "github.com/ipfs/go-log/v2"
"golang.org/x/xerrors"
2020-03-27 23:21:36 +00:00
"github.com/filecoin-project/sector-storage/tarutil"
2020-03-23 11:40:02 +00:00
)
var log = logging.Logger("stores")
type FetchHandler struct {
*Local
}
func (handler *FetchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // /remote/
mux := mux.NewRouter()
mux.HandleFunc("/remote/stat/{id}", handler.remoteStatFs).Methods("GET")
2020-03-23 11:40:02 +00:00
mux.HandleFunc("/remote/{type}/{id}", handler.remoteGetSector).Methods("GET")
mux.HandleFunc("/remote/{type}/{id}", handler.remoteDeleteSector).Methods("DELETE")
mux.ServeHTTP(w, r)
}
func (handler *FetchHandler) remoteStatFs(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := ID(vars["id"])
st, err := handler.Local.FsStat(r.Context(), id)
switch err {
case errPathNotFound:
w.WriteHeader(404)
return
case nil:
break
default:
w.WriteHeader(500)
log.Errorf("%+v", err)
return
}
if err := json.NewEncoder(w).Encode(&st); err != nil {
log.Warnf("error writing stat response: %+v", err)
}
}
2020-03-23 11:40:02 +00:00
func (handler *FetchHandler) remoteGetSector(w http.ResponseWriter, r *http.Request) {
log.Infof("SERVE GET %s", r.URL)
vars := mux.Vars(r)
2020-03-26 02:50:56 +00:00
id, err := ParseSectorID(vars["id"])
2020-03-23 11:40:02 +00:00
if err != nil {
log.Error("%+v", err)
w.WriteHeader(500)
return
}
ft, err := ftFromString(vars["type"])
if err != nil {
log.Error("%+v", err)
2020-03-24 23:37:40 +00:00
w.WriteHeader(500)
2020-03-23 11:40:02 +00:00
return
}
2020-06-04 19:00:16 +00:00
// The caller has a lock on this sector already, no need to get one here
// passing 0 spt because we don't allocate anything
2020-07-06 14:13:42 +00:00
paths, _, err := handler.Local.AcquireSector(r.Context(), id, 0, ft, FTNone, PathStorage, AcquireMove)
2020-03-23 11:40:02 +00:00
if err != nil {
log.Error("%+v", err)
2020-03-24 23:37:40 +00:00
w.WriteHeader(500)
2020-03-23 11:40:02 +00:00
return
}
2020-07-06 16:36:44 +00:00
// TODO: reserve local storage here
2020-03-26 02:50:56 +00:00
path := PathByType(paths, ft)
2020-03-23 11:40:02 +00:00
if path == "" {
log.Error("acquired path was empty")
w.WriteHeader(500)
return
}
stat, err := os.Stat(path)
if err != nil {
log.Error("%+v", err)
w.WriteHeader(500)
return
}
var rd io.Reader
if stat.IsDir() {
rd, err = tarutil.TarDirectory(path)
w.Header().Set("Content-Type", "application/x-tar")
} else {
rd, err = os.OpenFile(path, os.O_RDONLY, 0644)
w.Header().Set("Content-Type", "application/octet-stream")
}
if err != nil {
log.Error("%+v", err)
w.WriteHeader(500)
return
}
w.WriteHeader(200)
if _, err := io.Copy(w, rd); err != nil { // TODO: default 32k buf may be too small
log.Error("%+v", err)
return
}
}
func (handler *FetchHandler) remoteDeleteSector(w http.ResponseWriter, r *http.Request) {
log.Infof("SERVE DELETE %s", r.URL)
vars := mux.Vars(r)
2020-03-26 02:50:56 +00:00
id, err := ParseSectorID(vars["id"])
2020-03-23 11:40:02 +00:00
if err != nil {
log.Error("%+v", err)
w.WriteHeader(500)
return
}
ft, err := ftFromString(vars["type"])
if err != nil {
log.Error("%+v", err)
2020-03-24 23:37:40 +00:00
w.WriteHeader(500)
2020-03-23 11:40:02 +00:00
return
}
2020-05-13 18:45:14 +00:00
if err := handler.Remove(r.Context(), id, ft, false); err != nil {
2020-03-23 11:40:02 +00:00
log.Error("%+v", err)
w.WriteHeader(500)
return
}
}
2020-03-26 02:50:56 +00:00
func ftFromString(t string) (SectorFileType, error) {
2020-03-23 11:40:02 +00:00
switch t {
2020-03-26 02:50:56 +00:00
case FTUnsealed.String():
return FTUnsealed, nil
case FTSealed.String():
return FTSealed, nil
case FTCache.String():
return FTCache, nil
2020-03-23 11:40:02 +00:00
default:
return 0, xerrors.Errorf("unknown sector file type: '%s'", t)
}
}