package controller import ( "encoding/base64" "fmt" "html/template" "io" "log" "net/http" "net/url" "time" "drop.janw.name/storage" qrcode "github.com/skip2/go-qrcode" ) const MAX_FILESIZE = (1 << 19) * 100 func (app App) FilePost(res http.ResponseWriter, req *http.Request) { if !app.requireAuth(res, req) { return } if err := req.ParseMultipartForm(MAX_FILESIZE); err != nil { panic(err) } formFile, formFileHeader, err := req.FormFile("file") if err != nil { panic(err) } protected := req.FormValue("protect") == "on" fileData, err := io.ReadAll(formFile) if err != nil { panic(err) } file := storage.File{ Protected: protected, Filename: formFileHeader.Filename, Data: fileData, AvailableUntil: time.Now().Add(time.Hour * 24), } key, err := app.storage.Put(file) if err != nil { panic(err) } log.Println("received new file:", key) downloadURL := fmt.Sprintf("%s/%s", app.config.Http.BaseAddress, key) qrcodePng, err := qrcode.Encode(downloadURL, qrcode.Medium, 256) if err != nil { panic(err) } qrcodeDataUrl := fmt.Sprintf( "data:image/png;base64,%s", url.QueryEscape(base64.StdEncoding.WithPadding('=').EncodeToString(qrcodePng)), ) app.tmpl.ExecuteTemplate(res, "uploaded", struct { DownloadURL string QRCode template.URL }{ DownloadURL: downloadURL, QRCode: template.URL(qrcodeDataUrl), }) } func (app App) FileGet(res http.ResponseWriter, req *http.Request) { fileId := req.PathValue("file") file, _ := app.storage.Get(fileId) if file == nil || !file.IsAvailable() { if !app.requireAuth(res, req) { return } res.WriteHeader(http.StatusNotFound) app.tmpl.ExecuteTemplate(res, "404", nil) return } if file.Protected && !app.requireAuth(res, req) { return } res.Header().Add("Content-Type", "application/octet-stream") res.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", file.Filename)) if _, err := res.Write(file.Data); err != nil { panic(err) } else { log.Println("served file:", fileId, file.Filename) } }