Skip to content

Commit 3e663ab

Browse files
committed
Fix message length encoding
This fix has been taken from the master branch, see #30.
1 parent 9b4b529 commit 3e663ab

File tree

1 file changed

+16
-50
lines changed

1 file changed

+16
-50
lines changed

src/MessageProcessors/Mqtt31MessageProcessor.php

Lines changed: 16 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -97,61 +97,36 @@ public function tryFindMessageInBuffer(string $buffer, int $bufferLength, string
9797
*/
9898
public function buildConnectMessage(ConnectionSettings $connectionSettings, bool $useCleanSession = false): string
9999
{
100-
$i = 0;
101-
$buffer = '';
102-
103100
// The protocol name and version.
104-
$buffer .= chr(0x00); // length of protocol name 1
105-
$buffer .= chr(0x06); // length of protocol name 2
106-
$buffer .= chr(0x4d); // protocol name: M
107-
$buffer .= chr(0x51); // protocol name: Q
108-
$buffer .= chr(0x49); // protocol name: I
109-
$buffer .= chr(0x73); // protocol name: s
110-
$buffer .= chr(0x64); // protocol name: d
111-
$buffer .= chr(0x70); // protocol name: p
101+
$buffer = $this->buildLengthPrefixedString('MQIsdp');
112102
$buffer .= chr(0x03); // protocol version (3)
113-
$i += 9;
114103

115104
// Build connection flags based on the connection settings.
116-
$flags = $this->buildConnectionFlags($connectionSettings, $useCleanSession);
117-
$buffer .= chr($flags);
118-
$i++;
105+
$buffer .= chr($this->buildConnectionFlags($connectionSettings, $useCleanSession));
119106

120107
// Encode and add the keep alive interval.
121108
$buffer .= chr($connectionSettings->getKeepAliveInterval() >> 8);
122109
$buffer .= chr($connectionSettings->getKeepAliveInterval() & 0xff);
123-
$i += 2;
124110

125111
// Encode and add the client identifier.
126-
$clientIdPart = $this->buildLengthPrefixedString($this->clientId);
127-
$buffer .= $clientIdPart;
128-
$i += strlen($clientIdPart);
112+
$buffer .= $this->buildLengthPrefixedString($this->clientId);
129113

130114
// Encode and add the last will topic and message, if configured.
131115
if ($connectionSettings->hasLastWill()) {
132-
$topicPart = $this->buildLengthPrefixedString($connectionSettings->getLastWillTopic());
133-
$buffer .= $topicPart;
134-
$i += strlen($topicPart);
135-
136-
$messagePart = $this->buildLengthPrefixedString($connectionSettings->getLastWillMessage());
137-
$buffer .= $messagePart;
138-
$i += strlen($messagePart);
116+
$buffer .= $this->buildLengthPrefixedString($connectionSettings->getLastWillTopic());
117+
$buffer .= $this->buildLengthPrefixedString($connectionSettings->getLastWillMessage());
139118
}
140119

141120
// Encode and add the credentials, if configured.
142121
if ($connectionSettings->getUsername() !== null) {
143-
$usernamePart = $this->buildLengthPrefixedString($connectionSettings->getUsername());
144-
$buffer .= $usernamePart;
145-
$i += strlen($usernamePart);
122+
$buffer .= $this->buildLengthPrefixedString($connectionSettings->getUsername());
146123
}
147124
if ($connectionSettings->getPassword() !== null) {
148-
$passwordPart = $this->buildLengthPrefixedString($connectionSettings->getPassword());
149-
$buffer .= $passwordPart;
150-
$i += strlen($passwordPart);
125+
$buffer .= $this->buildLengthPrefixedString($connectionSettings->getPassword());
151126
}
152127

153128
// The header consists of the message type 0x10 and the length.
154-
$header = chr(0x10) . chr($i);
129+
$header = chr(0x10) . $this->encodeMessageLength(strlen($buffer));
155130

156131
return $header . $buffer;
157132
}
@@ -287,6 +262,7 @@ public function handleConnectAcknowledgement(string $message): void
287262
*/
288263
public function buildPingMessage(): string
289264
{
265+
// The message consists of the command 0xc0 and the length 0.
290266
return chr(0xc0) . chr(0x00);
291267
}
292268

@@ -297,6 +273,7 @@ public function buildPingMessage(): string
297273
*/
298274
public function buildDisconnectMessage(): string
299275
{
276+
// The message consists of the command 0xe0 and the length 0.
300277
return chr(0xe0) . chr(0x00);
301278
}
302279

@@ -307,19 +284,15 @@ public function buildSubscribeMessage(int $messageId, string $topic, int $qualit
307284
{
308285
// Encode the message id, it always consists of two bytes.
309286
$buffer = $this->encodeMessageId($messageId);
310-
$i = 2;
311287

312288
// Encode the topic as length prefixed string.
313-
$topicPart = $this->buildLengthPrefixedString($topic);
314-
$buffer .= $topicPart;
315-
$i += strlen($topicPart);
289+
$buffer .= $this->buildLengthPrefixedString($topic);
316290

317291
// Encode the quality of service level.
318292
$buffer .= chr($qualityOfService);
319-
$i++;
320293

321294
// The header consists of the message type 0x82 and the length.
322-
$header = chr(0x82) . chr($i);
295+
$header = chr(0x82) . $this->encodeMessageLength(strlen($buffer));
323296

324297
return $header . $buffer;
325298
}
@@ -331,17 +304,14 @@ public function buildUnsubscribeMessage(int $messageId, string $topic, bool $isD
331304
{
332305
// Encode the message id, it always consists of two bytes.
333306
$buffer = $this->encodeMessageId($messageId);
334-
$i = 2;
335307

336308
// Encode the topic as length prefixed string.
337-
$topicPart = $this->buildLengthPrefixedString($topic);
338-
$buffer .= $topicPart;
339-
$i += strlen($topicPart);
309+
$buffer .= $this->buildLengthPrefixedString($topic);
340310

341311
// The header consists of the message type 0xa2 and the length.
342312
// Additionally, the first byte may contain the duplicate flag.
343313
$command = 0xa2 | ($isDuplicate ? 1 << 3 : 0);
344-
$header = chr($command) . chr($i);
314+
$header = chr($command) . $this->encodeMessageLength(strlen($buffer));
345315

346316
return $header . $buffer;
347317
}
@@ -359,20 +329,16 @@ public function buildPublishMessage(
359329
): string
360330
{
361331
// Encode the topic as length prefixed string.
362-
$topicPart = $this->buildLengthPrefixedString($topic);
363-
$buffer = $topicPart;
364-
$i = strlen($topicPart);
332+
$buffer = $this->buildLengthPrefixedString($topic);
365333

366334
// Encode the message id, if given. It always consists of two bytes.
367335
if ($messageId !== null)
368336
{
369337
$buffer .= $this->encodeMessageId($messageId);
370-
$i += 2;
371338
}
372339

373340
// Add the message without encoding.
374341
$buffer .= $message;
375-
$i += strlen($message);
376342

377343
// Encode the command with supported flags.
378344
$command = 0x30;
@@ -387,7 +353,7 @@ public function buildPublishMessage(
387353
}
388354

389355
// Build the header from the command and the encoded message length.
390-
$header = chr($command) . $this->encodeMessageLength($i);
356+
$header = chr($command) . $this->encodeMessageLength(strlen($buffer));
391357

392358
return $header . $buffer;
393359
}

0 commit comments

Comments
 (0)