@@ -448,6 +448,8 @@ class Server {
448
448
using Handler = std::function<void (const Request &, Response &)>;
449
449
using HandlerWithContentReader = std::function<void (
450
450
const Request &, Response &, const ContentReader &content_reader)>;
451
+ using Expect100ContinueHandler =
452
+ std::function<int (const Request &, Response &)>;
451
453
452
454
Server ();
453
455
@@ -476,6 +478,8 @@ class Server {
476
478
void set_error_handler (Handler handler);
477
479
void set_logger (Logger logger);
478
480
481
+ void set_expect_100_continue_handler (Expect100ContinueHandler handler);
482
+
479
483
void set_keep_alive_max_count (size_t count);
480
484
void set_read_timeout (time_t sec, time_t usec);
481
485
void set_payload_max_length (size_t length);
@@ -553,6 +557,7 @@ class Server {
553
557
Handlers options_handlers_;
554
558
Handler error_handler_;
555
559
Logger logger_;
560
+ Expect100ContinueHandler expect_100_continue_handler_;
556
561
};
557
562
558
563
class Client {
@@ -1594,6 +1599,7 @@ find_content_type(const std::string &path,
1594
1599
1595
1600
inline const char *status_message (int status) {
1596
1601
switch (status) {
1602
+ case 100 : return " Continue" ;
1597
1603
case 200 : return " OK" ;
1598
1604
case 202 : return " Accepted" ;
1599
1605
case 204 : return " No Content" ;
@@ -1610,6 +1616,7 @@ inline const char *status_message(int status) {
1610
1616
case 414 : return " Request-URI Too Long" ;
1611
1617
case 415 : return " Unsupported Media Type" ;
1612
1618
case 416 : return " Range Not Satisfiable" ;
1619
+ case 417 : return " Expectation Failed" ;
1613
1620
case 503 : return " Service Unavailable" ;
1614
1621
1615
1622
default :
@@ -2931,6 +2938,11 @@ inline void Server::set_error_handler(Handler handler) {
2931
2938
2932
2939
inline void Server::set_logger (Logger logger) { logger_ = std::move (logger); }
2933
2940
2941
+ inline void
2942
+ Server::set_expect_100_continue_handler (Expect100ContinueHandler handler) {
2943
+ expect_100_continue_handler_ = std::move (handler);
2944
+ }
2945
+
2934
2946
inline void Server::set_keep_alive_max_count (size_t count) {
2935
2947
keep_alive_max_count_ = count;
2936
2948
}
@@ -3012,11 +3024,12 @@ inline bool Server::write_response(Stream &strm, bool last_connection,
3012
3024
res.set_header (" Connection" , " Keep-Alive" );
3013
3025
}
3014
3026
3015
- if (!res.has_header (" Content-Type" )) {
3027
+ if (!res.has_header (" Content-Type" ) &&
3028
+ (!res.body .empty () || res.content_length > 0 )) {
3016
3029
res.set_header (" Content-Type" , " text/plain" );
3017
3030
}
3018
3031
3019
- if (!res.has_header (" Accept-Ranges" )) {
3032
+ if (!res.has_header (" Accept-Ranges" ) && req. method == " HEAD " ) {
3020
3033
res.set_header (" Accept-Ranges" , " bytes" );
3021
3034
}
3022
3035
@@ -3491,6 +3504,21 @@ Server::process_request(Stream &strm, bool last_connection,
3491
3504
3492
3505
if (setup_request) { setup_request (req); }
3493
3506
3507
+ if (req.get_header_value (" Expect" ) == " 100-continue" ) {
3508
+ auto status = 100 ;
3509
+ if (expect_100_continue_handler_) {
3510
+ status = expect_100_continue_handler_ (req, res);
3511
+ }
3512
+ switch (status) {
3513
+ case 100 :
3514
+ case 417 :
3515
+ strm.write_format (" HTTP/1.1 %d %s\r\n\r\n " , status,
3516
+ detail::status_message (status));
3517
+ break ;
3518
+ default : return write_response (strm, last_connection, req, res);
3519
+ }
3520
+ }
3521
+
3494
3522
// Rounting
3495
3523
if (routing (req, res, strm, last_connection)) {
3496
3524
if (res.status == -1 ) { res.status = req.ranges .empty () ? 200 : 206 ; }
0 commit comments