portal/protocols/s5/http.go

142 lines
3.5 KiB
Go
Raw Normal View History

2024-01-15 04:54:43 +00:00
package s5
import (
"bytes"
"errors"
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
s5interface "git.lumeweb.com/LumeWeb/libs5-go/interfaces"
2024-01-15 19:41:24 +00:00
"git.lumeweb.com/LumeWeb/libs5-go/types"
2024-01-15 04:54:43 +00:00
"git.lumeweb.com/LumeWeb/portal/interfaces"
"go.sia.tech/jape"
"go.uber.org/zap"
"io"
"mime/multipart"
"net/http"
"strings"
2024-01-15 04:54:43 +00:00
)
var (
_ s5interface.HTTPHandler = (*HttpHandlerImpl)(nil)
)
const (
errMultiformParse = "Error parsing multipart form"
errRetrievingFile = "Error retrieving the file"
errReadFile = "Error reading the file"
errClosingStream = "Error closing the stream"
errUploadingFile = "Error uploading the file"
)
var (
errUploadingFileErr = errors.New(errUploadingFile)
)
type HttpHandlerImpl struct {
portal interfaces.Portal
}
func NewHttpHandler(portal interfaces.Portal) *HttpHandlerImpl {
return &HttpHandlerImpl{portal: portal}
}
func (h *HttpHandlerImpl) SmallFileUpload(jc *jape.Context) {
2024-01-15 20:16:48 +00:00
var rs io.ReadSeeker
var bufferSize int64
2024-01-15 04:54:43 +00:00
r := jc.Request
contentType := r.Header.Get("Content-Type")
if strings.HasPrefix(contentType, "multipart/form-data") {
2024-01-15 04:54:43 +00:00
// Parse the multipart form
err := r.ParseMultipartForm(h.portal.Config().GetInt64("core.post-upload-limit"))
if jc.Check(errMultiformParse, err) != nil {
h.portal.Logger().Error(errMultiformParse, zap.Error(err))
return
}
// Retrieve the file from the form data
file, _, err := r.FormFile("file")
if jc.Check(errRetrievingFile, err) != nil {
h.portal.Logger().Error(errRetrievingFile, zap.Error(err))
return
}
defer func(file multipart.File) {
err := file.Close()
if err != nil {
h.portal.Logger().Error(errClosingStream, zap.Error(err))
}
}(file)
2024-01-15 20:16:48 +00:00
rs = file
2024-01-15 04:54:43 +00:00
} else {
2024-01-15 20:16:48 +00:00
data, err := io.ReadAll(r.Body)
2024-01-15 04:54:43 +00:00
if jc.Check(errReadFile, err) != nil {
h.portal.Logger().Error(errReadFile, zap.Error(err))
return
}
2024-01-15 20:16:48 +00:00
buffer := bytes.NewReader(data)
bufferSize = int64(buffer.Len())
rs = buffer
2024-01-15 04:54:43 +00:00
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
h.portal.Logger().Error(errClosingStream, zap.Error(err))
}
}(r.Body)
}
2024-01-16 06:05:09 +00:00
hash, err := h.portal.Storage().GetHash(rs)
if err != nil {
_ = jc.Error(errUploadingFileErr, http.StatusInternalServerError)
h.portal.Logger().Error(errUploadingFile, zap.Error(err))
return
}
if exists, upload := h.portal.Storage().FileExists(hash); exists {
cid, err := encoding.CIDFromHash(hash, upload.Size, types.CIDTypeRaw)
if err != nil {
_ = jc.Error(errUploadingFileErr, http.StatusInternalServerError)
h.portal.Logger().Error(errUploadingFile, zap.Error(err))
return
}
cidStr, err := cid.ToString()
if err != nil {
_ = jc.Error(errUploadingFileErr, http.StatusInternalServerError)
h.portal.Logger().Error(errUploadingFile, zap.Error(err))
return
}
jc.Encode(map[string]string{"hash": cidStr})
return
}
hash, err = h.portal.Storage().PutFile(rs, "s5", false)
2024-01-15 04:54:43 +00:00
if err != nil {
_ = jc.Error(errUploadingFileErr, http.StatusInternalServerError)
h.portal.Logger().Error(errUploadingFile, zap.Error(err))
return
}
2024-01-15 20:16:48 +00:00
cid, err := encoding.CIDFromHash(hash, uint64(bufferSize), types.CIDTypeRaw)
2024-01-15 04:54:43 +00:00
if err != nil {
_ = jc.Error(errUploadingFileErr, http.StatusInternalServerError)
h.portal.Logger().Error(errUploadingFile, zap.Error(err))
return
}
cidStr, err := cid.ToString()
if err != nil {
_ = jc.Error(errUploadingFileErr, http.StatusInternalServerError)
h.portal.Logger().Error(errUploadingFile, zap.Error(err))
return
}
jc.Encode(map[string]string{"hash": cidStr})
}