roadrunner-server / roadrunner

🤯 High-performance PHP application server, process manager written in Go and powered with plugins
https://docs.roadrunner.dev
MIT License
7.86k stars 409 forks source link

Zend\Diactoros\Exception\InvalidArgumentException: Invalid header value type; must be a string or numeric; received boolean #130

Closed 4n70w4 closed 5 years ago

4n70w4 commented 5 years ago

Setup from instruction: https://github.com/spiral/roadrunner/wiki/Symfony-Framework

Exception on each request:

Zend\Diactoros\Exception\InvalidArgumentException: Invalid header value type; must be a string or numeric; received boolean in /var/www/app/current/vendor/zendframework/zend-diactoros/src/HeaderSecurity.php:139
Stack trace:
#0 /var/www/app/current/vendor/zendframework/zend-diactoros/src/MessageTrait.php(398): Zend\Diactoros\HeaderSecurity::assertValid(true)
#1 [internal function]: Zend\Diactoros\Response->Zend\Diactoros\{closure}(true)
#2 /var/www/app/current/vendor/zendframework/zend-diactoros/src/MessageTrait.php(401): array_map(Object(Closure), Array)
#3 /var/www/app/current/vendor/zendframework/zend-diactoros/src/MessageTrait.php(338): Zend\Diactoros\Response->filterHeaderValue(Array)
#4 /var/www/app/current/vendor/zendframework/zend-diactoros/src/Response.php(134): Zend\Diactoros\Response->setHeaders(Array)
#5 /var/www/app/current/vendor/symfony/psr-http-message-bridge/Factory/DiactorosFactory.php(160): Zend\Diactoros\Response->__construct(Object(Zend\Diactoros\Stream), 200, Array)
#6 /var/www/app/current/worker.php(52): Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory->createResponse(Object(Symfony\Component\HttpFoundation\Response))
#7 {main}
OO00O0O commented 5 years ago

Today I had same problem, so I added debug and now waiting for bad headers, but because of some unknown reasons it does not reappear again. So maybe you could add this too.

while ($request = $client->acceptRequest()) {
    $headers = [];
    try {
        $response = $httpServer->handlePSR7($request);
        $headers = $response->getHeaders();
        $client->respond($response);
        $httpServer->cleanup();
    } catch (\Zend\Diactoros\Exception\InvalidArgumentException $e) {
        $client->getWorker()->error("$e \n\n" . print_r($headers, true));
    } catch (\Throwable $e) {
        $client->getWorker()->error((string) $e);
    }
}
4n70w4 commented 5 years ago

@BunnyHolder my app generated header:

$h['Access-Control-Allow-Credentials'] = true;

I add quotes and all work. It is strange that this library Zend\Diactoros does not accept the boolean header without quotes, because inside the symfony it all works correctly.

Perhaps there is a parameter in the Zend\Diactoros so that it does not throw out exceptions about it.

Perhaps need to create a issue in the Zend\Diactoros, or come up with a workaround and publish it in the instructions.

Because the current roadrunner symfony-example from the instructions is not fully compatible with the native symfony app.

Alex-Bond commented 5 years ago

@4n70w4 hey. I didn't think of this case. I will fix it inside RR and my side module for SF.

wolfy-j commented 5 years ago

You can use less strict PSR7 implementation instead.

askobara commented 5 years ago

Same problem here: Invalid header value type; must be a string or numeric; received NULL

wolfy-j commented 5 years ago

Hi, this is caused by the strict implementation of Zend Diactoros. If you have any issues using this library try to use alternative PSR-7 implementation. For example https://github.com/Nyholm/psr7 is fully compatible with RR and even provides greater performance.

To enable alternative PSR-7 provides alter your PSR7Client constructor like that:

$factory = new \Nyholm\Psr7\Factory\Psr17Factory();
$psr7 = new PSR7Client($worker, $factory, $factory, $factory);

In our synthetic benches it shows +30% performance boost compared to Zend version.

wolfy-j commented 5 years ago

Closing due to inability to bypass strict implementation of Zend. Use alternative PSR-7 implementations listed above.