diff --git a/main.go b/main.go index e0c2fd5..d5fedf8 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,7 @@ import ( "net/http" "os" "path/filepath" + "strconv" "strings" "sync" "time" @@ -34,6 +35,7 @@ var assetsFS embed.FS type meta struct { Expiry time.Time `json:"expiry"` ExpireOnView bool `json:"expire_on_view"` + FileName string `json:"file_name,omitempty"` } func init() { @@ -144,8 +146,8 @@ Upload from stdin and expire on first view: -

Quick text

-

Type or paste text and upload as a .txt (no file chooser needed).

+

No file? Type your text in here!

+

Type or paste text and upload as a .txt.

@@ -285,6 +287,7 @@ func uploadHandler(w http.ResponseWriter, r *http.Request) { var reader io.Reader var ext string + var fileName string contentType := r.Header.Get("Content-Type") if strings.HasPrefix(contentType, "multipart/form-data") { @@ -293,6 +296,7 @@ func uploadHandler(w http.ResponseWriter, r *http.Request) { defer file.Close() reader = file ext = filepath.Ext(header.Filename) + fileName = filepath.Base(header.Filename) } } } @@ -345,7 +349,10 @@ func uploadHandler(w http.ResponseWriter, r *http.Request) { m.Expiry = time.Now().Add(d) } } - if !m.Expiry.IsZero() || m.ExpireOnView { + if fileName != "" { + m.FileName = fileName + } + if !m.Expiry.IsZero() || m.ExpireOnView || m.FileName != "" { metaBytes, _ := json.Marshal(m) _ = os.WriteFile(path+".json", metaBytes, 0644) } @@ -357,6 +364,20 @@ func uploadHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "%s://%s/%s\n", scheme, domain, filename) } +func contentDispositionInlineFilename(name string) string { + q := strconv.QuoteToASCII(name) + var b strings.Builder + for i := 0; i < len(name); i++ { + c := name[i] + if (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '.' || c == '-' || c == '_' { + b.WriteByte(c) + } else { + fmt.Fprintf(&b, "%%%02X", c) + } + } + return fmt.Sprintf(`inline; filename=%s; filename*=UTF-8''%s`, q, b.String()) +} + func viewHandler(w http.ResponseWriter, r *http.Request) { id := strings.TrimPrefix(r.URL.Path, "/") if id == "" { @@ -379,6 +400,9 @@ func viewHandler(w http.ResponseWriter, r *http.Request) { defer os.Remove(path) defer os.Remove(metaPath) } + if m.FileName != "" { + w.Header().Set("Content-Disposition", contentDispositionInlineFilename(m.FileName)) + } } }