feat: implement /s5/download/:cid

This commit is contained in:
Derrick Hammer 2024-01-24 01:27:05 -05:00
parent 12093637ed
commit 22eacc4af1
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
2 changed files with 45 additions and 0 deletions

View File

@ -54,6 +54,7 @@ func getRoutes(h *s5.HttpHandler, portal interfaces.Portal) map[string]jape.Hand
// Download API
"GET /s5/blob/:cid": middleware.ApplyMiddlewares(h.DownloadBlob, middleware.AuthMiddleware(portal)),
"GET /s5/metadata/:cid": h.DownloadMetadata,
"GET /s5/download/:cid": middleware.ApplyMiddlewares(h.DownloadFile, middleware.AuthMiddleware(portal)),
// Pins API
"POST /s5/pin/:cid": middleware.ApplyMiddlewares(h.AccountPin, middleware.AuthMiddleware(portal)),

View File

@ -48,6 +48,7 @@ const (
errFailedToAddPin = "Failed to add pin"
errorNotMultiform = "Not a multipart form"
errFetchingUrls = "Error fetching urls"
errDownloadingFile = "Error downloading file"
)
var (
@ -68,6 +69,7 @@ var (
errFailedToAddPinErr = errors.New(errFailedToAddPin)
errNotMultiformErr = errors.New(errorNotMultiform)
errFetchingUrlsErr = errors.New(errFetchingUrls)
errDownloadingFileErr = errors.New(errDownloadingFile)
)
type HttpHandler struct {
@ -1257,6 +1259,7 @@ func (h *HttpHandler) DownloadMetadata(jc jape.Context) {
cidDecoded, err := encoding.CIDFromString(cid)
if jc.Check("error decoding cid", err) != nil {
h.portal.Logger().Error("error decoding cid", zap.Error(err))
return
}
@ -1273,6 +1276,7 @@ func (h *HttpHandler) DownloadMetadata(jc jape.Context) {
meta, err := h.getNode().GetMetadataByCID(cidDecoded)
if jc.Check("error getting metadata", err) != nil {
h.portal.Logger().Error("error getting metadata", zap.Error(err))
return
}
@ -1286,6 +1290,46 @@ func (h *HttpHandler) DownloadMetadata(jc jape.Context) {
}
func (h *HttpHandler) DownloadFile(jc jape.Context) {
var cid string
if jc.DecodeParam("cid", &cid) != nil {
return
}
cidDecoded, err := encoding.CIDFromString(cid)
if jc.Check("error decoding cid", err) != nil {
return
}
file, fileSize, err := h.portal.Storage().GetFile(cidDecoded.Hash.HashBytes())
if jc.Check("error getting file", err) != nil {
return
}
defer func(file io.ReadCloser) {
err := file.Close()
if err != nil {
h.portal.Logger().Error("error closing file", zap.Error(err))
}
}(file)
mimeBuffer := make([]byte, 512)
if _, err := file.Read(mimeBuffer); err != nil {
_ = jc.Error(errUploadingFileErr, http.StatusInternalServerError)
return
}
contentType := http.DetectContentType(mimeBuffer)
jc.ResponseWriter.Header().Set("Content-Type", contentType)
jc.ResponseWriter.Header().Set("Content-Length", strconv.FormatUint(fileSize, 10))
jc.ResponseWriter.Header().Set("Cache-Control", "public, max-age=31536000")
jc.ResponseWriter.WriteHeader(http.StatusOK)
_, _ = jc.ResponseWriter.Write(mimeBuffer)
_, _ = io.Copy(jc.ResponseWriter, file)
}
func setAuthCookie(jwt string, jc jape.Context) {
authCookie := http.Cookie{
Name: "s5-auth-token",