Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix corrupt reads. #61

Merged
merged 2 commits into from
Jun 15, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ class Connection
*/
private $pings = 0;

/**
* Chunk size in bytes to use when reading with fread.
* @var int
*/
private $chunkSize = 8192;

/**
* Return the number of pings.
*
Expand Down Expand Up @@ -159,7 +165,21 @@ private function receive($len = null)
{

if ($len) {
$line = fread($this->streamSocket, $len);
$chunkSize = $this->chunkSize;
$line = null;
$receivedBytes = 0;
while ($receivedBytes < $len) {
$bytesLeft = $len - $receivedBytes;
if ( $bytesLeft < 1500 ) {
$chunkSize = $bytesLeft;
}

$line .= fread($this->streamSocket, $chunkSize);
$receivedBytes += $chunkSize;
}
if (strlen($line) > 2) {
$line = substr($line, 0, -2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line create the regression, basically if there is escape char at the end of message, using rtrim is safer, but I'm not sure if the need to be done here. Maybe you should double check if you don't introduce those two bytes in your own code.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not at home but I will look at it ASAP. Thanks!

Copy link
Contributor Author

@byrnedo byrnedo Jun 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're probably right that I don't need to trim those, I'm using protobuf on the wire and had a corrupt message initially when I didn't trim them but that must have been caused by something else I was doing.

Copy link
Contributor Author

@byrnedo byrnedo Jun 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just had a look at the spec for MSG and the payload length doesn't include the \r\n at the end, from the example at http://nats.io/documentation/internals/nats-protocol/#a-name-msg-a-msg:4b9a176fc3df6b183e7b5ba0c60737ef.
I believe I added this line since initially I had incorrectly set if ( $bytesLeft < 1500 ) instead of the correct if ( $bytesLeft < $this->chunksize ), and that ended up reading in the \r\n at the end in cases.

Removing the substr section seems to work fine locally for me.

}
} else {
$line = fgets($this->streamSocket);
}
Expand Down Expand Up @@ -425,6 +445,13 @@ public function reconnect()
$this->connect();
}

/**
* @param integer $chunkSize Set byte chunk len to read when reading from wire
*/
public function setChunkSize($chunkSize){
$this->chunkSize = $chunkSize;
}

/**
* Close will close the connection to the server.
*
Expand Down