Description
Environment: Tested with PHP 7.0.14 and PHP 5.6.29 (installed via brew) on macOS Sierra (10.12.2).
When using Mailguns SDK which uses the multipart-stream-builder I ran into the problem of local file attachments being handled correctly by the multipart stream builder, however uri attachments did not.
Looking at the source code the cause of this seems to be the fact that the stream generated from an URI is not seekable, which causes (string) $data['contents'] at https://github.com/php-http/multipart-stream-builder/blob/master/src/MultipartStreamBuilder.php#L98 to return en empty string due to the stream's to string method:
public function __toString()
{
try {
$this->seek(0);
return (string) stream_get_contents($this->stream);
} catch (\Exception $e) {
return '';
}
}
To reproduce the issue:
public function testMultipartStreamBuilderWithURI()
{
$builder = new \Http\Message\MultipartStream\MultipartStreamBuilder;
$url = 'https://assets-cdn.github.com/images/modules/site/home-hero.jpg';
$stream = fopen($url, 'r');
$builder->addResource(basename($url), $stream);
$body = $builder->build();
$contents = $body->getContents();
$uriContents = file_get_contents($url);
$this->assertContains($uriContents, $contents);
}
I am not sure if the psr7 stream method __toString should be altered, or alternatively one could change the build method (https://github.com/php-http/multipart-stream-builder/blob/master/src/MultipartStreamBuilder.php#L98) to something along the lines of:
if ($data['contents']->isSeekable())
{
$streams .= (string) $data['contents'];
}
else {
$streams .= $data['contents']->getContents();
}