@@ -41,7 +41,7 @@ function Connection(socket, parentOrUrl, callback) {
41
41
42
42
this . socket = socket
43
43
this . readyState = this . CONNECTING
44
- this . buffer = '' // string before handshake, Buffer after that
44
+ this . buffer = new Buffer ( 0 )
45
45
this . frameBuffer = null // string for text frames and InStream for binary frames
46
46
this . outStream = null // current allocated OutStream object for sending binary frames
47
47
this . key = null // the Sec-WebSocket-Key header
@@ -192,28 +192,18 @@ Connection.prototype.doRead = function () {
192
192
return
193
193
}
194
194
195
+ // Save to the internal buffer
196
+ this . buffer = Buffer . concat ( [ this . buffer , buffer ] , this . buffer . length + buffer . length )
197
+
195
198
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
204
201
return
205
202
}
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
217
207
while ( ( temp = this . extractFrame ( ) ) === true ) { }
218
208
if ( temp === false ) {
219
209
// Protocol error
@@ -245,10 +235,52 @@ Connection.prototype.startHandshake = function () {
245
235
this . socket . write ( str )
246
236
}
247
237
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
+
248
279
/**
249
280
* Read headers from HTTP protocol
250
281
* Update the Connection#headers property
251
282
* @param {string[] } lines one for each '\r\n'-separated HTTP request line
283
+ * @private
252
284
*/
253
285
Connection . prototype . readHeaders = function ( lines ) {
254
286
var i , match
0 commit comments