@@ -145,8 +145,7 @@ int aws_websocket_client_connect(const struct aws_websocket_client_connection_op
145145
146146 const struct aws_http_headers * request_headers = aws_http_message_get_headers (options -> handshake_request );
147147 struct aws_byte_cursor sec_websocket_key ;
148- if (aws_http_headers_get_single (
149- request_headers , aws_byte_cursor_from_c_str ("Sec-WebSocket-Key" ), & sec_websocket_key )) {
148+ if (aws_http_headers_get (request_headers , aws_byte_cursor_from_c_str ("Sec-WebSocket-Key" ), & sec_websocket_key )) {
150149 AWS_LOGF_ERROR (
151150 AWS_LS_HTTP_WEBSOCKET_SETUP ,
152151 "id=static: Websocket handshake request is missing required 'Sec-WebSocket-Key' header" );
@@ -262,27 +261,43 @@ static int s_ws_bootstrap_calculate_sec_websocket_accept(
262261
263262 AWS_ASSERT (out_buf && !out_buf -> allocator && out_buf -> len == 0 ); /* expect buf to be uninitialized */
264263
265- /* ignore leading and trailing whitespace */
266- sec_websocket_key = aws_strutil_trim_http_whitespace (sec_websocket_key );
264+ /* note: leading and trailing whitespace was already trimmed by aws_http_headers */
267265
268- /* concatenation of key with magic string (store temporarily in out_buf) */
269- struct aws_byte_cursor magic_string = aws_byte_cursor_from_c_str ( "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" );
266+ /* optimization: skip concatenating Sec-WebSocket-Key and the magic string.
267+ * just run the SHA1 over the first string, and then the 2nd. */
270268
271- aws_byte_buf_init (out_buf , alloc , sec_websocket_key .len + magic_string .len );
272- aws_byte_buf_append_dynamic (out_buf , & sec_websocket_key );
273- aws_byte_buf_append_dynamic (out_buf , & magic_string );
274- struct aws_byte_cursor key_and_magic_string = aws_byte_cursor_from_buf (out_buf );
269+ bool success = false;
270+ struct aws_byte_cursor magic_string = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL ("258EAFA5-E914-47DA-95CA-C5AB0DC85B11" );
275271
276272 /* SHA-1 */
273+ struct aws_hash * sha1 = aws_sha1_new (alloc );
274+ if (!sha1 ) {
275+ AWS_LOGF_ERROR (
276+ AWS_LS_HTTP_WEBSOCKET_SETUP ,
277+ "id=static: Failed to initiate SHA1, error %d (%s)" ,
278+ aws_last_error (),
279+ aws_error_name (aws_last_error ()));
280+ goto cleanup ;
281+ }
282+
283+ if (aws_hash_update (sha1 , & sec_websocket_key ) || aws_hash_update (sha1 , & magic_string )) {
284+ AWS_LOGF_ERROR (
285+ AWS_LS_HTTP_WEBSOCKET_SETUP ,
286+ "id=static: Failed to update SHA1, error %d (%s)" ,
287+ aws_last_error (),
288+ aws_error_name (aws_last_error ()));
289+ goto cleanup ;
290+ }
291+
277292 uint8_t sha1_storage [AWS_SHA1_LEN ];
278293 struct aws_byte_buf sha1_buf = aws_byte_buf_from_empty_array (sha1_storage , sizeof (sha1_storage ));
279- if (aws_sha1_compute ( alloc , & key_and_magic_string , & sha1_buf , 0 )) {
294+ if (aws_hash_finalize ( sha1 , & sha1_buf , 0 )) {
280295 AWS_LOGF_ERROR (
281296 AWS_LS_HTTP_WEBSOCKET_SETUP ,
282- "id=static: Failed to compute SHA1, error %d (%s)" ,
297+ "id=static: Failed to finalize SHA1, error %d (%s)" ,
283298 aws_last_error (),
284299 aws_error_name (aws_last_error ()));
285- return AWS_OP_ERR ;
300+ goto cleanup ;
286301 }
287302
288303 /* base64-encoded SHA-1 (clear out_buf, and write to it again) */
@@ -293,10 +308,9 @@ static int s_ws_bootstrap_calculate_sec_websocket_accept(
293308 "id=static: Failed to determine Base64-encoded length, error %d (%s)" ,
294309 aws_last_error (),
295310 aws_error_name (aws_last_error ()));
296- return AWS_OP_ERR ;
311+ goto cleanup ;
297312 }
298- aws_byte_buf_reset (out_buf , false /*zero_contents*/ );
299- aws_byte_buf_reserve (out_buf , base64_encode_sha1_len );
313+ aws_byte_buf_init (out_buf , alloc , base64_encode_sha1_len );
300314
301315 struct aws_byte_cursor sha1_cursor = aws_byte_cursor_from_buf (& sha1_buf );
302316 if (aws_base64_encode (& sha1_cursor , out_buf )) {
@@ -305,10 +319,15 @@ static int s_ws_bootstrap_calculate_sec_websocket_accept(
305319 "id=static: Failed to Base64-encode, error %d (%s)" ,
306320 aws_last_error (),
307321 aws_error_name (aws_last_error ()));
308- return AWS_OP_ERR ;
322+ goto cleanup ;
309323 }
310324
311- return AWS_OP_SUCCESS ;
325+ success = true;
326+ cleanup :
327+ if (sha1 ) {
328+ aws_hash_destroy (sha1 );
329+ }
330+ return success ? AWS_OP_SUCCESS : AWS_OP_ERR ;
312331}
313332
314333/* Called if something goes wrong after an HTTP connection is established.
@@ -541,7 +560,7 @@ static int s_ws_bootstrap_validate_header(
541560 bool case_sensitive ) {
542561
543562 struct aws_byte_cursor actual_value ;
544- if (aws_http_headers_get_single (ws_bootstrap -> response_headers , aws_byte_cursor_from_c_str (name ), & actual_value )) {
563+ if (aws_http_headers_get (ws_bootstrap -> response_headers , aws_byte_cursor_from_c_str (name ), & actual_value )) {
545564 AWS_LOGF_ERROR (
546565 AWS_LS_HTTP_WEBSOCKET_SETUP , "id=%p: Response lacks required '%s' header" , (void * )ws_bootstrap , name );
547566 return aws_raise_error (AWS_ERROR_HTTP_WEBSOCKET_UPGRADE_FAILURE );
0 commit comments