file-transfer/upload.go
2025-02-07 00:24:26 +01:00

79 lines
1.8 KiB
Go

package main
import (
"encoding/base64"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
)
func uploadFile(w http.ResponseWriter, req *http.Request) {
maxFileSize := int64(16 * 1024 * 1024 * 1024)
err := req.ParseMultipartForm(maxFileSize)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Get the file from the form data
file, handler, err := req.FormFile("file")
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer file.Close()
if handler.Size > maxFileSize {
http.Error(w, "File too large", http.StatusRequestEntityTooLarge)
return
}
randBytes, err := randomBytes(64)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
dirname := base64SpecialCharRegEx.ReplaceAllString(base64.StdEncoding.EncodeToString(randBytes), "")
path := filepath.Join(storePath, dirname, handler.Filename)
if err = os.MkdirAll(filepath.Dir(path), 0700); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
dst, err := os.Create(path)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer dst.Close()
// Copy the uploaded file to the destination file
if _, err := io.Copy(dst, file); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
localFile := &LocalFile{path: path}
password := req.FormValue("password")
if password != "" {
salt, passwordHash, err := hashPasswordWihSalt(password, nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
localFile.passwordSalt = salt
localFile.passwordHash = passwordHash
}
fileId := dirname[:5]
localFiles[fileId] = localFile
w.Header().Add("Content-Type", "application/json")
fmt.Fprintf(w, "{ \"%s\": \"%s\" }", handler.Filename, fileId)
}