Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
From #2822298: Provide a show / hide headers link / button in the mail display we've noticed that
Using the multiple-attachments.eml example, it turns out the Message-ID line is wrapped into two lines still. We need to investigate where the newline is coming from.
This is the followup where to investigate and discuss about it.
Proposed resolution
- investigate
- discuss
- fix it
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#25 | interdiff-2822786-23-25.txt | 2.41 KB | toncic |
#25 | multiple-attachments_message-id-28222786-25.patch | 8.93 KB | toncic |
| |||
#23 | interdiff-2822786-21-23.txt | 4.73 KB | toncic |
#23 | multiple-attachments_message-id-28222786-23.patch | 9.16 KB | toncic |
| |||
#21 | interdiff-2822786-19-21.txt | 4.81 KB | toncic |
Comments
Comment #2
ModernMantra CreditAttribution: ModernMantra at MD Systems GmbH for MD Systems GmbH commentedWhat breaks to new line is
Header::toString()
. Debugged and verified and there is regex expression which breaks string after 78 characters.$field_string = !$encoded ? preg_replace('/(.{0,78})(\h|$)/', "\\1\n\\2", $field_string) : $field_string;
Comment #3
miro_dietikerFunny stuff...
Yeah this is because we are using toString() to go into the SMTP domain...
Not sure what is the clean solution. I guess there should be a different method getHeaderString or so that does this wrapping and keep toString() unencoded... However you will need to change all explicit and implicit string consumers to that method.
Comment #4
toncic CreditAttribution: toncic at MD Systems GmbH commentedChange toString() method just to skip Message-ID for regex and it is working for me.
Comment #5
toncic CreditAttribution: toncic at MD Systems GmbH commentedComment #6
miro_dietikerNo, this approach is the wrong direction.
All headers need to behave the same way. This wrapping would happen with every other line too if it is too long.
So it's about making the method toString NOT wrap at all and let everyone who expects that wrapping call the new method that contains the old wrapping. I tried to explain if this is fine in #3 and in order to decide it, we need it implemented to see the complexity / shift.
Comment #7
toncic CreditAttribution: toncic at MD Systems GmbH commentedI added new function toStringNotWrap() and use that now.
I think maybe we can add new checkbox in setting, something like write header into multi lines.
Comment #8
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedIt seems the same as before.
In case we are creating new variables, we should document/add them in theme info and the twig template doc block.
Considering #3, not sure if this new method should go into
MessageDecomposition
service... But, astoString()
also does encoding, I guess we can have it onMimeHeader
.Also, having optional
$wrapped
parameter intoString()
could be an option to consider in this case.Tests are missing as well.
Comment #9
miro_dietikerYou might underestimate the complexity and architectural decisions we need to think about here.
Instances of MimeMessageInterface / MimeEntityInterface contains a parsed message and calling toString() should reconstruct what was parsed WITHOUT changes. Currently toString simply force encodes header, which is also needed because we decode on parsing. Thus we do not really know if parsing and later converting back to string will result in the same. As soon as the header contains special characters that are inline encoded, things get worse. Originally, they could be unencoded 8bit while our conversion might apply inline encoding.
So the first thing here is, writing / extending unit tests that check the cycle. Parsing examples with special encodings.
Then later convert toString and check if the very same thing result again.
This will require analysis of the implementation in \Drupal\inmail\MIME\MimeHeader::toString and its \Drupal\inmail\MIME\MimeHeader::mimeHeaderEncode
The mess already starts at \Drupal\inmail\MIME\MimeParser::parseHeaderFields where we decode with the lines:
So it means lots of cases we encode here are not guaranteed to be returned the same way later.
In contrast, if you look at the body, we have two methods:
getBody() that keeps the body unchanged and getDecodedBody() that applies decoding.
The body is not modified when parsing.
So it seems that if we want to be able to show the original header from parsing, we need to additionally store the undecoded header when parsing and keep it with \Drupal\inmail\MIME\MimeHeader::addField
I think it should be a separate method addParsedField() with an extra argument.
We now need to decide if toString defaults to encoding and if we implement an additional getRaw() that returns the parsed values (plus the added ones without Raw data through regular encoding)... or if we make toString to default returning the unchanged data, offering an alternative call (param, method) to return the encoded value.
IMHO, we should default to return unchanged things as much as possible. and toString should only trigger encodings, ... if we do not have original raw information.
As a result, toStringNotWrap() is not needed. :-)
Comment #10
miro_dietikerAttached some implementation that follows my principles outlined.
So we need examples like this overlong MessageId in \Drupal\Tests\inmail\Unit\MIME\MimeHeaderTest::provideHeaders()
We might need to move this data to a different dataProvider and switch testParse to that.
I guess there aren't too many other changes needed here except deep test coverage.
Comment #13
toncic CreditAttribution: toncic at MD Systems GmbH commentedTrying to fix test fails but unfortunately not successful.
Comment #15
toncic CreditAttribution: toncic at MD Systems GmbH commentedAfter discussion with both @miro_dietiker and @Berdit, we deal to switch the way for solving this issue. Now the goal is to have $raw in MimeHeader class and to have getRaw() as a way to access to raw.
Comment #16
miro_dietikerraw
Revert. It's unused.
Comment #17
toncic CreditAttribution: toncic at MD Systems GmbH commentedImplemented comm #16.
Comment #19
toncic CreditAttribution: toncic at MD Systems GmbH commentedFixing test failing.
Comment #20
miro_dietikerWe don't want to remove this.
The new method getRaw() is not used at all now.
You want to write a unit test for it.
And then the twig "All headers" output needs to be switched to this method.
And there we should once assert an overlengthy row from the example in display.
Comment #21
toncic CreditAttribution: toncic at MD Systems GmbH commentedAdded test for getRaw() and switch to use getRaw() in twig.
Comment #23
toncic CreditAttribution: toncic at MD Systems GmbH commentedFixing test failing.
Comment #24
ModernMantra CreditAttribution: ModernMantra at MD Systems GmbH for MD Systems GmbH commentedSmall syntax stuff that can be optionally fixed.
Missing type.
IMHO, that it is not necessary.
Unrelated change. Seems that you hit two times space causing that it appears in patch.
Wrong indentation.
Comment #25
toncic CreditAttribution: toncic at MD Systems GmbH commentedFixed coding standard.
Comment #27
miro_dietikerCommitted with some comment updates.