I'm trying to access an uploaded file in the history middleware for Guzzle (v6).
My actual code receives a request (so is using the ServerRequestInterface
), then uses Guzzle to send the request elsewhere.
I'm trying to test uploaded files going through this layer, but I can't seem to access them in the Request object returned by Guzzle's middleware.
Example code:
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7\ServerRequest;
use GuzzleHttp\Psr7\UploadedFile;
class DoNotCommitTest extends \PHPUnit\Framework\TestCase
{
public function testUploads()
{
$request = new ServerRequest('GET', 'http://example.com/bla');
$file = new UploadedFile('test', 100, \UPLOAD_ERR_OK);
$request = $request->withUploadedFiles([$file]);
$this->assertCount(1, $request->getUploadedFiles());
// Mock Guzzle request, assert on the request it 'sent'
$mock = new MockHandler([
function (ServerRequest $request, array $options) {
// This fails...
$this->assertCount(1, $request->getUploadedFiles());
}
]);
$historyContainer = [];
$history = Middleware::history($historyContainer);
$handler = HandlerStack::create($mock);
$handler->push($history);
$client = new Client(['handler' => $handler]);
$client->send($request);
}
}
If you follow execution chain, $client->send($request)
at some point calls private applyOptions
function, which calls Psr7\modify_request
function. If you look at Psr7\modify_request
function:
...
if ($request instanceof ServerRequestInterface) {
return new ServerRequest(
isset($changes['method']) ? $changes['method'] : $request->getMethod(),
$uri,
$headers,
isset($changes['body']) ? $changes['body'] : $request->getBody(),
isset($changes['version'])
? $changes['version']
: $request->getProtocolVersion(),
$request->getServerParams()
);
}
...
It returns new ServerRequest
object without preserving your uploaded files array (ServerRequest
object doesn't have the uploadedFiles
as an argument in the constructor). That's why you lost your uploadedFiles
array.
UPDATE:
I created an issue and a pull request to fix it.