@@ -166,7 +166,7 @@ enum stream_type {
166166
167167enum stream_outgoing_state {
168168 STREAM_OUTGOING_STATE_HEAD ,
169- STREAM_OUTGOING_STATE_BODY , /* TODO: support 100-continue */
169+ STREAM_OUTGOING_STATE_BODY ,
170170 STREAM_OUTGOING_STATE_DONE ,
171171};
172172
@@ -278,7 +278,7 @@ static int s_stream_scan_outgoing_headers(
278278 size_t num_headers ,
279279 size_t * out_header_lines_len ) {
280280
281- * out_header_lines_len = 0 ;
281+ size_t total = 0 ;
282282
283283 for (size_t i = 0 ; i < num_headers ; ++ i ) {
284284 struct aws_http_header header = header_array [i ];
@@ -288,20 +288,25 @@ static int s_stream_scan_outgoing_headers(
288288 if (header .name .len > 0 ) {
289289 name_enum = aws_http_str_to_header_name (header .name );
290290 } 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 );
292296 return aws_raise_error (AWS_ERROR_INVALID_ARGUMENT );
293297 }
294298
295299 switch (name_enum ) {
296300 case AWS_HTTP_HEADER_CONTENT_LENGTH :
297301 case AWS_HTTP_HEADER_TRANSFER_ENCODING :
298- /* TODO: actually process the values in these headers*/
299302 stream -> has_outgoing_body = true;
300303
301304 if (!stream -> base .stream_outgoing_body ) {
302305 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 ,
305310 AWS_BYTE_CURSOR_PRI (header .name ));
306311
307312 return aws_raise_error (AWS_ERROR_INVALID_ARGUMENT );
@@ -312,11 +317,22 @@ static int s_stream_scan_outgoing_headers(
312317 }
313318
314319 /* 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+ }
318333 }
319334
335+ * out_header_lines_len = total ;
320336 return AWS_OP_SUCCESS ;
321337}
322338
@@ -339,7 +355,10 @@ static void s_write_headers(struct aws_byte_buf *dst, const struct aws_http_head
339355
340356struct aws_http_stream * s_new_client_request_stream (const struct aws_http_request_options * options ) {
341357 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 );
343362 aws_raise_error (AWS_ERROR_INVALID_ARGUMENT );
344363 return NULL ;
345364 }
@@ -368,24 +387,48 @@ struct aws_http_stream *s_new_client_request_stream(const struct aws_http_reques
368387
369388 /**
370389 * 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"
375390 */
376- size_t request_line_len = options -> method . len + 1 + options -> uri . len + 1 + version . len + 2 ;
391+
377392 size_t header_lines_len ;
378393 int err = s_stream_scan_outgoing_headers (stream , options -> header_array , options -> num_headers , & header_lines_len );
379394 if (err ) {
380- goto error ;
395+ /* errors already logged by scan_outgoing_headers() function */
396+ goto error_scanning_headers ;
381397 }
382398
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" */
383406 size_t head_end_len = 2 ;
384407
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+
386422 err = aws_byte_buf_init (& stream -> outgoing_head_buf , stream -> base .alloc , head_total_len );
387423 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 ;
389432 }
390433
391434 bool wrote_all = true;
@@ -430,18 +473,19 @@ struct aws_http_stream *s_new_client_request_stream(const struct aws_http_reques
430473
431474 if (is_shutting_down ) {
432475 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 );
436479
437480 aws_raise_error (AWS_ERROR_HTTP_CONNECTION_CLOSED );
438- goto error ;
481+ goto error_connection_closed ;
439482 }
440483
441484 AWS_LOGF_DEBUG (
442485 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 ,
444487 (void * )& stream -> base ,
488+ (void * )options -> client_connection ,
445489 AWS_BYTE_CURSOR_PRI (options -> method ),
446490 AWS_BYTE_CURSOR_PRI (options -> uri ),
447491 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
453497
454498 return & stream -> base ;
455499
456- error :
500+ error_connection_closed :
457501 aws_byte_buf_clean_up (& stream -> outgoing_head_buf );
502+ error_initializing_buf :
503+ error_calculating_size :
504+ error_scanning_headers :
458505 aws_mem_release (stream -> base .alloc , stream );
459506 return NULL ;
460507}
@@ -472,7 +519,14 @@ static void s_stream_destroy(struct aws_http_stream *stream_base) {
472519static void s_update_window_action (struct h1_connection * connection , size_t increment_size ) {
473520 int err = aws_channel_slot_increment_read_window (connection -> base .channel_slot , increment_size );
474521 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 ());
476530 }
477531}
478532
@@ -856,8 +910,8 @@ static void s_outgoing_stream_task(struct aws_channel_task *task, void *arg, enu
856910 AWS_LS_HTTP_CONNECTION ,
857911 "id=%p: Failed to send message up channel, error %d (%s). Closing connection." ,
858912 (void * )& connection -> base ,
859- err ,
860- aws_error_name (err ));
913+ aws_last_error () ,
914+ aws_error_name (aws_last_error () ));
861915
862916 goto error ;
863917 }
@@ -914,8 +968,6 @@ static int s_decoder_on_request(
914968 AWS_BYTE_CURSOR_PRI (* method_str ),
915969 AWS_BYTE_CURSOR_PRI (* uri ));
916970
917- /* TODO: Limit on lengths of incoming data https://httpwg.org/specs/rfc7230.html#attack.protocol.element.length */
918-
919971 /* Copy strings to internal buffer */
920972 struct aws_byte_buf * storage_buf = & incoming_stream -> incoming_storage_buf ;
921973 assert (storage_buf -> capacity == 0 );
@@ -976,8 +1028,6 @@ static int s_decoder_on_header(const struct aws_http_decoded_header *header, voi
9761028 AWS_BYTE_CURSOR_PRI (header -> name_data ),
9771029 AWS_BYTE_CURSOR_PRI (header -> value_data ));
9781030
979- /* TODO? how to support trailing headers? distinct cb? invoke same cb again? */
980-
9811031 if (incoming_stream -> base .on_incoming_headers ) {
9821032 struct aws_http_header deliver = {
9831033 .name = header -> name_data ,
@@ -1263,8 +1313,8 @@ static int s_handler_process_read_message(
12631313 AWS_LS_HTTP_CONNECTION ,
12641314 "id=%p: Message processing failed, error %d (%s). Closing connection." ,
12651315 (void * )& connection -> base ,
1266- err ,
1267- aws_error_name (err ));
1316+ aws_last_error () ,
1317+ aws_error_name (aws_last_error () ));
12681318
12691319 goto error ;
12701320 }
@@ -1282,8 +1332,8 @@ static int s_handler_process_read_message(
12821332 AWS_LS_HTTP_CONNECTION ,
12831333 "id=%p: Failed to increment read window, error %d (%s). Closing connection." ,
12841334 (void * )& connection -> base ,
1285- err ,
1286- aws_error_name (err ));
1335+ aws_last_error () ,
1336+ aws_error_name (aws_last_error () ));
12871337
12881338 goto error ;
12891339 }
0 commit comments