diff --git a/httplib.h b/httplib.h index 793bccaf0..3077e55fc 100644 --- a/httplib.h +++ b/httplib.h @@ -156,6 +156,7 @@ using socket_t = int; #include #include +#include #include // #if OPENSSL_VERSION_NUMBER < 0x1010100fL @@ -511,7 +512,7 @@ class Server { int bind_internal(const char *host, int port, int socket_flags); bool listen_internal(); - bool routing(Request &req, Response &res, Stream &strm, bool last_connection); + bool routing(Request &req, Response &res, Stream &strm); bool handle_file_request(Request &req, Response &res, bool head = false); bool dispatch_request(Request &req, Response &res, Handlers &handlers); bool dispatch_request_for_content_reader(Request &req, Response &res, @@ -524,14 +525,14 @@ class Server { bool write_content_with_provider(Stream &strm, const Request &req, Response &res, const std::string &boundary, const std::string &content_type); - bool read_content(Stream &strm, bool last_connection, Request &req, - Response &res); - bool read_content_with_content_receiver( - Stream &strm, bool last_connection, Request &req, Response &res, - ContentReceiver receiver, MultipartContentHeader multipart_header, - ContentReceiver multipart_receiver); - bool read_content_core(Stream &strm, bool last_connection, Request &req, - Response &res, ContentReceiver receiver, + bool read_content(Stream &strm, Request &req, Response &res); + bool + read_content_with_content_receiver(Stream &strm, Request &req, Response &res, + ContentReceiver receiver, + MultipartContentHeader multipart_header, + ContentReceiver multipart_receiver); + bool read_content_core(Stream &strm, Request &req, Response &res, + ContentReceiver receiver, MultipartContentHeader mulitpart_header, ContentReceiver multipart_receiver); @@ -859,8 +860,8 @@ class SSLServer : public Server { class SSLClient : public Client { public: explicit SSLClient(const std::string &host, int port = 443, - const std::string &client_cert_path = std::string(), - const std::string &client_key_path = std::string()); + const std::string &client_cert_path = std::string(), + const std::string &client_key_path = std::string()); ~SSLClient() override; @@ -2779,8 +2780,7 @@ inline void Response::set_content(const char *s, size_t n, set_header("Content-Type", content_type); } -inline void Response::set_content(std::string s, - const char *content_type) { +inline void Response::set_content(std::string s, const char *content_type) { body = std::move(s); set_header("Content-Type", content_type); } @@ -3244,47 +3244,45 @@ Server::write_content_with_provider(Stream &strm, const Request &req, return true; } -inline bool Server::read_content(Stream &strm, bool last_connection, - Request &req, Response &res) { +inline bool Server::read_content(Stream &strm, Request &req, Response &res) { MultipartFormDataMap::iterator cur; - auto ret = read_content_core( - strm, last_connection, req, res, - // Regular - [&](const char *buf, size_t n) { - if (req.body.size() + n > req.body.max_size()) { return false; } - req.body.append(buf, n); - return true; - }, - // Multipart - [&](const MultipartFormData &file) { - cur = req.files.emplace(file.name, file); - return true; - }, - [&](const char *buf, size_t n) { - auto &content = cur->second.content; - if (content.size() + n > content.max_size()) { return false; } - content.append(buf, n); - return true; - }); - - const auto &content_type = req.get_header_value("Content-Type"); - if (!content_type.find("application/x-www-form-urlencoded")) { - detail::parse_query_text(req.body, req.params); + if (read_content_core( + strm, req, res, + // Regular + [&](const char *buf, size_t n) { + if (req.body.size() + n > req.body.max_size()) { return false; } + req.body.append(buf, n); + return true; + }, + // Multipart + [&](const MultipartFormData &file) { + cur = req.files.emplace(file.name, file); + return true; + }, + [&](const char *buf, size_t n) { + auto &content = cur->second.content; + if (content.size() + n > content.max_size()) { return false; } + content.append(buf, n); + return true; + })) { + const auto &content_type = req.get_header_value("Content-Type"); + if (!content_type.find("application/x-www-form-urlencoded")) { + detail::parse_query_text(req.body, req.params); + } + return true; } - - return ret; + return false; } inline bool Server::read_content_with_content_receiver( - Stream &strm, bool last_connection, Request &req, Response &res, - ContentReceiver receiver, MultipartContentHeader multipart_header, + Stream &strm, Request &req, Response &res, ContentReceiver receiver, + MultipartContentHeader multipart_header, ContentReceiver multipart_receiver) { - return read_content_core(strm, last_connection, req, res, receiver, - multipart_header, multipart_receiver); + return read_content_core(strm, req, res, receiver, multipart_header, + multipart_receiver); } -inline bool Server::read_content_core(Stream &strm, bool last_connection, - Request &req, Response &res, +inline bool Server::read_content_core(Stream &strm, Request &req, Response &res, ContentReceiver receiver, MultipartContentHeader mulitpart_header, ContentReceiver multipart_receiver) { @@ -3296,7 +3294,7 @@ inline bool Server::read_content_core(Stream &strm, bool last_connection, std::string boundary; if (!detail::parse_multipart_boundary(content_type, boundary)) { res.status = 400; - return write_response(strm, last_connection, req, res); + return false; } multipart_form_data_parser.set_boundary(std::move(boundary)); @@ -3310,13 +3308,13 @@ inline bool Server::read_content_core(Stream &strm, bool last_connection, if (!detail::read_content(strm, req, payload_max_length_, res.status, Progress(), out)) { - return write_response(strm, last_connection, req, res); + return false; } if (req.is_multipart_form_data()) { if (!multipart_form_data_parser.is_valid()) { res.status = 400; - return write_response(strm, last_connection, req, res); + return false; } } @@ -3446,8 +3444,7 @@ inline bool Server::listen_internal() { return ret; } -inline bool Server::routing(Request &req, Response &res, Stream &strm, - bool last_connection) { +inline bool Server::routing(Request &req, Response &res, Stream &strm) { // File handler bool is_head_request = req.method == "HEAD"; if ((req.method == "GET" || is_head_request) && @@ -3460,12 +3457,12 @@ inline bool Server::routing(Request &req, Response &res, Stream &strm, { ContentReader reader( [&](ContentReceiver receiver) { - return read_content_with_content_receiver( - strm, last_connection, req, res, receiver, nullptr, nullptr); + return read_content_with_content_receiver(strm, req, res, receiver, + nullptr, nullptr); }, [&](MultipartContentHeader header, ContentReceiver receiver) { - return read_content_with_content_receiver( - strm, last_connection, req, res, nullptr, header, receiver); + return read_content_with_content_receiver(strm, req, res, nullptr, + header, receiver); }); if (req.method == "POST") { @@ -3487,7 +3484,7 @@ inline bool Server::routing(Request &req, Response &res, Stream &strm, } // Read content into `req.body` - if (!read_content(strm, last_connection, req, res)) { return false; } + if (!read_content(strm, req, res)) { return false; } } // Regular handler @@ -3614,7 +3611,7 @@ Server::process_request(Stream &strm, bool last_connection, } // Rounting - if (routing(req, res, strm, last_connection)) { + if (routing(req, res, strm)) { if (res.status == -1) { res.status = req.ranges.empty() ? 200 : 206; } } else { if (res.status == -1) { res.status = 404; }