@@ -448,6 +448,8 @@ class Server {
448448 using Handler = std::function<void (const Request &, Response &)>;
449449 using HandlerWithContentReader = std::function<void (
450450 const Request &, Response &, const ContentReader &content_reader)>;
451+ using Expect100ContinueHandler =
452+ std::function<int (const Request &, Response &)>;
451453
452454 Server ();
453455
@@ -476,6 +478,8 @@ class Server {
476478 void set_error_handler (Handler handler);
477479 void set_logger (Logger logger);
478480
481+ void set_expect_100_continue_handler (Expect100ContinueHandler handler);
482+
479483 void set_keep_alive_max_count (size_t count);
480484 void set_read_timeout (time_t sec, time_t usec);
481485 void set_payload_max_length (size_t length);
@@ -553,6 +557,7 @@ class Server {
553557 Handlers options_handlers_;
554558 Handler error_handler_;
555559 Logger logger_;
560+ Expect100ContinueHandler expect_100_continue_handler_;
556561};
557562
558563class Client {
@@ -1594,6 +1599,7 @@ find_content_type(const std::string &path,
15941599
15951600inline const char *status_message (int status) {
15961601 switch (status) {
1602+ case 100 : return " Continue" ;
15971603 case 200 : return " OK" ;
15981604 case 202 : return " Accepted" ;
15991605 case 204 : return " No Content" ;
@@ -1610,6 +1616,7 @@ inline const char *status_message(int status) {
16101616 case 414 : return " Request-URI Too Long" ;
16111617 case 415 : return " Unsupported Media Type" ;
16121618 case 416 : return " Range Not Satisfiable" ;
1619+ case 417 : return " Expectation Failed" ;
16131620 case 503 : return " Service Unavailable" ;
16141621
16151622 default :
@@ -2931,6 +2938,11 @@ inline void Server::set_error_handler(Handler handler) {
29312938
29322939inline void Server::set_logger (Logger logger) { logger_ = std::move (logger); }
29332940
2941+ inline void
2942+ Server::set_expect_100_continue_handler (Expect100ContinueHandler handler) {
2943+ expect_100_continue_handler_ = std::move (handler);
2944+ }
2945+
29342946inline void Server::set_keep_alive_max_count (size_t count) {
29352947 keep_alive_max_count_ = count;
29362948}
@@ -3012,11 +3024,12 @@ inline bool Server::write_response(Stream &strm, bool last_connection,
30123024 res.set_header (" Connection" , " Keep-Alive" );
30133025 }
30143026
3015- if (!res.has_header (" Content-Type" )) {
3027+ if (!res.has_header (" Content-Type" ) &&
3028+ (!res.body .empty () || res.content_length > 0 )) {
30163029 res.set_header (" Content-Type" , " text/plain" );
30173030 }
30183031
3019- if (!res.has_header (" Accept-Ranges" )) {
3032+ if (!res.has_header (" Accept-Ranges" ) && req. method == " HEAD " ) {
30203033 res.set_header (" Accept-Ranges" , " bytes" );
30213034 }
30223035
@@ -3491,6 +3504,21 @@ Server::process_request(Stream &strm, bool last_connection,
34913504
34923505 if (setup_request) { setup_request (req); }
34933506
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+
34943522 // Rounting
34953523 if (routing (req, res, strm, last_connection)) {
34963524 if (res.status == -1 ) { res.status = req.ranges .empty () ? 200 : 206 ; }
0 commit comments