Skip to content

Commit fcf195e

Browse files
author
Guilherme Souza
committed
Changed handshake reading logic. Fixes #13
1 parent d67ecac commit fcf195e

File tree

1 file changed

+52
-20
lines changed

1 file changed

+52
-20
lines changed

Connection.js

+52-20
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function Connection(socket, parentOrUrl, callback) {
4141

4242
this.socket = socket
4343
this.readyState = this.CONNECTING
44-
this.buffer = '' // string before handshake, Buffer after that
44+
this.buffer = new Buffer(0)
4545
this.frameBuffer = null // string for text frames and InStream for binary frames
4646
this.outStream = null // current allocated OutStream object for sending binary frames
4747
this.key = null // the Sec-WebSocket-Key header
@@ -192,28 +192,18 @@ Connection.prototype.doRead = function () {
192192
return
193193
}
194194

195+
// Save to the internal buffer
196+
this.buffer = Buffer.concat([this.buffer, buffer], this.buffer.length + buffer.length)
197+
195198
if (this.readyState === this.CONNECTING) {
196-
// Do the handshake and try to connect
197-
this.buffer += buffer.toString()
198-
if (this.buffer.length > Connection.maxBufferLength) {
199-
// Too big for a handshake
200-
return this.socket.end(this.server ? 'HTTP/1.1 400 Bad Request\r\n\r\n' : undefined)
201-
}
202-
if (this.buffer.substr(-4) !== '\r\n\r\n') {
203-
// Wait for more data
199+
if (!this.readHandshake()) {
200+
// May have failed or we're waiting for more data
204201
return
205202
}
206-
temp = this.buffer.split('\r\n')
207-
if (this.server ? this.answerHandshake(temp) : this.checkHandshake(temp)) {
208-
this.buffer = new Buffer(0)
209-
this.readyState = this.OPEN
210-
this.emit('connect')
211-
} else {
212-
this.socket.end(this.server ? 'HTTP/1.1 400 Bad Request\r\n\r\n' : undefined)
213-
}
214-
} else if (this.readyState !== this.CLOSED) {
215-
// Save to the internal buffer and try to read as many frames as possible
216-
this.buffer = Buffer.concat([this.buffer, buffer], this.buffer.length + buffer.length)
203+
}
204+
205+
if (this.readyState !== this.CLOSED) {
206+
// Try to read as many frames as possible
217207
while ((temp = this.extractFrame()) === true) {}
218208
if (temp === false) {
219209
// Protocol error
@@ -245,10 +235,52 @@ Connection.prototype.startHandshake = function () {
245235
this.socket.write(str)
246236
}
247237

238+
/**
239+
* Try to read the handshake from the internal buffer
240+
* If it succeeds, the handshake data is consumed from the internal buffer
241+
* @returns {boolean} - whether the handshake was done
242+
* @private
243+
*/
244+
Connection.prototype.readHandshake = function () {
245+
var found = false,
246+
i, data
247+
248+
// Do the handshake and try to connect
249+
if (this.buffer.length > Connection.maxBufferLength) {
250+
// Too big for a handshake
251+
this.socket.end(this.server ? 'HTTP/1.1 400 Bad Request\r\n\r\n' : undefined)
252+
return false
253+
}
254+
255+
// Search for '\r\n\r\n'
256+
for (i = 0; i < this.buffer.length - 3; i++) {
257+
if (this.buffer[i] === 13 && this.buffer[i + 2] === 13 &&
258+
this.buffer[i + 1] === 10 && this.buffer[i + 3] === 10) {
259+
found = true
260+
break
261+
}
262+
}
263+
if (!found) {
264+
// Wait for more data
265+
return false
266+
}
267+
data = this.buffer.slice(0, i + 4).toString().split('\r\n')
268+
if (this.server ? this.answerHandshake(data) : this.checkHandshake(data)) {
269+
this.buffer = this.buffer.slice(i + 4)
270+
this.readyState = this.OPEN
271+
this.emit('connect')
272+
return true
273+
} else {
274+
this.socket.end(this.server ? 'HTTP/1.1 400 Bad Request\r\n\r\n' : undefined)
275+
return false
276+
}
277+
}
278+
248279
/**
249280
* Read headers from HTTP protocol
250281
* Update the Connection#headers property
251282
* @param {string[]} lines one for each '\r\n'-separated HTTP request line
283+
* @private
252284
*/
253285
Connection.prototype.readHeaders = function (lines) {
254286
var i, match

0 commit comments

Comments
 (0)