94 lines
2.6 KiB
Go
94 lines
2.6 KiB
Go
package v1
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"io"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"os"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
"code.icb4dc0.de/prskr/searcherside/core/ports"
|
|
"code.icb4dc0.de/prskr/searcherside/internal/logging"
|
|
)
|
|
|
|
type IndexHandler struct {
|
|
MaxMemoryBytes int64
|
|
Indexer ports.IndexCurator
|
|
}
|
|
|
|
func (h IndexHandler) IngestIndex(writer http.ResponseWriter, req *http.Request) {
|
|
logger := logging.GetLogger(req.Context())
|
|
|
|
if err := req.ParseMultipartForm(h.MaxMemoryBytes); err != nil {
|
|
logger.WarnContext(req.Context(), "Failed to parse multipart form", logging.Error(err))
|
|
http.Error(writer, "Failed to parse multipart form", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if len(req.MultipartForm.File) != 1 {
|
|
http.Error(writer, "Only a single file can be uploaded", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var indexFile *multipart.FileHeader
|
|
|
|
for _, files := range req.MultipartForm.File {
|
|
if len(files) != 1 {
|
|
http.Error(writer, "Only a single file can be uploaded", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
indexFile = files[0]
|
|
break
|
|
}
|
|
|
|
indexTempFile, err := os.CreateTemp(os.TempDir(), "searcherside-index-*")
|
|
if err != nil {
|
|
logger.ErrorContext(req.Context(), "Failed to create temporary index file", logging.Error(err))
|
|
http.Error(writer, "Failed to create temporary index file", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
hash := sha256.New()
|
|
|
|
stream, err := indexFile.Open()
|
|
if err != nil {
|
|
logger.ErrorContext(req.Context(), "Failed to open index file", logging.Error(err))
|
|
http.Error(writer, "Failed to open index file", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if _, err := io.Copy(io.MultiWriter(hash, indexTempFile), stream); err != nil {
|
|
logger.ErrorContext(req.Context(), "Failed to copy index file", logging.Error(err))
|
|
http.Error(writer, "Failed to copy index file", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if err := stream.Close(); err != nil {
|
|
logger.ErrorContext(req.Context(), "Failed to close index file", logging.Error(err))
|
|
}
|
|
|
|
if err := indexTempFile.Close(); err != nil {
|
|
logger.ErrorContext(req.Context(), "Failed to close temporary index file", logging.Error(err))
|
|
http.Error(writer, "Failed to close temporary index file", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
go func() {
|
|
indexErr := h.Indexer.Ingest(req.Context(), ports.IngestIndexRequest{
|
|
FilePath: indexTempFile.Name(),
|
|
Hash: hex.EncodeToString(hash.Sum(nil)),
|
|
Module: chi.URLParam(req, "module"),
|
|
Instance: chi.URLParam(req, "instance"),
|
|
})
|
|
|
|
if indexErr != nil {
|
|
logger.ErrorContext(req.Context(), "Failed to ingest index", logging.Error(indexErr))
|
|
}
|
|
}()
|
|
|
|
writer.WriteHeader(http.StatusAccepted)
|
|
}
|