Skip to content

Commit 897a004

Browse files
committed
bug #57224 [Mime] Use streams instead of loading raw message generator into memory (bytestream)
This PR was squashed before being merged into the 6.4 branch. Discussion ---------- [Mime] Use streams instead of loading raw message generator into memory | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | Fix #51764 | License | MIT Generators can only be used once and so the previous iteration of the code loaded the contents of the generator into memory. That results in OOM errors when sending large e-mails. This PR changes the behaviour so that the generator contents are loaded into a `php://temp` stream. By default 2MB is stored in memory and the rest is written to temporary files to prevent OOM issues. Commits ------- 5471940a0c [Mime] Use streams instead of loading raw message generator into memory
2 parents 618597a + 2d2e8c4 commit 897a004

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

RawMessage.php

+24-3
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,32 @@
1818
*/
1919
class RawMessage
2020
{
21-
private iterable|string $message;
21+
/** @var iterable|string|resource */
22+
private $message;
2223
private bool $isGeneratorClosed;
2324

2425
public function __construct(iterable|string $message)
2526
{
2627
$this->message = $message;
2728
}
2829

30+
public function __destruct()
31+
{
32+
if (\is_resource($this->message)) {
33+
fclose($this->message);
34+
}
35+
}
36+
2937
public function toString(): string
3038
{
3139
if (\is_string($this->message)) {
3240
return $this->message;
3341
}
3442

43+
if (\is_resource($this->message)) {
44+
return stream_get_contents($this->message, -1, 0);
45+
}
46+
3547
$message = '';
3648
foreach ($this->message as $chunk) {
3749
$message .= $chunk;
@@ -53,10 +65,19 @@ public function toIterable(): iterable
5365
return;
5466
}
5567

68+
if (\is_resource($this->message)) {
69+
rewind($this->message);
70+
while ($line = fgets($this->message)) {
71+
yield $line;
72+
}
73+
74+
return;
75+
}
76+
5677
if ($this->message instanceof \Generator) {
57-
$message = '';
78+
$message = fopen('php://temp', 'w+');
5879
foreach ($this->message as $chunk) {
59-
$message .= $chunk;
80+
fwrite($message, $chunk);
6081
yield $chunk;
6182
}
6283
$this->isGeneratorClosed = !$this->message->valid();

0 commit comments

Comments
 (0)