mirror of
https://github.com/matrix-org/dendrite.git
synced 2024-11-26 00:01:55 -06:00
Fallback parsing for Content-Disposition minefield (#1144)
This commit is contained in:
parent
38053a5bb7
commit
23bed196e6
|
@ -47,6 +47,10 @@ const mediaIDCharacters = "A-Za-z0-9_=-"
|
||||||
// Note: unfortunately regex.MustCompile() cannot be assigned to a const
|
// Note: unfortunately regex.MustCompile() cannot be assigned to a const
|
||||||
var mediaIDRegex = regexp.MustCompile("^[" + mediaIDCharacters + "]+$")
|
var mediaIDRegex = regexp.MustCompile("^[" + mediaIDCharacters + "]+$")
|
||||||
|
|
||||||
|
// Regular expressions to help us cope with Content-Disposition parsing
|
||||||
|
var rfc2183 = regexp.MustCompile(`filename\=utf-8\"(.*)\"`)
|
||||||
|
var rfc6266 = regexp.MustCompile(`filename\*\=utf-8\'\'(.*)`)
|
||||||
|
|
||||||
// downloadRequest metadata included in or derivable from a download or thumbnail request
|
// downloadRequest metadata included in or derivable from a download or thumbnail request
|
||||||
// https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-media-r0-download-servername-mediaid
|
// https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-media-r0-download-servername-mediaid
|
||||||
// http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-media-r0-thumbnail-servername-mediaid
|
// http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-media-r0-thumbnail-servername-mediaid
|
||||||
|
@ -378,8 +382,8 @@ func (r *downloadRequest) addDownloadFilenameToHeaders(
|
||||||
} else {
|
} else {
|
||||||
// For UTF-8 filenames, we quote always, as that's the standard
|
// For UTF-8 filenames, we quote always, as that's the standard
|
||||||
w.Header().Set("Content-Disposition", fmt.Sprintf(
|
w.Header().Set("Content-Disposition", fmt.Sprintf(
|
||||||
`inline; filename=utf-8"%s"`,
|
`inline; filename*=utf-8''%s`,
|
||||||
unescaped,
|
url.QueryEscape(unescaped),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,9 +704,22 @@ func (r *downloadRequest) fetchRemoteFile(
|
||||||
}
|
}
|
||||||
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"))
|
||||||
_, params, err := mime.ParseMediaType(resp.Header.Get("Content-Disposition"))
|
|
||||||
if err == nil && params["filename"] != "" {
|
dispositionHeader := resp.Header.Get("Content-Disposition")
|
||||||
r.MediaMetadata.UploadName = types.Filename(params["filename"])
|
if _, params, e := mime.ParseMediaType(dispositionHeader); e == nil {
|
||||||
|
if params["filename"] != "" {
|
||||||
|
r.MediaMetadata.UploadName = types.Filename(params["filename"])
|
||||||
|
} else if params["filename*"] != "" {
|
||||||
|
r.MediaMetadata.UploadName = types.Filename(params["filename*"])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if matches := rfc6266.FindStringSubmatch(dispositionHeader); len(matches) > 1 {
|
||||||
|
// Always prefer the RFC6266 UTF-8 name if possible
|
||||||
|
r.MediaMetadata.UploadName = types.Filename(matches[1])
|
||||||
|
} else if matches := rfc2183.FindStringSubmatch(dispositionHeader); len(matches) > 1 {
|
||||||
|
// Otherwise, see if an RFC2183 name was provided (ASCII only)
|
||||||
|
r.MediaMetadata.UploadName = types.Filename(matches[1])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Logger.Info("Transferring remote file")
|
r.Logger.Info("Transferring remote file")
|
||||||
|
|
|
@ -331,4 +331,6 @@ Can download file 'ascii'
|
||||||
Can download file 'name with spaces'
|
Can download file 'name with spaces'
|
||||||
Can download file 'name;with;semicolons'
|
Can download file 'name;with;semicolons'
|
||||||
Can download specifying a different ASCII file name
|
Can download specifying a different ASCII file name
|
||||||
|
Can download with Unicode file name over federation
|
||||||
|
Can download specifying a different Unicode file name
|
||||||
Inbound /v1/send_join rejects joins from other servers
|
Inbound /v1/send_join rejects joins from other servers
|
||||||
|
|
Loading…
Reference in a new issue