@@ -166,7 +166,7 @@ enum stream_type {
166
166
167
167
enum stream_outgoing_state {
168
168
STREAM_OUTGOING_STATE_HEAD ,
169
- STREAM_OUTGOING_STATE_BODY , /* TODO: support 100-continue */
169
+ STREAM_OUTGOING_STATE_BODY ,
170
170
STREAM_OUTGOING_STATE_DONE ,
171
171
};
172
172
@@ -278,7 +278,7 @@ static int s_stream_scan_outgoing_headers(
278
278
size_t num_headers ,
279
279
size_t * out_header_lines_len ) {
280
280
281
- * out_header_lines_len = 0 ;
281
+ size_t total = 0 ;
282
282
283
283
for (size_t i = 0 ; i < num_headers ; ++ i ) {
284
284
struct aws_http_header header = header_array [i ];
@@ -288,20 +288,25 @@ static int s_stream_scan_outgoing_headers(
288
288
if (header .name .len > 0 ) {
289
289
name_enum = aws_http_str_to_header_name (header .name );
290
290
} else {
291
- AWS_LOGF_ERROR (AWS_LS_HTTP_STREAM , "static: No name set for header[%zu]." , i );
291
+ AWS_LOGF_ERROR (
292
+ AWS_LS_HTTP_CONNECTION ,
293
+ "id=%p: Failed to create stream, no name set for header[%zu]." ,
294
+ (void * )stream -> base .owning_connection ,
295
+ i );
292
296
return aws_raise_error (AWS_ERROR_INVALID_ARGUMENT );
293
297
}
294
298
295
299
switch (name_enum ) {
296
300
case AWS_HTTP_HEADER_CONTENT_LENGTH :
297
301
case AWS_HTTP_HEADER_TRANSFER_ENCODING :
298
- /* TODO: actually process the values in these headers*/
299
302
stream -> has_outgoing_body = true;
300
303
301
304
if (!stream -> base .stream_outgoing_body ) {
302
305
AWS_LOGF_ERROR (
303
- AWS_LS_HTTP_STREAM ,
304
- "static: '" PRInSTR "' header specified, but body-streaming callback is not set." ,
306
+ AWS_LS_HTTP_CONNECTION ,
307
+ "id=%p: Failed to create stream, '" PRInSTR
308
+ "' header specified but body-streaming callback is not set." ,
309
+ (void * )stream -> base .owning_connection ,
305
310
AWS_BYTE_CURSOR_PRI (header .name ));
306
311
307
312
return aws_raise_error (AWS_ERROR_INVALID_ARGUMENT );
@@ -312,11 +317,22 @@ static int s_stream_scan_outgoing_headers(
312
317
}
313
318
314
319
/* header-line: "{name}: {value}\r\n" */
315
- * out_header_lines_len += header .name .len + 2 + header .value .len + 2 ;
316
-
317
- /* TODO: check for overflows anywhere we do addition/subtraction? */
320
+ int err = 0 ;
321
+ err |= aws_add_size_checked (header .name .len , total , & total );
322
+ err |= aws_add_size_checked (header .value .len , total , & total );
323
+ err |= aws_add_size_checked (4 , total , & total ); /* ": " + "\r\n" */
324
+ if (err ) {
325
+ AWS_LOGF_ERROR (
326
+ AWS_LS_HTTP_CONNECTION ,
327
+ "id=%p: Failed to create stream, header size calculation produced error %d (%s)'" ,
328
+ (void * )stream -> base .owning_connection ,
329
+ aws_last_error (),
330
+ aws_error_name (aws_last_error ()));
331
+ return AWS_OP_ERR ;
332
+ }
318
333
}
319
334
335
+ * out_header_lines_len = total ;
320
336
return AWS_OP_SUCCESS ;
321
337
}
322
338
@@ -339,7 +355,10 @@ static void s_write_headers(struct aws_byte_buf *dst, const struct aws_http_head
339
355
340
356
struct aws_http_stream * s_new_client_request_stream (const struct aws_http_request_options * options ) {
341
357
if (options -> uri .len == 0 || options -> method .len == 0 ) {
342
- AWS_LOGF_ERROR (AWS_LS_HTTP_CONNECTION , "static: Invalid options, cannot create client request." );
358
+ AWS_LOGF_ERROR (
359
+ AWS_LS_HTTP_CONNECTION ,
360
+ "id=%p: Cannot create client request, options are invalid." ,
361
+ (void * )options -> client_connection );
343
362
aws_raise_error (AWS_ERROR_INVALID_ARGUMENT );
344
363
return NULL ;
345
364
}
@@ -368,24 +387,48 @@ struct aws_http_stream *s_new_client_request_stream(const struct aws_http_reques
368
387
369
388
/**
370
389
* Calculate total size needed for outgoing_head_buffer, then write to buffer.
371
- * The head will look like this:
372
- * request-line: "{method} {uri} {version}\r\n"
373
- * header-line: "{name}: {value}\r\n"
374
- * head-end: "\r\n"
375
390
*/
376
- size_t request_line_len = options -> method . len + 1 + options -> uri . len + 1 + version . len + 2 ;
391
+
377
392
size_t header_lines_len ;
378
393
int err = s_stream_scan_outgoing_headers (stream , options -> header_array , options -> num_headers , & header_lines_len );
379
394
if (err ) {
380
- goto error ;
395
+ /* errors already logged by scan_outgoing_headers() function */
396
+ goto error_scanning_headers ;
381
397
}
382
398
399
+ /* request-line: "{method} {uri} {version}\r\n" */
400
+ size_t request_line_len = 4 ; /* 2 spaces + "\r\n" */
401
+ err |= aws_add_size_checked (options -> method .len , request_line_len , & request_line_len );
402
+ err |= aws_add_size_checked (options -> uri .len , request_line_len , & request_line_len );
403
+ err |= aws_add_size_checked (version .len , request_line_len , & request_line_len );
404
+
405
+ /* head-end: "\r\n" */
383
406
size_t head_end_len = 2 ;
384
407
385
- size_t head_total_len = request_line_len + header_lines_len + head_end_len ;
408
+ size_t head_total_len = request_line_len ;
409
+ err |= aws_add_size_checked (header_lines_len , head_total_len , & head_total_len );
410
+ err |= aws_add_size_checked (head_end_len , head_total_len , & head_total_len );
411
+
412
+ if (err ) {
413
+ AWS_LOGF_ERROR (
414
+ AWS_LS_HTTP_CONNECTION ,
415
+ "id=%p: Failed to create request, size calculation had error %d (%s)." ,
416
+ (void * )options -> client_connection ,
417
+ aws_last_error (),
418
+ aws_error_name (aws_last_error ()));
419
+ goto error_calculating_size ;
420
+ }
421
+
386
422
err = aws_byte_buf_init (& stream -> outgoing_head_buf , stream -> base .alloc , head_total_len );
387
423
if (err ) {
388
- goto error ;
424
+ AWS_LOGF_ERROR (
425
+ AWS_LS_HTTP_CONNECTION ,
426
+ "id=%p: Failed to create request, buffer initialization had error %d (%s)." ,
427
+ (void * )options -> client_connection ,
428
+ aws_last_error (),
429
+ aws_error_name (aws_last_error ()));
430
+
431
+ goto error_initializing_buf ;
389
432
}
390
433
391
434
bool wrote_all = true;
@@ -430,18 +473,19 @@ struct aws_http_stream *s_new_client_request_stream(const struct aws_http_reques
430
473
431
474
if (is_shutting_down ) {
432
475
AWS_LOGF_ERROR (
433
- AWS_LS_HTTP_STREAM ,
434
- "static : Connection is closed, cannot create " PRInSTR " request." ,
435
- AWS_BYTE_CURSOR_PRI ( options -> method ) );
476
+ AWS_LS_HTTP_CONNECTION ,
477
+ "id=%p : Connection is closed, cannot create request." ,
478
+ ( void * ) options -> client_connection );
436
479
437
480
aws_raise_error (AWS_ERROR_HTTP_CONNECTION_CLOSED );
438
- goto error ;
481
+ goto error_connection_closed ;
439
482
}
440
483
441
484
AWS_LOGF_DEBUG (
442
485
AWS_LS_HTTP_STREAM ,
443
- "id=%p: Created client request: " PRInSTR " " PRInSTR " " PRInSTR ,
486
+ "id=%p: Created client request on connection=%p : " PRInSTR " " PRInSTR " " PRInSTR ,
444
487
(void * )& stream -> base ,
488
+ (void * )options -> client_connection ,
445
489
AWS_BYTE_CURSOR_PRI (options -> method ),
446
490
AWS_BYTE_CURSOR_PRI (options -> uri ),
447
491
AWS_BYTE_CURSOR_PRI (aws_http_version_to_str (connection -> base .http_version )));
@@ -453,8 +497,11 @@ struct aws_http_stream *s_new_client_request_stream(const struct aws_http_reques
453
497
454
498
return & stream -> base ;
455
499
456
- error :
500
+ error_connection_closed :
457
501
aws_byte_buf_clean_up (& stream -> outgoing_head_buf );
502
+ error_initializing_buf :
503
+ error_calculating_size :
504
+ error_scanning_headers :
458
505
aws_mem_release (stream -> base .alloc , stream );
459
506
return NULL ;
460
507
}
@@ -472,7 +519,14 @@ static void s_stream_destroy(struct aws_http_stream *stream_base) {
472
519
static void s_update_window_action (struct h1_connection * connection , size_t increment_size ) {
473
520
int err = aws_channel_slot_increment_read_window (connection -> base .channel_slot , increment_size );
474
521
if (err ) {
475
- /* TODO: log warning OR remove error code from aws_channel_slot_increment_read_window */
522
+ AWS_LOGF_ERROR (
523
+ AWS_LS_HTTP_CONNECTION ,
524
+ "id=%p: Failed to increment read window, error %d (%s). Closing connection." ,
525
+ (void * )& connection -> base ,
526
+ aws_last_error (),
527
+ aws_error_name (aws_last_error ()));
528
+
529
+ s_shutdown_connection (connection , aws_last_error ());
476
530
}
477
531
}
478
532
@@ -856,8 +910,8 @@ static void s_outgoing_stream_task(struct aws_channel_task *task, void *arg, enu
856
910
AWS_LS_HTTP_CONNECTION ,
857
911
"id=%p: Failed to send message up channel, error %d (%s). Closing connection." ,
858
912
(void * )& connection -> base ,
859
- err ,
860
- aws_error_name (err ));
913
+ aws_last_error () ,
914
+ aws_error_name (aws_last_error () ));
861
915
862
916
goto error ;
863
917
}
@@ -914,8 +968,6 @@ static int s_decoder_on_request(
914
968
AWS_BYTE_CURSOR_PRI (* method_str ),
915
969
AWS_BYTE_CURSOR_PRI (* uri ));
916
970
917
- /* TODO: Limit on lengths of incoming data https://httpwg.org/specs/rfc7230.html#attack.protocol.element.length */
918
-
919
971
/* Copy strings to internal buffer */
920
972
struct aws_byte_buf * storage_buf = & incoming_stream -> incoming_storage_buf ;
921
973
assert (storage_buf -> capacity == 0 );
@@ -976,8 +1028,6 @@ static int s_decoder_on_header(const struct aws_http_decoded_header *header, voi
976
1028
AWS_BYTE_CURSOR_PRI (header -> name_data ),
977
1029
AWS_BYTE_CURSOR_PRI (header -> value_data ));
978
1030
979
- /* TODO? how to support trailing headers? distinct cb? invoke same cb again? */
980
-
981
1031
if (incoming_stream -> base .on_incoming_headers ) {
982
1032
struct aws_http_header deliver = {
983
1033
.name = header -> name_data ,
@@ -1263,8 +1313,8 @@ static int s_handler_process_read_message(
1263
1313
AWS_LS_HTTP_CONNECTION ,
1264
1314
"id=%p: Message processing failed, error %d (%s). Closing connection." ,
1265
1315
(void * )& connection -> base ,
1266
- err ,
1267
- aws_error_name (err ));
1316
+ aws_last_error () ,
1317
+ aws_error_name (aws_last_error () ));
1268
1318
1269
1319
goto error ;
1270
1320
}
@@ -1282,8 +1332,8 @@ static int s_handler_process_read_message(
1282
1332
AWS_LS_HTTP_CONNECTION ,
1283
1333
"id=%p: Failed to increment read window, error %d (%s). Closing connection." ,
1284
1334
(void * )& connection -> base ,
1285
- err ,
1286
- aws_error_name (err ));
1335
+ aws_last_error () ,
1336
+ aws_error_name (aws_last_error () ));
1287
1337
1288
1338
goto error ;
1289
1339
}
0 commit comments