@@ -48,16 +48,17 @@ static void dump_hex(const char* buf, size_t len) {
48
48
}
49
49
#endif
50
50
51
+ static void remove_from_beginning (std::vector<char >* buffer, size_t count) {
52
+ buffer->erase (buffer->begin (), buffer->begin () + count);
53
+ }
54
+
51
55
static void dispose_inspector (uv_handle_t * handle) {
52
- inspector_socket_t * inspector =
53
- reinterpret_cast <inspector_socket_t *>(handle->data );
56
+ inspector_socket_t * inspector = inspector_from_stream (handle);
54
57
inspector_cb close =
55
58
inspector->ws_mode ? inspector->ws_state ->close_cb : nullptr ;
56
59
inspector->buffer .clear ();
57
60
delete inspector->ws_state ;
58
61
inspector->ws_state = nullptr ;
59
- inspector->data_len = 0 ;
60
- inspector->last_read_end = 0 ;
61
62
if (close ) {
62
63
close (inspector, 0 );
63
64
}
@@ -159,21 +160,19 @@ static std::vector<char> encode_frame_hybi17(const char* message,
159
160
return frame;
160
161
}
161
162
162
- static ws_decode_result decode_frame_hybi17 (const char * buffer_begin,
163
- size_t data_length,
163
+ static ws_decode_result decode_frame_hybi17 (const std::vector<char >& buffer,
164
164
bool client_frame,
165
165
int * bytes_consumed,
166
166
std::vector<char >* output,
167
167
bool * compressed) {
168
168
*bytes_consumed = 0 ;
169
- if (data_length < 2 )
169
+ if (buffer. size () < 2 )
170
170
return FRAME_INCOMPLETE;
171
171
172
- const char * p = buffer_begin;
173
- const char * buffer_end = p + data_length;
172
+ auto it = buffer.begin ();
174
173
175
- unsigned char first_byte = *p ++;
176
- unsigned char second_byte = *p ++;
174
+ unsigned char first_byte = *it ++;
175
+ unsigned char second_byte = *it ++;
177
176
178
177
bool final = (first_byte & kFinalBit ) != 0 ;
179
178
bool reserved1 = (first_byte & kReserved1Bit ) != 0 ;
@@ -215,12 +214,12 @@ static ws_decode_result decode_frame_hybi17(const char* buffer_begin,
215
214
} else {
216
215
return FRAME_ERROR;
217
216
}
218
- if (buffer_end - p < extended_payload_length_size)
217
+ if ((buffer. end () - it) < extended_payload_length_size)
219
218
return FRAME_INCOMPLETE;
220
219
payload_length64 = 0 ;
221
220
for (int i = 0 ; i < extended_payload_length_size; ++i) {
222
221
payload_length64 <<= 8 ;
223
- payload_length64 |= static_cast <unsigned char >(*p ++);
222
+ payload_length64 |= static_cast <unsigned char >(*it ++);
224
223
}
225
224
}
226
225
@@ -233,16 +232,16 @@ static ws_decode_result decode_frame_hybi17(const char* buffer_begin,
233
232
}
234
233
size_t payload_length = static_cast <size_t >(payload_length64);
235
234
236
- if (data_length - kMaskingKeyWidthInBytes < payload_length)
235
+ if (buffer. size () - kMaskingKeyWidthInBytes < payload_length)
237
236
return FRAME_INCOMPLETE;
238
237
239
- const char * masking_key = p ;
240
- const char * payload = p + kMaskingKeyWidthInBytes ;
238
+ std::vector< char >::const_iterator masking_key = it ;
239
+ std::vector< char >::const_iterator payload = it + kMaskingKeyWidthInBytes ;
241
240
for (size_t i = 0 ; i < payload_length; ++i) // Unmask the payload.
242
241
output->insert (output->end (),
243
242
payload[i] ^ masking_key[i % kMaskingKeyWidthInBytes ]);
244
243
245
- size_t pos = p + kMaskingKeyWidthInBytes + payload_length - buffer_begin ;
244
+ size_t pos = it + kMaskingKeyWidthInBytes + payload_length - buffer. begin () ;
246
245
*bytes_consumed = pos;
247
246
return closed ? FRAME_CLOSE : FRAME_OK;
248
247
}
@@ -280,13 +279,13 @@ static void close_frame_received(inspector_socket_t* inspector) {
280
279
}
281
280
}
282
281
283
- static int parse_ws_frames (inspector_socket_t * inspector, size_t len ) {
282
+ static int parse_ws_frames (inspector_socket_t * inspector) {
284
283
int bytes_consumed = 0 ;
285
284
std::vector<char > output;
286
285
bool compressed = false ;
287
286
288
- ws_decode_result r = decode_frame_hybi17 (& inspector->buffer [ 0 ] ,
289
- len, true /* client_frame */ ,
287
+ ws_decode_result r = decode_frame_hybi17 (inspector->buffer ,
288
+ true /* client_frame */ ,
290
289
&bytes_consumed, &output,
291
290
&compressed);
292
291
// Compressed frame means client is ignoring the headers and misbehaves
@@ -312,24 +311,22 @@ static int parse_ws_frames(inspector_socket_t* inspector, size_t len) {
312
311
}
313
312
314
313
static void prepare_buffer (uv_handle_t * stream, size_t len, uv_buf_t * buf) {
315
- inspector_socket_t * inspector =
316
- reinterpret_cast < inspector_socket_t *>(stream-> data );
314
+ *buf = uv_buf_init ( new char [len], len);
315
+ }
317
316
318
- if (len > ( inspector-> buffer . size () - inspector-> data_len )) {
319
- int new_size = (inspector-> data_len + len + BUFFER_GROWTH_CHUNK_SIZE - 1 ) /
320
- BUFFER_GROWTH_CHUNK_SIZE *
321
- BUFFER_GROWTH_CHUNK_SIZE ;
322
- inspector-> buffer .resize (new_size );
317
+ static void reclaim_uv_buf ( inspector_socket_t * inspector, const uv_buf_t * buf,
318
+ ssize_t read) {
319
+ if ( read > 0 ) {
320
+ std::vector< char >& buffer = inspector-> buffer ;
321
+ buffer.insert (buffer. end (), buf-> base , buf-> base + read );
323
322
}
324
- buf->base = &inspector->buffer [inspector->data_len ];
325
- buf->len = len;
326
- inspector->data_len += len;
323
+ delete[] buf->base ;
327
324
}
328
325
329
326
static void websockets_data_cb (uv_stream_t * stream, ssize_t nread,
330
327
const uv_buf_t * buf) {
331
- inspector_socket_t * inspector =
332
- reinterpret_cast < inspector_socket_t *>(stream-> data );
328
+ inspector_socket_t * inspector = inspector_from_stream (stream);
329
+ reclaim_uv_buf (inspector, buf, nread );
333
330
if (nread < 0 || nread == UV_EOF) {
334
331
inspector->connection_eof = true ;
335
332
if (!inspector->shutting_down && inspector->ws_state ->read_cb ) {
@@ -339,29 +336,19 @@ static void websockets_data_cb(uv_stream_t* stream, ssize_t nread,
339
336
#if DUMP_READS
340
337
printf (" %s read %ld bytes\n " , __FUNCTION__, nread);
341
338
if (nread > 0 ) {
342
- dump_hex (buf->base , nread);
339
+ dump_hex (inspector->buffer .data () + inspector->buffer .size () - nread,
340
+ nread);
343
341
}
344
342
#endif
345
- // 1. Move read bytes to continue the buffer
346
- // Should be same as this is supposedly last buffer
347
- ASSERT_EQ (buf->base + buf->len , &inspector->buffer [inspector->data_len ]);
348
-
349
- // Should be noop...
350
- memmove (&inspector->buffer [inspector->last_read_end ], buf->base , nread);
351
- inspector->last_read_end += nread;
352
-
353
343
// 2. Parse.
354
344
int processed = 0 ;
355
345
do {
356
- processed = parse_ws_frames (inspector, inspector-> last_read_end );
346
+ processed = parse_ws_frames (inspector);
357
347
// 3. Fix the buffer size & length
358
348
if (processed > 0 ) {
359
- memmove (&inspector->buffer [0 ], &inspector->buffer [processed],
360
- inspector->last_read_end - processed);
361
- inspector->last_read_end -= processed;
362
- inspector->data_len = inspector->last_read_end ;
349
+ remove_from_beginning (&inspector->buffer , processed);
363
350
}
364
- } while (processed > 0 && inspector->data_len > 0 );
351
+ } while (processed > 0 && ! inspector->buffer . empty () );
365
352
}
366
353
}
367
354
@@ -435,7 +422,6 @@ static void handshake_complete(inspector_socket_t* inspector) {
435
422
uv_read_stop (reinterpret_cast <uv_stream_t *>(&inspector->client ));
436
423
handshake_cb callback = inspector->http_parsing_state ->callback ;
437
424
inspector->ws_state = new ws_state_s ();
438
- inspector->last_read_end = 0 ;
439
425
inspector->ws_mode = true ;
440
426
callback (inspector, kInspectorHandshakeUpgraded ,
441
427
inspector->http_parsing_state ->path );
@@ -448,8 +434,7 @@ static void cleanup_http_parsing_state(inspector_socket_t* inspector) {
448
434
449
435
static void report_handshake_failure_cb (uv_handle_t * handle) {
450
436
dispose_inspector (handle);
451
- inspector_socket_t * inspector =
452
- static_cast <inspector_socket_t *>(handle->data );
437
+ inspector_socket_t * inspector = inspector_from_stream (handle);
453
438
handshake_cb cb = inspector->http_parsing_state ->callback ;
454
439
cleanup_http_parsing_state (inspector);
455
440
cb (inspector, kInspectorHandshakeFailed , std::string ());
@@ -481,8 +466,7 @@ static void init_handshake(inspector_socket_t* inspector);
481
466
static int message_complete_cb (http_parser* parser) {
482
467
inspector_socket_t * inspector =
483
468
reinterpret_cast <inspector_socket_t *>(parser->data );
484
- struct http_parsing_state_s * state =
485
- (struct http_parsing_state_s *) inspector->http_parsing_state ;
469
+ struct http_parsing_state_s * state = inspector->http_parsing_state ;
486
470
if (parser->method != HTTP_GET) {
487
471
handshake_failed (inspector);
488
472
} else if (!parser->upgrade ) {
@@ -527,22 +511,22 @@ static void data_received_cb(uv_stream_s* client, ssize_t nread,
527
511
printf (" [%s:%d] %s\n " , __FUNCTION__, __LINE__, uv_err_name (nread));
528
512
}
529
513
#endif
530
- inspector_socket_t * inspector =
531
- reinterpret_cast < inspector_socket_t *>((client-> data ) );
514
+ inspector_socket_t * inspector = inspector_from_stream (client);
515
+ reclaim_uv_buf (inspector, buf, nread );
532
516
if (nread < 0 || nread == UV_EOF) {
533
517
close_and_report_handshake_failure (inspector);
534
518
} else {
535
519
http_parsing_state_s* state = inspector->http_parsing_state ;
536
520
http_parser* parser = &state->parser ;
537
- http_parser_execute (parser, &state->parser_settings , &inspector->buffer [0 ],
538
- nread);
521
+ http_parser_execute (parser, &state->parser_settings ,
522
+ inspector->buffer .data (), nread);
523
+ remove_from_beginning (&inspector->buffer , nread);
539
524
if (parser->http_errno != HPE_OK) {
540
525
handshake_failed (inspector);
541
526
}
542
527
if (inspector->http_parsing_state ->done ) {
543
528
cleanup_http_parsing_state (inspector);
544
529
}
545
- inspector->data_len = 0 ;
546
530
}
547
531
}
548
532
@@ -576,7 +560,6 @@ int inspector_accept(uv_stream_t* server, inspector_socket_t* inspector,
576
560
err = uv_accept (server, client);
577
561
}
578
562
if (err == 0 ) {
579
- client->data = inspector;
580
563
init_handshake (inspector);
581
564
inspector->http_parsing_state ->callback = callback;
582
565
err = uv_read_start (client, prepare_buffer,
0 commit comments