1

I have a DiscordPHP bot that I'm trying to download some web pages that require a cookie. It seems I need to use a curl handler with Guzzle because the ReactPHP http browser doesn't support cookies.

I've created this minimal script:

use GuzzleHttp\Client;
use GuzzleHttp\Handler\CurlMultiHandler;
use GuzzleHttp\HandlerStack;
use Psr\Http\Message\ResponseInterface;

include 'vendor/autoload.php';

$loop = \React\EventLoop\Loop::get();

$curl = new CurlMultiHandler;
$handler = HandlerStack::create($curl);
$client = new Client( [ /* 'cookies' => $cookieJar, */ 'handler' => $handler ] );

$promise = $client->getAsync('https://httpstat.us/200')
    ->then(
        function (ResponseInterface $res) {
            echo 'response: ' . $res->getStatusCode() . PHP_EOL;
        },
        function (\Exception $e) {
            echo $e->getMessage() . PHP_EOL;
        }
    );


$timer = $loop->addPeriodicTimer(0.5, function () use ($curl, $promise) {
    if ($promise->getState() === 'pending') {
    echo 'Tick ';
    $curl->tick();
    }
    echo 'Beat ';
});

$loop->run();

This exits immediately without the code adding the addPeriodicTimer to check pending and call tick() manually:

$ time php minimal.php
0.022u 0.010s 0:00.03 100.0%    0+0k 0+0io 67pf+0w

With the timer, it works as expected:

Tick Beat Tick Beat Tick Beat Tick Beat Tick Beat Tick Beat Tick response: 200
Beat Beat Beat ...

The idea to use a tick() came from this 73 comment closed thread on github.com.

There are some similar questions, but none of them seem to address this issue:

How do I start a HTTP GET with a cookie jar and get the response in a ReactPHP event loop without using a blocking call such as ->wait() or manually tick()ing curl's handler?

James Risner
  • 5,451
  • 11
  • 25
  • 47

1 Answers1

-2

the ReactPHP http browser doesn't support cookies.

Well, ReactPHP doesn't set cookies automatically, there's already a ticket discussing this topic: https://github.com/reactphp/http/issues/445, but you can still go the manual way and set HTTP cookie header.

It's also worth mentioning that using ReactPHP with Guzzle won't work as Guzzle will block ReactPHP's eventloop. This means you can send multiple requests, but can't do anything else asynchronously.

  • Thanks for the answer. I’m aware of the ticket over cookies and the ability to set cookie headers manually (with much effort and code). However, using a url handler and manually ticking curl, there is zero blocking. My example minimal code demonstrates this. So this answer does answer the question and is a regression from what I have in the question. – James Risner Feb 06 '23 at 15:25
  • Url handler should have been curl handler – James Risner Feb 06 '23 at 15:33
  • could you comment on my points? Thank you – James Risner Feb 06 '23 at 18:12