Skip to content

Commit 31a40b6

Browse files
committed
Optimization: thanks Dmitriy!
1 parent 6dc91eb commit 31a40b6

File tree

1 file changed

+38
-19
lines changed

1 file changed

+38
-19
lines changed

source/websocket_bootstrap.c

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)