@@ -360,6 +360,85 @@ static bool lwan_setup_tls(const struct lwan *l, struct lwan_connection *conn)
360
360
}
361
361
#endif
362
362
363
+ __attribute__((cold ))
364
+ static bool send_buffer_without_coro (int fd , const char * buf , size_t buf_len , int flags )
365
+ {
366
+ size_t total_sent = 0 ;
367
+
368
+ for (int try = 0 ; try < 10 ; try ++ ) {
369
+ size_t to_send = buf_len - total_sent ;
370
+ if (!to_send )
371
+ return true;
372
+
373
+ ssize_t sent = send (fd , buf + total_sent , to_send , flags );
374
+ if (sent <= 0 ) {
375
+ if (errno == EINTR )
376
+ continue ;
377
+ if (errno == EAGAIN )
378
+ continue ;
379
+ break ;
380
+ }
381
+
382
+ total_sent += (size_t )sent ;
383
+ }
384
+
385
+ return false;
386
+ }
387
+
388
+ __attribute__((cold ))
389
+ static bool send_string_without_coro (int fd , const char * str , int flags )
390
+ {
391
+ return send_buffer_without_coro (fd , str , strlen (str ), flags );
392
+ }
393
+
394
+ __attribute__((cold )) static void
395
+ send_last_response_without_coro (const struct lwan * l ,
396
+ const struct lwan_connection * conn ,
397
+ enum lwan_http_status status )
398
+ {
399
+ int fd = lwan_connection_get_fd (l , conn );
400
+
401
+ if (conn -> flags & CONN_TLS ) {
402
+ /* There's nothing that can be done here if a client is expecting a
403
+ * TLS connection: the TLS handshake requires a coroutine as it
404
+ * might yield. (In addition, the TLS handshake might allocate
405
+ * memory, and if you couldn't create a coroutine at this point,
406
+ * it's unlikely you'd be able to allocate memory for the TLS
407
+ * context anyway.) */
408
+ goto shutdown_and_close ;
409
+ }
410
+
411
+ if (!send_string_without_coro (fd , "HTTP/1.0 " , MSG_MORE ))
412
+ goto shutdown_and_close ;
413
+
414
+ if (!send_string_without_coro (
415
+ fd , lwan_http_status_as_string_with_code (status ), MSG_MORE ))
416
+ goto shutdown_and_close ;
417
+
418
+ if (!send_string_without_coro (fd , "\r\nConnection: close" , MSG_MORE ))
419
+ goto shutdown_and_close ;
420
+
421
+ if (!send_string_without_coro (fd , "\r\nContent-Type: text/html" , MSG_MORE ))
422
+ goto shutdown_and_close ;
423
+
424
+ if (send_buffer_without_coro (fd , l -> headers .value , l -> headers .len ,
425
+ MSG_MORE )) {
426
+ struct lwan_strbuf buffer ;
427
+
428
+ lwan_strbuf_init (& buffer );
429
+ lwan_fill_default_response (& buffer , status );
430
+
431
+ send_buffer_without_coro (fd , lwan_strbuf_get_buffer (& buffer ),
432
+ lwan_strbuf_get_length (& buffer ), 0 );
433
+
434
+ lwan_strbuf_free (& buffer );
435
+ }
436
+
437
+ shutdown_and_close :
438
+ shutdown (fd , SHUT_RDWR );
439
+ close (fd );
440
+ }
441
+
363
442
__attribute__((noreturn )) static int process_request_coro (struct coro * coro ,
364
443
void * data )
365
444
{
@@ -397,12 +476,28 @@ __attribute__((noreturn)) static int process_request_coro(struct coro *coro,
397
476
.value = coro_malloc (conn -> coro , request_buffer_size ),
398
477
.len = request_buffer_size ,
399
478
};
479
+
480
+ if (UNLIKELY (!buffer .value )) {
481
+ /* If CONN_TLS is set at this point, we can send responses just
482
+ * fine and they'll be encrypted by the kernel. However,
483
+ * send_last_response_without_coro() can't send the response if
484
+ * this bit is set as it has been designed to be used in cases
485
+ * where coroutines were not created yet. */
486
+ conn -> flags &= ~CONN_TLS ;
487
+
488
+ send_last_response_without_coro (lwan , conn , HTTP_UNAVAILABLE );
489
+
490
+ coro_yield (conn -> coro , CONN_CORO_ABORT );
491
+ __builtin_unreachable ();
492
+ }
493
+
400
494
init_gen = 2 ;
401
495
} else {
402
496
buffer = (struct lwan_value ){
403
497
.value = alloca (request_buffer_size ),
404
498
.len = request_buffer_size ,
405
499
};
500
+
406
501
init_gen = 1 ;
407
502
}
408
503
@@ -638,85 +733,6 @@ static void update_date_cache(struct lwan_thread *thread)
638
733
thread -> date .expires );
639
734
}
640
735
641
- __attribute__((cold ))
642
- static bool send_buffer_without_coro (int fd , const char * buf , size_t buf_len , int flags )
643
- {
644
- size_t total_sent = 0 ;
645
-
646
- for (int try = 0 ; try < 10 ; try ++ ) {
647
- size_t to_send = buf_len - total_sent ;
648
- if (!to_send )
649
- return true;
650
-
651
- ssize_t sent = send (fd , buf + total_sent , to_send , flags );
652
- if (sent <= 0 ) {
653
- if (errno == EINTR )
654
- continue ;
655
- if (errno == EAGAIN )
656
- continue ;
657
- break ;
658
- }
659
-
660
- total_sent += (size_t )sent ;
661
- }
662
-
663
- return false;
664
- }
665
-
666
- __attribute__((cold ))
667
- static bool send_string_without_coro (int fd , const char * str , int flags )
668
- {
669
- return send_buffer_without_coro (fd , str , strlen (str ), flags );
670
- }
671
-
672
- __attribute__((cold )) static void
673
- send_last_response_without_coro (const struct lwan * l ,
674
- const struct lwan_connection * conn ,
675
- enum lwan_http_status status )
676
- {
677
- int fd = lwan_connection_get_fd (l , conn );
678
-
679
- if (conn -> flags & CONN_TLS ) {
680
- /* There's nothing that can be done here if a client is expecting a
681
- * TLS connection: the TLS handshake requires a coroutine as it
682
- * might yield. (In addition, the TLS handshake might allocate
683
- * memory, and if you couldn't create a coroutine at this point,
684
- * it's unlikely you'd be able to allocate memory for the TLS
685
- * context anyway.) */
686
- goto shutdown_and_close ;
687
- }
688
-
689
- if (!send_string_without_coro (fd , "HTTP/1.0 " , MSG_MORE ))
690
- goto shutdown_and_close ;
691
-
692
- if (!send_string_without_coro (
693
- fd , lwan_http_status_as_string_with_code (status ), MSG_MORE ))
694
- goto shutdown_and_close ;
695
-
696
- if (!send_string_without_coro (fd , "\r\nConnection: close" , MSG_MORE ))
697
- goto shutdown_and_close ;
698
-
699
- if (!send_string_without_coro (fd , "\r\nContent-Type: text/html" , MSG_MORE ))
700
- goto shutdown_and_close ;
701
-
702
- if (send_buffer_without_coro (fd , l -> headers .value , l -> headers .len ,
703
- MSG_MORE )) {
704
- struct lwan_strbuf buffer ;
705
-
706
- lwan_strbuf_init (& buffer );
707
- lwan_fill_default_response (& buffer , status );
708
-
709
- send_buffer_without_coro (fd , lwan_strbuf_get_buffer (& buffer ),
710
- lwan_strbuf_get_length (& buffer ), 0 );
711
-
712
- lwan_strbuf_free (& buffer );
713
- }
714
-
715
- shutdown_and_close :
716
- shutdown (fd , SHUT_RDWR );
717
- close (fd );
718
- }
719
-
720
736
static ALWAYS_INLINE bool spawn_coro (struct lwan_connection * conn ,
721
737
struct coro_switcher * switcher ,
722
738
struct timeout_queue * tq )
0 commit comments