Browse Source

feat(mediaproxy): pass original filename in Content-Disposition header

When you download/save proxified media, the original filename is lost. That
information could be retained by passing a header `Content-Disposition: inline;
filename="ORIGNAL_FILENAME.EXT"` when serving the media file. The requested URL
would still be obfuscated, but if the client downloads the file it'll use that
original filename.
Frédéric Guillot 1 year ago
parent
commit
7c5d6cf35f
1 changed files with 10 additions and 4 deletions
  1. 10 4
      internal/ui/proxy.go

+ 10 - 4
internal/ui/proxy.go

@@ -12,6 +12,7 @@ import (
 	"log/slog"
 	"net/http"
 	"net/url"
+	"path"
 	"time"
 
 	"miniflux.app/v2/internal/config"
@@ -57,23 +58,23 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	u, err := url.Parse(string(decodedURL))
+	parsedMediaURL, err := url.Parse(string(decodedURL))
 	if err != nil {
 		html.BadRequest(w, r, errors.New("invalid URL provided"))
 		return
 	}
 
-	if u.Scheme != "http" && u.Scheme != "https" {
+	if parsedMediaURL.Scheme != "http" && parsedMediaURL.Scheme != "https" {
 		html.BadRequest(w, r, errors.New("invalid URL provided"))
 		return
 	}
 
-	if u.Host == "" {
+	if parsedMediaURL.Host == "" {
 		html.BadRequest(w, r, errors.New("invalid URL provided"))
 		return
 	}
 
-	if !u.IsAbs() {
+	if !parsedMediaURL.IsAbs() {
 		html.BadRequest(w, r, errors.New("invalid URL provided"))
 		return
 	}
@@ -145,6 +146,11 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) {
 		b.WithStatus(resp.StatusCode)
 		b.WithHeader("Content-Security-Policy", `default-src 'self'`)
 		b.WithHeader("Content-Type", resp.Header.Get("Content-Type"))
+
+		if filename := path.Base(parsedMediaURL.Path); filename != "" {
+			b.WithHeader("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, filename))
+		}
+
 		forwardedResponseHeader := []string{"Content-Encoding", "Content-Type", "Content-Length", "Accept-Ranges", "Content-Range"}
 		for _, responseHeaderName := range forwardedResponseHeader {
 			if resp.Header.Get(responseHeaderName) != "" {