Skip to content

Commit

Permalink
Move chunkedReader to a method
Browse files Browse the repository at this point in the history
The method has no state, so therefore declared static.
Ideally this should be a standalone class, perhaps in laminas-stdlib.
  • Loading branch information
glensc committed Mar 5, 2021
1 parent 6225613 commit 5459b48
Showing 1 changed file with 41 additions and 30 deletions.
71 changes: 41 additions & 30 deletions src/Protocol/Smtp.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace Laminas\Mail\Protocol;

use Generator;
use Laminas\Mail\Headers;

/**
Expand Down Expand Up @@ -172,6 +173,44 @@ public function setUseCompleteQuit($useCompleteQuit)
return $this->useCompleteQuit = (bool) $useCompleteQuit;
}

/**
* Read $data as lines terminated by "\n"
*
* @param string $data
* @param int $chunkSize
* @return Generator|string[]
* @author Elan Ruusamäe <glen@pld-linux.org>
*/
private static function chunkedReader(string $data, int $chunkSize = 4096): Generator
{
if (($fp = fopen("php://temp", "r+")) === false) {
throw new Exception\RuntimeException('cannot fopen');
}
if (fwrite($fp, $data) === false) {
throw new Exception\RuntimeException('cannot fwrite');
}
rewind($fp);

$line = null;
while (($buffer = fgets($fp, $chunkSize)) !== false) {
$line .= $buffer;

// partial read, continue loop to read again to complete the line
if (isset($buffer[$chunkSize - 2]) && $buffer[$chunkSize - 2] !== "\n") {
continue;
}

yield $line;
$line = null;
}

if ($line !== null) {
yield $line;
}

fclose($fp);
}

/**
* Whether or not send QUIT command
*
Expand Down Expand Up @@ -317,36 +356,8 @@ public function data($data)
$this->_send('DATA');
$this->_expect(354, 120); // Timeout set for 2 minutes as per RFC 2821 4.5.3.2

$chunkReader = static function (string $data, int $chunkSize = 4096) {
if (($fp = fopen("php://temp", "r+")) === false) {
throw new Exception\RuntimeException('cannot fopen');
}
if (fwrite($fp, $data) === false) {
throw new Exception\RuntimeException('cannot fwrite');
}
rewind($fp);

$line = null;
while (($buffer = fgets($fp, $chunkSize)) !== false) {
$line .= $buffer;

// partial read, continue loop to read again to complete the line
if (isset($buffer[$chunkSize - 2]) && $buffer[$chunkSize - 2] !== "\n") {
continue;
}

yield $line;
$line = null;
}

if ($line !== null) {
yield $line;
}

fclose($fp);
};

foreach ($chunkReader($data) as $line) {
$reader = self::chunkedReader($data);
foreach ($reader as $line) {
$line = rtrim($line, "\r\n");
if (isset($line[0]) && $line[0] === '.') {
// Escape lines prefixed with a '.'
Expand Down

0 comments on commit 5459b48

Please sign in to comment.