Closed bileslav closed 1 year ago
Hey @bileslav, thanks for bringing this to our attention :rocket:
I tested the same example on my local machine and everything seems to be working fine, so I'm having difficulty reproducing the behavior you described. I even tried different timeouts, but the result remains consistent: it either throws a TimeoutException
when the timeout triggers or returns a Response from google.com
.
Although I couldn't reproduce this issue, there is still a possibility that it might be a bug in ReactPHP. To confirm this, we would need a way to reproduce the behavior you're experiencing, which is also necessary in order to write tests for this. I think we need to gather more information in order to fully understand what's going on:
As I mentioned above, I currently can't confirm that this is a bug, so I will close this ticket for now. However, if you can provide more evidence that this is indeed a bug in this package, we can always reopen the ticket and further investigate the issue.
Hi @SimonFrings! :sunglasses:
I found that the problem only occurs when I'm connected to my VPN. Here are the steps to reproduce with Vagrant:
mkdir issue500
cd issue500
vagrant init archlinux/archlinux
vagrant up
vagrant ssh
sudo pacman -Syu --noconfirm
logout
vagrant reload
vagrant ssh
sudo pacman -S --noconfirm bat micro php composer wireguard-tools
sudo pacman -S --noconfirm --asdeps systemd-resolvconf
curl https://pastebin.com/raw/N345fGdP | tee issue500.php | bat
curl https://pastebin.com/raw/JikZhmVZ | sudo tee /etc/wireguard/wg0.conf | bat
composer require react/{http,promise-timer}
curl https://ifconfig.co/ # your IP
time php issue500.php 0.01 # fine
wg-quick up wg0 # to disconnect: wg-quick down wg0
curl https://ifconfig.co/ # new IP
time php issue500.php 0.01 # here we go
micro issue500.php # to edit
logout
vagrant destroy -f
cd ..
rm -r issue500
@bileslav Thanks for sharing this file :+1:
I'm not convinced that you using a VPN is causing this, ReactPHP doesn't really interact with this concept. The behavior you're describing is still odd and I think we have to answer the "when" question in order to figure out the "why". Do you have any information at which point the connection to google.com
takes longer (is this happening at a specific point of the connection establishment)?
I'm also curious if you've experimented with different timeouts. Does the problem persist regardless of the timeout setting?
@SimonFrings,
ReactPHP doesn't really interact with this concept.
Yeah, I understand your confusion. I'm confused too.
I think we have to answer the "when" question in order to figure out the "why". Do you have any information at which point the connection to google.com takes longer (is this happening at a specific point of the connection establishment)? Does the problem persist regardless of the timeout setting?
It's literally (always and only) when the WireGuard network interface (VPN) is up, but it seems like it's not a matter of the connection itself. Here are my stable observations:
VPN state | Timeout | Output | Time to output | Total time |
---|---|---|---|---|
any | 0 0.1 |
TimeoutException | same as timeout | same as time to output |
off | 0.01 | TimeoutException | same as timeout | same as time to output |
on | 0.01 | TimeoutException | same as timeout | ~10 |
any | 1 10 |
Response (200 OK) | 0.2-0.8 | same as time to output |
This behavior is still reproducible with the commands above.
What output do you see when it returns after ~10 seconds?
Nothing, the script just exits. Relevant output happens much earlier, as expected.
Important note: the problem is observed with a timeout of 0.01, but not 0.1, although the request itself takes up to a second in any case, which is also clear from the table. Because of this, I have absolutely no idea why this might be happening.
@bileslav thanks for the additional input on this, but I'm still not sure what could be causing this behavior. Another approach you can try is, instead of using the default React\Socket\Connector()
, to create a custom connector in order to listen to specific connection events happening and then use this new connector inside the HTTP client (React\Http\Browser
). This new connector would still use the default React\Socket\Connector()
underneath and could look something like the example inside the socket documentation:
$connector = new React\Socket\Connector();
$connector->connect($uri)->then(function (React\Socket\ConnectionInterface $connection) {
$connection->write('...');
$connection->end();
}, function (Exception $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
});
The events you can listen to are described inside the reactphp/socket "Connection usage" chapter.
It's been a while since your last message (my bad, had some busy months and now catching up outstanding ticket replies), maybe you found the cause or even a solution for this in the meantime? Happy about your input on this :)
Hey @SimonFrings,
Glad to hear from you. Sorry, no news on this issue.
I'm now using a different type of VPN, the problem was observed when using WireGuard tunnel, which I don't currently have on lease, so I have no way of confirming the bug at this time.
In theory, I could install a WireGuard server on my VPS or even locally maybe, but I don't think I can find the time for this now, unfortunately.
@bileslav I've fixed a somewhat nasty bug earlier this week that might be related: https://github.com/reactphp/socket/pull/311
Perhaps you can update to the latest versions and try again? The problem specifically deals with cancellation of connection attempts during a very small 50ms time window depending on DNS resolution order between IPv4/IPv6, so this may indeed be indirectly affected by the kind of VPN you're using.
Please report back if get more insights :+1:
@clue,
Nice job fixing that bug 👍
As I wrote above, I no longer have access to the WireGuard configurations I was using. Russia recently started experimenting with blocking WireGuard, so I've switched to a more obscure protocol.
However, I remembered that free VPN configurations can be found on the Internet. They're probably stealing personal data, dunno. The point is that I found a working config and tried to reproduce the problem.
I was unable to reproduce it either with new versions or with those that were available at the time this issue was created.
This is weird. There's a recipe above for reproducing the problem, which I tested on different computers. The only thing missing now is the WireGuard configuration from then. That config remained in the recipe (link to pastebin), but it has long expired.
No ideas...
Hello. The following code, contrary to expectations, doesn't return after 0.02 seconds. Or rather, not every run. Otherwise, it waits for something up to 10 seconds. The problem doesn't occur if you change
React\Http\Browser::get()
toReact\Promise\Timer\sleep()
.