PluginProbe ʕ •ᴥ•ʔ
Kubio AI Page Builder / trunk
Kubio AI Page Builder vtrunk
2.9.0 2.8.6 2.8.5 2.8.4 2.8.3 2.8.2 2.8.1 trunk 1.0.0 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.9.0 2.0.0 2.1.1 2.1.2 2.1.3 2.2.0 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.5 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.6.2 2.6.3 2.6.5 2.6.6 2.6.7 2.7.0 2.7.1 2.7.2 2.7.3 2.8.0
kubio / vendor / symfony / var-dumper / Server / DumpServer.php
kubio / vendor / symfony / var-dumper / Server Last commit date
Connection.php 1 year ago DumpServer.php 1 year ago
DumpServer.php
116 lines
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Symfony\Component\VarDumper\Server;
13
14 use Psr\Log\LoggerInterface;
15 use Symfony\Component\VarDumper\Cloner\Data;
16 use Symfony\Component\VarDumper\Cloner\Stub;
17
18 /**
19 * A server collecting Data clones sent by a ServerDumper.
20 *
21 * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
22 *
23 * @final
24 */
25 class DumpServer
26 {
27 private $host;
28 private $logger;
29
30 /**
31 * @var resource|null
32 */
33 private $socket;
34
35 public function __construct(string $host, ?LoggerInterface $logger = null)
36 {
37 if (!str_contains($host, '://')) {
38 $host = 'tcp://'.$host;
39 }
40
41 $this->host = $host;
42 $this->logger = $logger;
43 }
44
45 public function start(): void
46 {
47 if (!$this->socket = stream_socket_server($this->host, $errno, $errstr)) {
48 throw new \RuntimeException(sprintf('Server start failed on "%s": ', $this->host).$errstr.' '.$errno);
49 }
50 }
51
52 public function listen(callable $callback): void
53 {
54 if (null === $this->socket) {
55 $this->start();
56 }
57
58 foreach ($this->getMessages() as $clientId => $message) {
59 if ($this->logger) {
60 $this->logger->info('Received a payload from client {clientId}', ['clientId' => $clientId]);
61 }
62
63 $payload = @unserialize(base64_decode($message), ['allowed_classes' => [Data::class, Stub::class]]);
64
65 // Impossible to decode the message, give up.
66 if (false === $payload) {
67 if ($this->logger) {
68 $this->logger->warning('Unable to decode a message from {clientId} client.', ['clientId' => $clientId]);
69 }
70
71 continue;
72 }
73
74 if (!\is_array($payload) || \count($payload) < 2 || !$payload[0] instanceof Data || !\is_array($payload[1])) {
75 if ($this->logger) {
76 $this->logger->warning('Invalid payload from {clientId} client. Expected an array of two elements (Data $data, array $context)', ['clientId' => $clientId]);
77 }
78
79 continue;
80 }
81
82 [$data, $context] = $payload;
83
84 $callback($data, $context, $clientId);
85 }
86 }
87
88 public function getHost(): string
89 {
90 return $this->host;
91 }
92
93 private function getMessages(): iterable
94 {
95 $sockets = [(int) $this->socket => $this->socket];
96 $write = [];
97
98 while (true) {
99 $read = $sockets;
100 stream_select($read, $write, $write, null);
101
102 foreach ($read as $stream) {
103 if ($this->socket === $stream) {
104 $stream = stream_socket_accept($this->socket);
105 $sockets[(int) $stream] = $stream;
106 } elseif (feof($stream)) {
107 unset($sockets[(int) $stream]);
108 fclose($stream);
109 } else {
110 yield (int) $stream => fgets($stream);
111 }
112 }
113 }
114 }
115 }
116