@@ -22,6 +22,7 @@ struct http_parsing_state_s {
22
22
http_parser parser;
23
23
http_parser_settings parser_settings;
24
24
handshake_cb callback;
25
+ bool done;
25
26
bool parsing_value;
26
27
char * ws_key;
27
28
char * path;
@@ -482,24 +483,42 @@ static void handshake_complete(inspector_socket_t* inspector) {
482
483
inspector->http_parsing_state ->path );
483
484
}
484
485
485
- static void cleanup_http_parsing_state (struct http_parsing_state_s * state) {
486
+ static void cleanup_http_parsing_state (inspector_socket_t * inspector) {
487
+ struct http_parsing_state_s * state = inspector->http_parsing_state ;
486
488
free (state->current_header );
487
489
free (state->path );
488
490
free (state->ws_key );
489
491
free (state);
492
+ inspector->http_parsing_state = nullptr ;
493
+ }
494
+
495
+ static void report_handshake_failure_cb (uv_handle_t * handle) {
496
+ dispose_inspector (handle);
497
+ inspector_socket_t * inspector =
498
+ static_cast <inspector_socket_t *>(handle->data );
499
+ handshake_cb cb = inspector->http_parsing_state ->callback ;
500
+ cleanup_http_parsing_state (inspector);
501
+ cb (inspector, kInspectorHandshakeFailed , nullptr );
502
+ }
503
+
504
+ static void close_and_report_handshake_failure (inspector_socket_t * inspector) {
505
+ uv_handle_t * socket = reinterpret_cast <uv_handle_t *>(&inspector->client );
506
+ if (uv_is_closing (socket)) {
507
+ report_handshake_failure_cb (socket);
508
+ } else {
509
+ uv_read_stop (reinterpret_cast <uv_stream_t *>(socket));
510
+ uv_close (socket, report_handshake_failure_cb);
511
+ }
490
512
}
491
513
492
514
static void handshake_failed (inspector_socket_t * inspector) {
493
- http_parsing_state_s* state = inspector->http_parsing_state ;
494
515
const char HANDSHAKE_FAILED_RESPONSE[] =
495
516
" HTTP/1.0 400 Bad Request\r\n "
496
517
" Content-Type: text/html; charset=UTF-8\r\n\r\n "
497
518
" WebSockets request was expected\r\n " ;
498
519
write_to_client (inspector, HANDSHAKE_FAILED_RESPONSE,
499
520
sizeof (HANDSHAKE_FAILED_RESPONSE) - 1 );
500
- close_connection (inspector);
501
- inspector->http_parsing_state = nullptr ;
502
- state->callback (inspector, kInspectorHandshakeFailed , state->path );
521
+ close_and_report_handshake_failure (inspector);
503
522
}
504
523
505
524
// init_handshake references message_complete_cb
@@ -542,11 +561,10 @@ static int message_complete_cb(http_parser* parser) {
542
561
int len = sizeof (accept_response);
543
562
if (write_to_client (inspector, accept_response, len) >= 0 ) {
544
563
handshake_complete (inspector);
564
+ inspector->http_parsing_state ->done = true ;
545
565
} else {
546
- state->callback (inspector, kInspectorHandshakeFailed , nullptr );
547
- close_connection (inspector);
566
+ close_and_report_handshake_failure (inspector);
548
567
}
549
- inspector->http_parsing_state = nullptr ;
550
568
} else {
551
569
handshake_failed (inspector);
552
570
}
@@ -565,27 +583,21 @@ static void data_received_cb(uv_stream_s* client, ssize_t nread,
565
583
#endif
566
584
inspector_socket_t * inspector =
567
585
reinterpret_cast <inspector_socket_t *>((client->data ));
568
- http_parsing_state_s* state = inspector->http_parsing_state ;
569
586
if (nread < 0 || nread == UV_EOF) {
570
- inspector->http_parsing_state ->callback (inspector,
571
- kInspectorHandshakeFailed ,
572
- nullptr );
573
- close_connection (inspector);
574
- inspector->http_parsing_state = nullptr ;
587
+ close_and_report_handshake_failure (inspector);
575
588
} else {
589
+ http_parsing_state_s* state = inspector->http_parsing_state ;
576
590
http_parser* parser = &state->parser ;
577
- ssize_t parsed = http_parser_execute (parser, &state->parser_settings ,
578
- inspector->buffer ,
579
- nread);
580
- if (parsed < nread) {
591
+ http_parser_execute (parser, &state->parser_settings , inspector->buffer ,
592
+ nread);
593
+ if (parser->http_errno != HPE_OK) {
581
594
handshake_failed (inspector);
582
595
}
596
+ if (inspector->http_parsing_state ->done ) {
597
+ cleanup_http_parsing_state (inspector);
598
+ }
583
599
inspector->data_len = 0 ;
584
600
}
585
-
586
- if (inspector->http_parsing_state == nullptr ) {
587
- cleanup_http_parsing_state (state);
588
- }
589
601
}
590
602
591
603
static void init_handshake (inspector_socket_t * inspector) {
@@ -600,6 +612,7 @@ static void init_handshake(inspector_socket_t* inspector) {
600
612
if (state->path ) {
601
613
state->path [0 ] = ' \0 ' ;
602
614
}
615
+ state->done = false ;
603
616
http_parser_init (&state->parser , HTTP_REQUEST);
604
617
state->parser .data = inspector;
605
618
http_parser_settings* settings = &state->parser_settings ;
0 commit comments