mediaapi/writers/download: Use mime.ParseMediaType to parse Content-Disposition

main
Robert Swain 2017-06-01 16:04:41 +02:00
parent 2d822c57f9
commit a398cdd193
1 changed files with 8 additions and 20 deletions

View File

@ -18,9 +18,9 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"mime"
"net" "net"
"net/http" "net/http"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
@ -375,7 +375,10 @@ func (r *downloadRequest) fetchRemoteFile(absBasePath types.Path, maxFileSizeByt
} }
r.MediaMetadata.FileSizeBytes = types.FileSizeBytes(contentLength) r.MediaMetadata.FileSizeBytes = types.FileSizeBytes(contentLength)
r.MediaMetadata.ContentType = types.ContentType(resp.Header.Get("Content-Type")) r.MediaMetadata.ContentType = types.ContentType(resp.Header.Get("Content-Type"))
r.MediaMetadata.UploadName = types.Filename(contentDispositionToFilename(resp.Header.Get("Content-Disposition"))) _, params, err := mime.ParseMediaType(resp.Header.Get("Content-Disposition"))
if err == nil && params["filename"] != "" {
r.MediaMetadata.UploadName = types.Filename(params["filename"])
}
r.Logger.Info("Transferring remote file") r.Logger.Info("Transferring remote file")
@ -430,11 +433,11 @@ func (r *downloadRequest) createRemoteRequest() (*http.Response, *util.JSONRespo
resErr := jsonerror.InternalServerError() resErr := jsonerror.InternalServerError()
return nil, &resErr return nil, &resErr
} }
url := "https://" + dnsResult.Addrs[0] httpsURL := "https://" + dnsResult.Addrs[0]
r.Logger.WithField("URL", url).Info("Connecting to remote") r.Logger.WithField("URL", httpsURL).Info("Connecting to remote")
remoteReqAddr := url + "/_matrix/media/v1/download/" + string(r.MediaMetadata.Origin) + "/" + string(r.MediaMetadata.MediaID) remoteReqAddr := httpsURL + "/_matrix/media/v1/download/" + string(r.MediaMetadata.Origin) + "/" + string(r.MediaMetadata.MediaID)
remoteReq, err := http.NewRequest("GET", remoteReqAddr, nil) remoteReq, err := http.NewRequest("GET", remoteReqAddr, nil)
if err != nil { if err != nil {
resErr := jsonerror.InternalServerError() resErr := jsonerror.InternalServerError()
@ -471,18 +474,3 @@ func (r *downloadRequest) createRemoteRequest() (*http.Response, *util.JSONRespo
return resp, nil return resp, nil
} }
var contentDispositionRegex = regexp.MustCompile("filename([*])?=(utf-8'')?([A-Za-z0-9._-]+)")
func contentDispositionToFilename(contentDisposition string) types.Filename {
filename := ""
if matches := contentDispositionRegex.FindStringSubmatch(contentDisposition); len(matches) == 4 {
// Note: the filename should already be escaped. If not, unescape should be close to a no-op. This way filename is sure to be safe.
unescaped, err := url.PathUnescape(matches[3])
if err != nil {
unescaped = matches[3]
}
filename = url.PathEscape(unescaped)
}
return types.Filename(filename)
}