Initial commit
This commit is contained in:
commit
4f8fe007ad
133
main.go
Normal file
133
main.go
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var uploadDir string
|
||||||
|
|
||||||
|
func initConfig() {
|
||||||
|
if envUploadDir := os.Getenv("UPLOAD_DIR"); envUploadDir != "" {
|
||||||
|
uploadDir = envUploadDir
|
||||||
|
} else {
|
||||||
|
uploadDir = "./uploads/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
initConfig()
|
||||||
|
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
fmt.Println("Usage: go run main.go <port>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
port := os.Args[1]
|
||||||
|
|
||||||
|
uploadEndpoint := "upload"
|
||||||
|
if len(os.Args) >= 3 {
|
||||||
|
uploadEndpoint = os.Args[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
http.HandleFunc(fmt.Sprintf("/%s/", uploadEndpoint), uploadHandler)
|
||||||
|
fmt.Printf("Server started at :%s\n", port)
|
||||||
|
fmt.Printf("Endpoint: /%s/\n", uploadEndpoint)
|
||||||
|
fmt.Printf("Upload Directory: %s\n", uploadDir)
|
||||||
|
http.ListenAndServe(":"+port, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func uploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != http.MethodPost {
|
||||||
|
http.Error(w, "Only POST method is allowed", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the multipart form
|
||||||
|
err := r.ParseMultipartForm(10 << 20) // 10 MB
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Error parsing form data", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
file, handler, err := r.FormFile("file")
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Error retrieving the file", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
// Sanitize the filename
|
||||||
|
sanitizedFilename := sanitizeFilename(handler.Filename)
|
||||||
|
if sanitizedFilename == "" {
|
||||||
|
sanitizedFilename = generateRandomFilename()
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := filepath.Join(uploadDir, sanitizedFilename)
|
||||||
|
|
||||||
|
// Ensure unique filename
|
||||||
|
for fileExists(filePath) {
|
||||||
|
sanitizedFilename = generateRandomFilename()
|
||||||
|
filePath = filepath.Join(uploadDir, sanitizedFilename)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the uploads directory if it doesn't exist
|
||||||
|
if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
|
||||||
|
os.MkdirAll(uploadDir, os.ModePerm)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the file
|
||||||
|
out, err := os.Create(filePath)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Unable to save the file", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(out, file)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Error saving the file", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write([]byte("File uploaded successfully"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func sanitizeFilename(filename string) string {
|
||||||
|
// Allow only alphanumeric, dashes, underscores, and dots
|
||||||
|
re := regexp.MustCompile(`[^a-zA-Z0-9._-]`)
|
||||||
|
sanitized := re.ReplaceAllString(filename, "")
|
||||||
|
sanitized = strings.TrimLeft(sanitized, ".")
|
||||||
|
|
||||||
|
return sanitized
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateRandomFilename() string {
|
||||||
|
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
b := make([]byte, 16)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = letters[randInt(len(letters))]
|
||||||
|
}
|
||||||
|
return string(b) + ".file"
|
||||||
|
}
|
||||||
|
|
||||||
|
func randInt(n int) int {
|
||||||
|
b := make([]byte, 1)
|
||||||
|
rand.Read(b)
|
||||||
|
return int(b[0]) % n
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileExists(filename string) bool {
|
||||||
|
info, err := os.Stat(filename)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !info.IsDir()
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user