tagliatelle

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

include-upload-local.go (1740B)


      1 package main
      2 
      3 import (
      4 	"fmt"
      5 	"net/http"
      6 	"os"
      7 	"path/filepath"
      8 	"strings"
      9 )
     10 
     11 func localFileHandler(w http.ResponseWriter, r *http.Request) {
     12 	if r.Method != http.MethodPost {
     13 		http.Redirect(w, r, "/upload", http.StatusSeeOther)
     14 		return
     15 	}
     16 
     17 	rawPath := strings.TrimSpace(r.FormValue("filepath"))
     18 	if rawPath == "" {
     19 		renderError(w, "No file path provided", http.StatusBadRequest)
     20 		return
     21 	}
     22 
     23 	// Resolve to an absolute, cleaned path to prevent traversal tricks
     24 	absPath, err := filepath.Abs(rawPath)
     25 	if err != nil {
     26 		renderError(w, "Invalid file path", http.StatusBadRequest)
     27 		return
     28 	}
     29 
     30 	// Confirm the file actually exists and is a regular file (not a dir/symlink)
     31 	info, err := os.Stat(absPath)
     32 	if err != nil {
     33 		if os.IsNotExist(err) {
     34 			renderError(w, fmt.Sprintf("File not found: %s", absPath), http.StatusBadRequest)
     35 		} else {
     36 			renderError(w, fmt.Sprintf("Cannot access file: %v", err), http.StatusInternalServerError)
     37 		}
     38 		return
     39 	}
     40 	if !info.Mode().IsRegular() {
     41 		renderError(w, "Path must point to a regular file", http.StatusBadRequest)
     42 		return
     43 	}
     44 
     45 	f, err := os.Open(absPath)
     46 	if err != nil {
     47 		renderError(w, fmt.Sprintf("Failed to open file: %v", err), http.StatusInternalServerError)
     48 		return
     49 	}
     50 	defer f.Close()
     51 
     52 	deleteSource := r.FormValue("delete_source") == "on"
     53 
     54 	id, warningMsg, err := processUpload(f, filepath.Base(absPath))
     55 	if err != nil {
     56 		renderError(w, err.Error(), http.StatusInternalServerError)
     57 		return
     58 	}
     59 
     60 	if deleteSource {
     61 		f.Close()
     62 		if removeErr := os.Remove(absPath); removeErr != nil {
     63 			warningMsg = strings.TrimPrefix(fmt.Sprintf("%s; could not delete source file: %v", warningMsg, removeErr), "; ")
     64 		}
     65 	}
     66 
     67 	redirectWithWarning(w, r, fmt.Sprintf("/file/%d", id), warningMsg)
     68 }