mirror of
https://github.com/mjl-/mox.git
synced 2025-07-18 23:26:36 +03:00
imapserver: return all the extensible fields for bodystructure, notably for content-disposition
The gmail iOS/Android app were showing mime image parts as (garbled) text instead of rendering them as image. By returning all the optional fields in the bodystructure fetch attribute, the gmail app renders the image as expected by the user. So we now add all fields. We didn't before, because we weren't keeping track of Content-MD5, Content-Language and Content-Location header fields, since they aren't that useful. Messages in mailboxes have to be reparsed: ./mox reparse Without reparsing, imap responses will claim the extra fields (content-disposition) are absent for existing messages, instead of not claiming anything at all, which is what we did before. Accounts and all/some mailboxes can get their "uid validity" bumped ("./mox bumpuidvalidity $account [$mailbox]"), which should trigger clients to load all messages from scratch, but gmail doesn't appear to notice, so it would be better to remove & add the account in gmail. For issue #327, also relevant to issue #217.
This commit is contained in:
@ -67,7 +67,11 @@ type Part struct {
|
||||
ContentTypeParams map[string]string // E.g. holds "boundary" for multipart messages. Has lower-case keys, and original case values.
|
||||
ContentID string
|
||||
ContentDescription string
|
||||
ContentTransferEncoding string // In upper case.
|
||||
ContentTransferEncoding string // In upper case.
|
||||
ContentDisposition string
|
||||
ContentMD5 string
|
||||
ContentLanguage string
|
||||
ContentLocation string
|
||||
Envelope *Envelope // Email message headers. Not for non-message parts.
|
||||
|
||||
Parts []Part // Parts if this is a multipart.
|
||||
@ -155,6 +159,10 @@ func fallbackPart(p Part, r io.ReaderAt, size int64) (Part, error) {
|
||||
ContentID: p.ContentID,
|
||||
ContentDescription: p.ContentDescription,
|
||||
ContentTransferEncoding: p.ContentTransferEncoding,
|
||||
ContentDisposition: p.ContentDisposition,
|
||||
ContentMD5: p.ContentMD5,
|
||||
ContentLanguage: p.ContentLanguage,
|
||||
ContentLocation: p.ContentLocation,
|
||||
Envelope: p.Envelope,
|
||||
// We don't keep:
|
||||
// - BoundaryOffset: irrelevant for top-level message.
|
||||
@ -357,6 +365,10 @@ func newPart(log mlog.Log, strict bool, r io.ReaderAt, offset int64, parent *Par
|
||||
p.ContentID = p.header.Get("Content-Id")
|
||||
p.ContentDescription = p.header.Get("Content-Description")
|
||||
p.ContentTransferEncoding = strings.ToUpper(p.header.Get("Content-Transfer-Encoding"))
|
||||
p.ContentDisposition = p.header.Get("Content-Disposition")
|
||||
p.ContentMD5 = p.header.Get("Content-Md5")
|
||||
p.ContentLanguage = p.header.Get("Content-Language")
|
||||
p.ContentLocation = p.header.Get("Content-Location")
|
||||
|
||||
if parent == nil {
|
||||
p.Envelope, err = parseEnvelope(log, mail.Header(p.header))
|
||||
@ -644,13 +656,16 @@ var ErrParamEncoding = errors.New("bad header parameter encoding")
|
||||
// If the returned error is an ErrParamEncoding, it can be treated as a diagnostic
|
||||
// and a filename may still be returned.
|
||||
func (p *Part) DispositionFilename() (disposition string, filename string, err error) {
|
||||
h, err := p.Header()
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("parsing header: %w", err)
|
||||
cd := p.ContentDisposition
|
||||
if cd == "" {
|
||||
h, err := p.Header()
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("parsing header: %w", err)
|
||||
}
|
||||
cd = h.Get("Content-Disposition")
|
||||
}
|
||||
var disp string
|
||||
var params map[string]string
|
||||
cd := h.Get("Content-Disposition")
|
||||
if cd != "" {
|
||||
disp, params, err = mime.ParseMediaType(cd)
|
||||
}
|
||||
|
Reference in New Issue
Block a user