@@ -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 */
253285Connection . prototype . readHeaders = function ( lines ) {
254286 var i , match
0 commit comments