package main import ( "encoding/json" "fmt" "net/http" "os" "strconv" "sync" "time" "github.com/google/uuid" ) type Admin struct { name string } type UploadState int const ( inactive UploadState = iota active completed ) type UploadContext struct { maxSize int64 created time.Time state UploadState finalName string } type UploadDatabase struct { data map[uuid.UUID]UploadContext mtx sync.Mutex } var db UploadDatabase func (d *UploadDatabase) commit(size int64, finalName string, lifefile time.Duration) uuid.UUID { id := uuid.New() d.mtx.Lock() defer d.mtx.Unlock() _, found := d.data[id] if found { return uuid.Max } d.data[id] = UploadContext{ created: time.Now(), finalName: finalName, maxSize: size, state: inactive, } return id } func (d *UploadDatabase) exists(id uuid.UUID) bool { d.mtx.Lock() defer d.mtx.Unlock() _, found := d.data[id] return found } func (d *UploadDatabase) activate(id uuid.UUID) *UploadContext { d.mtx.Lock() defer d.mtx.Unlock() // i, found := d.data[id] return nil } func (d *UploadDatabase) deactivate(id uuid.UUID) { } func (d *UploadDatabase) getSize(id uuid.UUID) int64 { d.mtx.Lock() defer d.mtx.Unlock() return d.data[id].maxSize } func initialize() { db.data = make(map[uuid.UUID]UploadContext) } func adminHandler(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./html/admin.html") } func generateHandler(w http.ResponseWriter, r *http.Request) { var maxSizeBytes int64 var linkLifetime int64 var id uuid.UUID var uploadLink string if r.Method != "POST" { w.WriteHeader(http.StatusMethodNotAllowed) } var linkSettings struct { Lifetime string `json:"lifetime"` MaxSize string `json:"maxSize"` SizeUnit string `json:"sizeUnit"` } err := json.NewDecoder(r.Body).Decode(&linkSettings) if err != nil { http.Error(w, fmt.Sprintf("Invalid input: %v", err), http.StatusBadRequest) return } linkLifetime, err = strconv.ParseInt(linkSettings.Lifetime, 10, 64) if err != nil { http.Error(w, fmt.Sprintf("Invalid input: %v", err), http.StatusBadRequest) return } maxSizeBytes, err = strconv.ParseInt(linkSettings.MaxSize, 10, 64) if err != nil { http.Error(w, fmt.Sprintf("Invalid input: %v", err), http.StatusBadRequest) return } if linkSettings.SizeUnit == "GB" { maxSizeBytes *= 1024 * 1024 * 1024 } else if linkSettings.SizeUnit == "MB" { maxSizeBytes *= 1024 * 1024 } else { http.Error(w, fmt.Sprintf("Invalid input: %v", err), http.StatusBadRequest) return } id = db.commit(int64(maxSizeBytes), "untitled"+time.Now().String(), time.Duration(linkLifetime)) if id == uuid.Max { http.Error(w, "Commit failed", http.StatusBadRequest) return } uploadLink = fmt.Sprintf("http://localhost:8080/upload?key=%s", id) response := map[string]string{"uploadLink": uploadLink} w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(response); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } func uploadHandler(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { w.WriteHeader(http.StatusMethodNotAllowed) } id, err := uuid.Parse(r.URL.Query().Get("key")) if err != nil || !db.exists(id) { http.ServeFile(w, r, "./html/user_bad.html") return } if !r.URL.Query().Has("limit") { q := r.URL.Query() q.Set("limit", strconv.FormatInt(db.getSize(id), 10)) r.URL.RawQuery = q.Encode() http.Redirect(w, r, r.URL.String(), http.StatusSeeOther) return } http.ServeFile(w, r, "./html/user.html") } func fileHandler(w http.ResponseWriter, r *http.Request) { } func main() { initialize() os.MkdirAll("uploads", os.ModePerm) http.HandleFunc("/admin", adminHandler) http.HandleFunc("/generate", generateHandler) http.HandleFunc("/upload", uploadHandler) http.HandleFunc("/file", fileHandler) // http.Handle("/", http.FileServer(http.Dir("."))) // Start the server fmt.Println("Starting server on :8080") err := http.ListenAndServe(":8080", nil) if err != nil { fmt.Printf("Error starting server: %v", err) } }