Passed
Push — master ( beaa4b...da3f2a )
by Shahrad
02:02
created
src/Traits/WSClientTrait.php 2 patches
Indentation   +219 added lines, -219 removed lines patch added patch discarded remove patch
@@ -17,224 +17,224 @@
 block discarded – undo
17 17
 trait WSClientTrait
18 18
 {
19 19
 
20
-	/**
21
-	 * Validates whether server sent valid upgrade response
22
-	 *
23
-	 * @param WSConfig $config
24
-	 * @param string $pathWithQuery
25
-	 * @param string $key
26
-	 * @throws ConnectionException
27
-	 */
28
-	private function validateResponse(WSConfig $config, string $pathWithQuery, string $key): void
29
-	{
30
-		$response = stream_get_line($this->socket, self::DEFAULT_RESPONSE_HEADER, "\r\n\r\n");
31
-		if (!preg_match(self::SEC_WEBSOCKET_ACCEPT_PTTRN, $response, $matches)) {
32
-			$address = $config->getScheme() . '://' . $config->getHost() . ':' . $config->getPort() . $pathWithQuery;
33
-			throw new ConnectionException(
34
-				"Connection to '{$address}' failed: Server sent invalid upgrade response:\n"
35
-				. $response, CommonsContract::CLIENT_INVALID_UPGRADE_RESPONSE
36
-			);
37
-		}
38
-
39
-		$keyAccept = trim($matches[1]);
40
-		$expectedResponse = base64_encode(pack('H*', sha1($key . self::SERVER_KEY_ACCEPT)));
41
-		if ($keyAccept !== $expectedResponse) {
42
-			throw new ConnectionException('Server sent bad upgrade response.',
43
-				CommonsContract::CLIENT_INVALID_UPGRADE_RESPONSE);
44
-		}
45
-	}
46
-
47
-	/**
48
-	 *  Gets host uri based on protocol
49
-	 *
50
-	 * @param WSConfig $config
51
-	 * @return string
52
-	 * @throws BadUriException
53
-	 */
54
-	private function getHostUri(WSConfig $config): string
55
-	{
56
-		if (in_array($config->getScheme(), ['ws', 'wss'], true) === false) {
57
-			throw new BadUriException(
58
-				"Url should have scheme ws or wss, not '{$config->getScheme()}' from URI '$this->socketUrl' .",
59
-				CommonsContract::CLIENT_INCORRECT_SCHEME
60
-			);
61
-		}
62
-
63
-		return ($config->getScheme() === 'wss' ? 'ssl' : 'tcp') . '://' . $config->getHost();
64
-	}
65
-
66
-	/**
67
-	 * @param string $data
68
-	 * @return float|int
69
-	 * @throws ConnectionException
70
-	 */
71
-	private function getPayloadLength(string $data): float|int
72
-	{
73
-		$payloadLength = (int)ord($data[1]) & self::MASK_127; // Bits 1-7 in byte 1
74
-		if ($payloadLength > self::MASK_125) {
75
-			if ($payloadLength === self::MASK_126) {
76
-				$data = $this->read(2); // 126: Payload is a 16-bit unsigned int
77
-			} else {
78
-				$data = $this->read(8); // 127: Payload is a 64-bit unsigned int
79
-			}
80
-			$payloadLength = bindec(self::sprintB($data));
81
-		}
82
-
83
-		return $payloadLength;
84
-	}
85
-
86
-	/**
87
-	 * @param string $data
88
-	 * @param int $payloadLength
89
-	 * @return string
90
-	 * @throws ConnectionException
91
-	 */
92
-	private function getPayloadData(string $data, int $payloadLength): string
93
-	{
94
-		// Masking?
95
-		$mask = (bool)(ord($data[1]) >> 7);  // Bit 0 in byte 1
96
-		$payload = '';
97
-		$maskingKey = '';
98
-
99
-		// Get masking key.
100
-		if ($mask) {
101
-			$maskingKey = $this->read(4);
102
-		}
103
-
104
-		// Get the actual payload, if any (might not be for e.g. close frames.
105
-		if ($payloadLength > 0) {
106
-			$data = $this->read($payloadLength);
107
-
108
-			if ($mask) {
109
-				// Unmask payload.
110
-				for ($i = 0; $i < $payloadLength; $i++) {
111
-					$payload .= ($data[$i] ^ $maskingKey[$i % 4]);
112
-				}
113
-			} else {
114
-				$payload = $data;
115
-			}
116
-		}
117
-
118
-		return $payload;
119
-	}
120
-
121
-	/**
122
-	 * @return null|string
123
-	 * @throws \Exception
124
-	 */
125
-	protected function receiveFragment(): ?string
126
-	{
127
-		$data = $this->read(2);
128
-
129
-		$final = (bool)(ord($data[0]) & 1 << 7);
130
-
131
-		$opcodeInt = ord($data[0]) & 31;
132
-		$opcodeInts = array_flip(self::$opcodes);
133
-		if (!array_key_exists($opcodeInt, $opcodeInts)) {
134
-			throw new ConnectionException(
135
-				"Bad opcode in websocket frame: $opcodeInt",
136
-				CommonsContract::CLIENT_BAD_OPCODE
137
-			);
138
-		}
139
-
140
-		$opcode = $opcodeInts[$opcodeInt];
141
-
142
-		if ($opcode !== 'continuation') {
143
-			$this->lastOpcode = $opcode;
144
-		}
145
-
146
-		$payloadLength = $this->getPayloadLength($data);
147
-		$payload = $this->getPayloadData($data, $payloadLength);
148
-
149
-		if ($opcode === CommonsContract::EVENT_TYPE_CLOSE) {
150
-			if ($payloadLength >= 2) {
151
-				$statusBin = $payload[0] . $payload[1];
152
-				$status = bindec(sprintf('%08b%08b', ord($payload[0]), ord($payload[1])));
153
-				$this->closeStatus = $status;
154
-				$payload = substr($payload, 2);
155
-
156
-				if (!$this->isClosing) {
157
-					$this->send($statusBin . 'Close acknowledged: ' . $status,
158
-						CommonsContract::EVENT_TYPE_CLOSE); // Respond.
159
-				}
160
-			}
161
-
162
-			if ($this->isClosing) {
163
-				$this->isClosing = false; // A close response, all done.
164
-			}
165
-
166
-			fclose($this->socket);
167
-			$this->isConnected = false;
168
-		}
169
-
170
-		if (!$final) {
171
-			$this->hugePayload .= $payload;
172
-
173
-			return NULL;
174
-		}
175
-
176
-		if ($this->hugePayload) {
177
-			$payload = $this->hugePayload .= $payload;
178
-			$this->hugePayload = NULL;
179
-		}
180
-
181
-		return $payload;
182
-	}
183
-
184
-	/**
185
-	 * @param $final
186
-	 * @param $payload
187
-	 * @param $opcode
188
-	 * @param $masked
189
-	 * @throws \Exception
190
-	 */
191
-	protected function sendFragment($final, $payload, $opcode, $masked): void
192
-	{
193
-		// Binary string for header.
194
-		$frameHeadBin = '';
195
-		// Write FIN, final fragment bit.
196
-		$frameHeadBin .= (bool)$final ? '1' : '0';
197
-		// RSV 1, 2, & 3 false and unused.
198
-		$frameHeadBin .= '000';
199
-		// Opcode rest of the byte.
200
-		$frameHeadBin .= sprintf('%04b', self::$opcodes[$opcode]);
201
-		// Use masking?
202
-		$frameHeadBin .= $masked ? '1' : '0';
203
-
204
-		// 7 bits of payload length...
205
-		$payloadLen = strlen($payload);
206
-		if ($payloadLen > self::MAX_BYTES_READ) {
207
-			$frameHeadBin .= decbin(self::MASK_127);
208
-			$frameHeadBin .= sprintf('%064b', $payloadLen);
209
-		} else if ($payloadLen > self::MASK_125) {
210
-			$frameHeadBin .= decbin(self::MASK_126);
211
-			$frameHeadBin .= sprintf('%016b', $payloadLen);
212
-		} else {
213
-			$frameHeadBin .= sprintf('%07b', $payloadLen);
214
-		}
215
-
216
-		$frame = '';
217
-
218
-		// Write frame head to frame.
219
-		foreach (str_split($frameHeadBin, 8) as $binstr) {
220
-			$frame .= chr(bindec($binstr));
221
-		}
222
-		// Handle masking
223
-		if ($masked) {
224
-			// generate a random mask:
225
-			$mask = '';
226
-			for ($i = 0; $i < 4; $i++) {
227
-				$mask .= chr(random_int(0, 255));
228
-			}
229
-			$frame .= $mask;
230
-		}
231
-
232
-		// Append payload to frame:
233
-		for ($i = 0; $i < $payloadLen; $i++) {
234
-			$frame .= ($masked === true) ? $payload[$i] ^ $mask[$i % 4] : $payload[$i];
235
-		}
236
-
237
-		$this->write($frame);
238
-	}
20
+    /**
21
+     * Validates whether server sent valid upgrade response
22
+     *
23
+     * @param WSConfig $config
24
+     * @param string $pathWithQuery
25
+     * @param string $key
26
+     * @throws ConnectionException
27
+     */
28
+    private function validateResponse(WSConfig $config, string $pathWithQuery, string $key): void
29
+    {
30
+        $response = stream_get_line($this->socket, self::DEFAULT_RESPONSE_HEADER, "\r\n\r\n");
31
+        if (!preg_match(self::SEC_WEBSOCKET_ACCEPT_PTTRN, $response, $matches)) {
32
+            $address = $config->getScheme() . '://' . $config->getHost() . ':' . $config->getPort() . $pathWithQuery;
33
+            throw new ConnectionException(
34
+                "Connection to '{$address}' failed: Server sent invalid upgrade response:\n"
35
+                . $response, CommonsContract::CLIENT_INVALID_UPGRADE_RESPONSE
36
+            );
37
+        }
38
+
39
+        $keyAccept = trim($matches[1]);
40
+        $expectedResponse = base64_encode(pack('H*', sha1($key . self::SERVER_KEY_ACCEPT)));
41
+        if ($keyAccept !== $expectedResponse) {
42
+            throw new ConnectionException('Server sent bad upgrade response.',
43
+                CommonsContract::CLIENT_INVALID_UPGRADE_RESPONSE);
44
+        }
45
+    }
46
+
47
+    /**
48
+     *  Gets host uri based on protocol
49
+     *
50
+     * @param WSConfig $config
51
+     * @return string
52
+     * @throws BadUriException
53
+     */
54
+    private function getHostUri(WSConfig $config): string
55
+    {
56
+        if (in_array($config->getScheme(), ['ws', 'wss'], true) === false) {
57
+            throw new BadUriException(
58
+                "Url should have scheme ws or wss, not '{$config->getScheme()}' from URI '$this->socketUrl' .",
59
+                CommonsContract::CLIENT_INCORRECT_SCHEME
60
+            );
61
+        }
62
+
63
+        return ($config->getScheme() === 'wss' ? 'ssl' : 'tcp') . '://' . $config->getHost();
64
+    }
65
+
66
+    /**
67
+     * @param string $data
68
+     * @return float|int
69
+     * @throws ConnectionException
70
+     */
71
+    private function getPayloadLength(string $data): float|int
72
+    {
73
+        $payloadLength = (int)ord($data[1]) & self::MASK_127; // Bits 1-7 in byte 1
74
+        if ($payloadLength > self::MASK_125) {
75
+            if ($payloadLength === self::MASK_126) {
76
+                $data = $this->read(2); // 126: Payload is a 16-bit unsigned int
77
+            } else {
78
+                $data = $this->read(8); // 127: Payload is a 64-bit unsigned int
79
+            }
80
+            $payloadLength = bindec(self::sprintB($data));
81
+        }
82
+
83
+        return $payloadLength;
84
+    }
85
+
86
+    /**
87
+     * @param string $data
88
+     * @param int $payloadLength
89
+     * @return string
90
+     * @throws ConnectionException
91
+     */
92
+    private function getPayloadData(string $data, int $payloadLength): string
93
+    {
94
+        // Masking?
95
+        $mask = (bool)(ord($data[1]) >> 7);  // Bit 0 in byte 1
96
+        $payload = '';
97
+        $maskingKey = '';
98
+
99
+        // Get masking key.
100
+        if ($mask) {
101
+            $maskingKey = $this->read(4);
102
+        }
103
+
104
+        // Get the actual payload, if any (might not be for e.g. close frames.
105
+        if ($payloadLength > 0) {
106
+            $data = $this->read($payloadLength);
107
+
108
+            if ($mask) {
109
+                // Unmask payload.
110
+                for ($i = 0; $i < $payloadLength; $i++) {
111
+                    $payload .= ($data[$i] ^ $maskingKey[$i % 4]);
112
+                }
113
+            } else {
114
+                $payload = $data;
115
+            }
116
+        }
117
+
118
+        return $payload;
119
+    }
120
+
121
+    /**
122
+     * @return null|string
123
+     * @throws \Exception
124
+     */
125
+    protected function receiveFragment(): ?string
126
+    {
127
+        $data = $this->read(2);
128
+
129
+        $final = (bool)(ord($data[0]) & 1 << 7);
130
+
131
+        $opcodeInt = ord($data[0]) & 31;
132
+        $opcodeInts = array_flip(self::$opcodes);
133
+        if (!array_key_exists($opcodeInt, $opcodeInts)) {
134
+            throw new ConnectionException(
135
+                "Bad opcode in websocket frame: $opcodeInt",
136
+                CommonsContract::CLIENT_BAD_OPCODE
137
+            );
138
+        }
139
+
140
+        $opcode = $opcodeInts[$opcodeInt];
141
+
142
+        if ($opcode !== 'continuation') {
143
+            $this->lastOpcode = $opcode;
144
+        }
145
+
146
+        $payloadLength = $this->getPayloadLength($data);
147
+        $payload = $this->getPayloadData($data, $payloadLength);
148
+
149
+        if ($opcode === CommonsContract::EVENT_TYPE_CLOSE) {
150
+            if ($payloadLength >= 2) {
151
+                $statusBin = $payload[0] . $payload[1];
152
+                $status = bindec(sprintf('%08b%08b', ord($payload[0]), ord($payload[1])));
153
+                $this->closeStatus = $status;
154
+                $payload = substr($payload, 2);
155
+
156
+                if (!$this->isClosing) {
157
+                    $this->send($statusBin . 'Close acknowledged: ' . $status,
158
+                        CommonsContract::EVENT_TYPE_CLOSE); // Respond.
159
+                }
160
+            }
161
+
162
+            if ($this->isClosing) {
163
+                $this->isClosing = false; // A close response, all done.
164
+            }
165
+
166
+            fclose($this->socket);
167
+            $this->isConnected = false;
168
+        }
169
+
170
+        if (!$final) {
171
+            $this->hugePayload .= $payload;
172
+
173
+            return NULL;
174
+        }
175
+
176
+        if ($this->hugePayload) {
177
+            $payload = $this->hugePayload .= $payload;
178
+            $this->hugePayload = NULL;
179
+        }
180
+
181
+        return $payload;
182
+    }
183
+
184
+    /**
185
+     * @param $final
186
+     * @param $payload
187
+     * @param $opcode
188
+     * @param $masked
189
+     * @throws \Exception
190
+     */
191
+    protected function sendFragment($final, $payload, $opcode, $masked): void
192
+    {
193
+        // Binary string for header.
194
+        $frameHeadBin = '';
195
+        // Write FIN, final fragment bit.
196
+        $frameHeadBin .= (bool)$final ? '1' : '0';
197
+        // RSV 1, 2, & 3 false and unused.
198
+        $frameHeadBin .= '000';
199
+        // Opcode rest of the byte.
200
+        $frameHeadBin .= sprintf('%04b', self::$opcodes[$opcode]);
201
+        // Use masking?
202
+        $frameHeadBin .= $masked ? '1' : '0';
203
+
204
+        // 7 bits of payload length...
205
+        $payloadLen = strlen($payload);
206
+        if ($payloadLen > self::MAX_BYTES_READ) {
207
+            $frameHeadBin .= decbin(self::MASK_127);
208
+            $frameHeadBin .= sprintf('%064b', $payloadLen);
209
+        } else if ($payloadLen > self::MASK_125) {
210
+            $frameHeadBin .= decbin(self::MASK_126);
211
+            $frameHeadBin .= sprintf('%016b', $payloadLen);
212
+        } else {
213
+            $frameHeadBin .= sprintf('%07b', $payloadLen);
214
+        }
215
+
216
+        $frame = '';
217
+
218
+        // Write frame head to frame.
219
+        foreach (str_split($frameHeadBin, 8) as $binstr) {
220
+            $frame .= chr(bindec($binstr));
221
+        }
222
+        // Handle masking
223
+        if ($masked) {
224
+            // generate a random mask:
225
+            $mask = '';
226
+            for ($i = 0; $i < 4; $i++) {
227
+                $mask .= chr(random_int(0, 255));
228
+            }
229
+            $frame .= $mask;
230
+        }
231
+
232
+        // Append payload to frame:
233
+        for ($i = 0; $i < $payloadLen; $i++) {
234
+            $frame .= ($masked === true) ? $payload[$i] ^ $mask[$i % 4] : $payload[$i];
235
+        }
236
+
237
+        $this->write($frame);
238
+    }
239 239
 
240 240
 }
241 241
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -70,7 +70,7 @@  discard block
 block discarded – undo
70 70
 	 */
71 71
 	private function getPayloadLength(string $data): float|int
72 72
 	{
73
-		$payloadLength = (int)ord($data[1]) & self::MASK_127; // Bits 1-7 in byte 1
73
+		$payloadLength = (int) ord($data[1]) & self::MASK_127; // Bits 1-7 in byte 1
74 74
 		if ($payloadLength > self::MASK_125) {
75 75
 			if ($payloadLength === self::MASK_126) {
76 76
 				$data = $this->read(2); // 126: Payload is a 16-bit unsigned int
@@ -92,7 +92,7 @@  discard block
 block discarded – undo
92 92
 	private function getPayloadData(string $data, int $payloadLength): string
93 93
 	{
94 94
 		// Masking?
95
-		$mask = (bool)(ord($data[1]) >> 7);  // Bit 0 in byte 1
95
+		$mask = (bool) (ord($data[1]) >> 7); // Bit 0 in byte 1
96 96
 		$payload = '';
97 97
 		$maskingKey = '';
98 98
 
@@ -108,7 +108,7 @@  discard block
 block discarded – undo
108 108
 			if ($mask) {
109 109
 				// Unmask payload.
110 110
 				for ($i = 0; $i < $payloadLength; $i++) {
111
-					$payload .= ($data[$i] ^ $maskingKey[$i % 4]);
111
+					$payload .= ($data[$i]^$maskingKey[$i % 4]);
112 112
 				}
113 113
 			} else {
114 114
 				$payload = $data;
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
 	{
127 127
 		$data = $this->read(2);
128 128
 
129
-		$final = (bool)(ord($data[0]) & 1 << 7);
129
+		$final = (bool) (ord($data[0]) & 1 << 7);
130 130
 
131 131
 		$opcodeInt = ord($data[0]) & 31;
132 132
 		$opcodeInts = array_flip(self::$opcodes);
@@ -193,7 +193,7 @@  discard block
 block discarded – undo
193 193
 		// Binary string for header.
194 194
 		$frameHeadBin = '';
195 195
 		// Write FIN, final fragment bit.
196
-		$frameHeadBin .= (bool)$final ? '1' : '0';
196
+		$frameHeadBin .= (bool) $final ? '1' : '0';
197 197
 		// RSV 1, 2, & 3 false and unused.
198 198
 		$frameHeadBin .= '000';
199 199
 		// Opcode rest of the byte.
@@ -231,7 +231,7 @@  discard block
 block discarded – undo
231 231
 
232 232
 		// Append payload to frame:
233 233
 		for ($i = 0; $i < $payloadLen; $i++) {
234
-			$frame .= ($masked === true) ? $payload[$i] ^ $mask[$i % 4] : $payload[$i];
234
+			$frame .= ($masked === true) ? $payload[$i]^$mask[$i % 4] : $payload[$i];
235 235
 		}
236 236
 
237 237
 		$this->write($frame);
Please login to merge, or discard this patch.
src/WebSocketClient.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -17,25 +17,25 @@
 block discarded – undo
17 17
 abstract class WebSocketClient implements WebSocketContract, MessageContract
18 18
 {
19 19
 
20
-	/**
21
-	 * @var array
22
-	 */
23
-	public array $pathParams = [];
20
+    /**
21
+     * @var array
22
+     */
23
+    public array $pathParams = [];
24 24
 
25
-	/**
26
-	 * You may want to implement these methods to bring ping/pong events
27
-	 *
28
-	 * @param ConnectionContract $conn
29
-	 * @param string $msg
30
-	 * @throws WebSocketException
31
-	 */
32
-	abstract public function onPing(ConnectionContract $conn, string $msg);
25
+    /**
26
+     * You may want to implement these methods to bring ping/pong events
27
+     *
28
+     * @param ConnectionContract $conn
29
+     * @param string $msg
30
+     * @throws WebSocketException
31
+     */
32
+    abstract public function onPing(ConnectionContract $conn, string $msg);
33 33
 
34
-	/**
35
-	 * @param ConnectionContract $conn
36
-	 * @param mixed $msg
37
-	 * @throws WebSocketException
38
-	 */
39
-	abstract public function onPong(ConnectionContract $conn, mixed $msg);
34
+    /**
35
+     * @param ConnectionContract $conn
36
+     * @param mixed $msg
37
+     * @throws WebSocketException
38
+     */
39
+    abstract public function onPong(ConnectionContract $conn, mixed $msg);
40 40
 
41 41
 }
Please login to merge, or discard this patch.