diff --git a/upload.go b/upload.go index 17c2586..9ba4b84 100644 --- a/upload.go +++ b/upload.go @@ -3,8 +3,10 @@ package main import ( "encoding/json" "fmt" + "io" "net/http" "os" + "path/filepath" "strconv" "sync" "time" @@ -22,23 +24,29 @@ const ( inactive UploadState = iota active completed + full ) -type UploadContext struct { - maxSize int64 +type UploadFile struct { created time.Time state UploadState finalName string } +type UploadContext struct { + maxSize int64 + created time.Time + lifetime time.Duration +} + type UploadDatabase struct { - data map[uuid.UUID]UploadContext + data map[uuid.UUID]*UploadContext mtx sync.Mutex } var db UploadDatabase -func (d *UploadDatabase) commit(size int64, finalName string, lifefile time.Duration) uuid.UUID { +func (d *UploadDatabase) commit(size int64, lifefile time.Duration) uuid.UUID { id := uuid.New() d.mtx.Lock() defer d.mtx.Unlock() @@ -49,12 +57,12 @@ func (d *UploadDatabase) commit(size int64, finalName string, lifefile time.Dura return uuid.Max } - d.data[id] = UploadContext{ - created: time.Now(), - finalName: finalName, - maxSize: size, - state: inactive, - } + ctx := new(UploadContext) + d.data[id] = ctx + + ctx.created = time.Now() + ctx.lifetime = lifefile + ctx.maxSize = size return id } @@ -66,18 +74,6 @@ func (d *UploadDatabase) exists(id uuid.UUID) bool { 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() @@ -85,7 +81,7 @@ func (d *UploadDatabase) getSize(id uuid.UUID) int64 { } func initialize() { - db.data = make(map[uuid.UUID]UploadContext) + db.data = make(map[uuid.UUID]*UploadContext) } func adminHandler(w http.ResponseWriter, r *http.Request) { @@ -100,6 +96,7 @@ func generateHandler(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { w.WriteHeader(http.StatusMethodNotAllowed) + return } var linkSettings struct { @@ -134,7 +131,7 @@ func generateHandler(w http.ResponseWriter, r *http.Request) { return } - id = db.commit(int64(maxSizeBytes), "untitled"+time.Now().String(), time.Duration(linkLifetime)) + id = db.commit(maxSizeBytes, time.Duration(linkLifetime)) if id == uuid.Max { http.Error(w, "Commit failed", http.StatusBadRequest) return @@ -152,6 +149,7 @@ func generateHandler(w http.ResponseWriter, r *http.Request) { func uploadHandler(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { w.WriteHeader(http.StatusMethodNotAllowed) + return } id, err := uuid.Parse(r.URL.Query().Get("key")) @@ -172,7 +170,55 @@ func uploadHandler(w http.ResponseWriter, r *http.Request) { } func fileHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + id, err := uuid.Parse(r.URL.Query().Get("key")) + if err != nil || !db.exists(id) { + w.WriteHeader(http.StatusBadRequest) + return + } + + // ctx := db.activate(id) + // defer db.deactivate(id) + // if ctx == nil { + // w.WriteHeader(http.StatusBadRequest) + // return + // } + + // parse form + err = r.ParseMultipartForm(10 << 20) // 10MB memory cache + if err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + + // Retrieve the file from form + file, handler, err := r.FormFile("file") + if err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + defer file.Close() + + // Create a new file in the uploads directory + dst, err := os.Create(filepath.Join("uploads", handler.Filename)) + if err != nil { + fmt.Fprintf(w, "Error creating file: %v", err) + return + } + defer dst.Close() + + // Copy the uploaded file to the new file + _, err = io.Copy(dst, file) + if err != nil { + fmt.Fprintf(w, "Error saving file: %v", err) + return + } + + w.WriteHeader(http.StatusAccepted) } func main() {