@@ -99,7 +99,11 @@ static int s_ws_bootstrap_on_handshake_response_headers(
9999 const struct aws_http_header * header_array ,
100100 size_t num_headers ,
101101 void * user_data );
102- static void s_ws_bootstrap_on_handshake_complete (struct aws_http_stream * stream , int error_code , void * user_data );
102+ static int s_ws_bootstrap_on_handshake_response_header_block_done (
103+ struct aws_http_stream * stream ,
104+ enum aws_http_header_block header_block ,
105+ void * user_data );
106+ static void s_ws_bootstrap_on_stream_complete (struct aws_http_stream * stream , int error_code , void * user_data );
103107
104108int aws_websocket_client_connect (const struct aws_websocket_client_connection_options * options ) {
105109 aws_http_fatal_assert_library_initialized ();
@@ -307,7 +311,8 @@ static void s_ws_bootstrap_on_http_setup(struct aws_http_connection *http_connec
307311 .request = ws_bootstrap -> handshake_request ,
308312 .user_data = ws_bootstrap ,
309313 .on_response_headers = s_ws_bootstrap_on_handshake_response_headers ,
310- .on_complete = s_ws_bootstrap_on_handshake_complete ,
314+ .on_response_header_block_done = s_ws_bootstrap_on_handshake_response_header_block_done ,
315+ .on_complete = s_ws_bootstrap_on_stream_complete ,
311316 };
312317
313318 struct aws_http_stream * handshake_stream =
@@ -393,6 +398,7 @@ static void s_ws_bootstrap_on_http_shutdown(
393398 s_ws_bootstrap_destroy (ws_bootstrap );
394399}
395400
401+ /* Invoked repeatedly as handshake response headers arrive */
396402static int s_ws_bootstrap_on_handshake_response_headers (
397403 struct aws_http_stream * stream ,
398404 enum aws_http_header_block header_block ,
@@ -444,15 +450,25 @@ static int s_ws_bootstrap_on_handshake_response_headers(
444450 return AWS_OP_ERR ;
445451}
446452
447- static void s_ws_bootstrap_on_handshake_complete (struct aws_http_stream * stream , int error_code , void * user_data ) {
453+ /**
454+ * Invoked each time we reach the end of a block of response headers.
455+ * If we got a valid 101 Switching Protocols response, we insert the websocket handler.
456+ * Note:
457+ * In HTTP, 1xx responses are "interim" responses. So a 101 Switching Protocols
458+ * response does not "complete" the stream. Once the connection has switched
459+ * protocols, the stream does not end until the whole connection is closed.
460+ */
461+ static int s_ws_bootstrap_on_handshake_response_header_block_done (
462+ struct aws_http_stream * stream ,
463+ enum aws_http_header_block header_block ,
464+ void * user_data ) {
465+
466+ (void )header_block ;
467+
448468 struct aws_websocket_client_bootstrap * ws_bootstrap = user_data ;
449469 struct aws_http_connection * http_connection = s_system_vtable -> aws_http_stream_get_connection (stream );
450470 AWS_ASSERT (http_connection );
451471
452- if (error_code ) {
453- goto error ;
454- }
455-
456472 /* Get data from stream */
457473 s_system_vtable -> aws_http_stream_get_incoming_response_status (stream , & ws_bootstrap -> response_status );
458474
@@ -522,13 +538,20 @@ static void s_ws_bootstrap_on_handshake_complete(struct aws_http_stream *stream,
522538 /* Clear setup callback so that we know that it's been invoked. */
523539 ws_bootstrap -> websocket_setup_callback = NULL ;
524540
525- s_system_vtable -> aws_http_stream_release (stream );
526- return ;
541+ return AWS_OP_SUCCESS ;
527542
528543error :
529- if (!error_code ) {
530- error_code = aws_last_error ();
531- }
532- s_ws_bootstrap_cancel_setup_due_to_err (ws_bootstrap , http_connection , error_code );
544+ s_ws_bootstrap_cancel_setup_due_to_err (ws_bootstrap , http_connection , aws_last_error ());
545+ /* Returning error stops HTTP from processing any further data */
546+ return AWS_OP_ERR ;
547+ }
548+
549+ static void s_ws_bootstrap_on_stream_complete (struct aws_http_stream * stream , int error_code , void * user_data ) {
550+ /* Not checking error_code because a stream error ends the HTTP connection.
551+ * We'll deal with finishing setup and/or shutdown from the http-shutdown callback */
552+ (void )error_code ;
553+ (void )user_data ;
554+
555+ /* Done with stream, let it be cleaned up */
533556 s_system_vtable -> aws_http_stream_release (stream );
534557}
0 commit comments