diff --git a/third_party/cpp-httplib/README.crashpad b/third_party/cpp-httplib/README.crashpad index 275564ef..f89ae325 100644 --- a/third_party/cpp-httplib/README.crashpad +++ b/third_party/cpp-httplib/README.crashpad @@ -1,7 +1,8 @@ Name: cpp-httplib Short Name: cpp-httplib URL: https://github.com/yhirose/cpp-httplib -Revision: 6a848b1a16437fe216cb26a14ee9fcb5c5785464 +Version: 0.16.2 +Revision: c5c54b31e2bf8bd37ceba2715de756d1132e3685 License: MIT License File: cpp-httplib/LICENSE Security Critical: no (test only) diff --git a/third_party/cpp-httplib/cpp-httplib/httplib.h b/third_party/cpp-httplib/cpp-httplib/httplib.h index 93d8a28d..4ae7377b 100644 --- a/third_party/cpp-httplib/cpp-httplib/httplib.h +++ b/third_party/cpp-httplib/cpp-httplib/httplib.h @@ -8,7 +8,7 @@ #ifndef CPPHTTPLIB_HTTPLIB_H #define CPPHTTPLIB_HTTPLIB_H -#define CPPHTTPLIB_VERSION "0.16.0" +#define CPPHTTPLIB_VERSION "0.16.2" /* * Configuration @@ -117,7 +117,7 @@ #define CPPHTTPLIB_LISTEN_BACKLOG 5 #endif -#define CPPHTTPLIB_NO_EXCEPTIONS +#define CPPHTTPLIB_NO_EXCEPTIONS 1 /* * Headers @@ -272,6 +272,9 @@ using socket_t = int; #include #if defined(OPENSSL_IS_BORINGSSL) +#if OPENSSL_VERSION_NUMBER < 0x1010107f +#error Please use OpenSSL or a current version of BoringSSL +#endif #define SSL_get1_peer_certificate SSL_get_peer_certificate #elif OPENSSL_VERSION_NUMBER < 0x30000000L #error Sorry, OpenSSL versions prior to 3.0.0 are not supported @@ -732,7 +735,7 @@ private: } #if defined(CPPHTTPLIB_OPENSSL_SUPPORT) && !defined(OPENSSL_IS_BORINGSSL) - OPENSSL_thread_stop (); + OPENSSL_thread_stop(); #endif } @@ -1828,9 +1831,9 @@ public: bool is_valid() const override; SSL_CTX *ssl_context() const; - - void update_certs (X509 *cert, EVP_PKEY *private_key, - X509_STORE *client_ca_cert_store = nullptr); + + void update_certs(X509 *cert, EVP_PKEY *private_key, + X509_STORE *client_ca_cert_store = nullptr); private: bool process_and_close_socket(socket_t sock) override; @@ -2828,7 +2831,9 @@ inline bool mmap::open(const char *path) { wpath += path[i]; } -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8) +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | \ + WINAPI_PARTITION_GAMES) && \ + (_WIN32_WINNT >= _WIN32_WINNT_WIN8) hFile_ = ::CreateFile2(wpath.c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, NULL); #else @@ -2838,7 +2843,8 @@ inline bool mmap::open(const char *path) { if (hFile_ == INVALID_HANDLE_VALUE) { return false; } -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | \ + WINAPI_PARTITION_GAMES) LARGE_INTEGER size{}; if (!::GetFileSizeEx(hFile_, &size)) { return false; } size_ = static_cast(size.QuadPart); @@ -2850,13 +2856,13 @@ inline bool mmap::open(const char *path) { size_ = (static_cast(sizeHigh) << (sizeof(DWORD) * 8)) | sizeLow; #endif -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8) +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) && \ + (_WIN32_WINNT >= _WIN32_WINNT_WIN8) hMapping_ = ::CreateFileMappingFromApp(hFile_, NULL, PAGE_READONLY, size_, NULL); #else - hMapping_ = - ::CreateFileMappingW(hFile_, NULL, PAGE_READONLY, size.HighPart, - size.LowPart, NULL); + hMapping_ = ::CreateFileMappingW(hFile_, NULL, PAGE_READONLY, size.HighPart, + size.LowPart, NULL); #endif if (hMapping_ == NULL) { @@ -2864,7 +2870,8 @@ inline bool mmap::open(const char *path) { return false; } -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8) +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) && \ + (_WIN32_WINNT >= _WIN32_WINNT_WIN8) addr_ = ::MapViewOfFileFromApp(hMapping_, FILE_MAP_READ, 0, 0); #else addr_ = ::MapViewOfFile(hMapping_, FILE_MAP_READ, 0, 0, 0); @@ -3251,7 +3258,13 @@ socket_t create_socket(const std::string &host, const std::string &ip, int port, const auto addrlen = host.length(); if (addrlen > sizeof(sockaddr_un::sun_path)) { return INVALID_SOCKET; } +#ifdef SOCK_CLOEXEC + auto sock = socket(hints.ai_family, hints.ai_socktype | SOCK_CLOEXEC, + hints.ai_protocol); +#else auto sock = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol); +#endif + if (sock != INVALID_SOCKET) { sockaddr_un addr{}; addr.sun_family = AF_UNIX; @@ -3261,7 +3274,10 @@ socket_t create_socket(const std::string &host, const std::string &ip, int port, hints.ai_addrlen = static_cast( sizeof(addr) - sizeof(addr.sun_path) + addrlen); +#ifndef SOCK_CLOEXEC fcntl(sock, F_SETFD, FD_CLOEXEC); +#endif + if (socket_options) { socket_options(sock); } if (!bind_or_connect(sock, hints)) { @@ -3306,11 +3322,18 @@ socket_t create_socket(const std::string &host, const std::string &ip, int port, sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); } #else + +#ifdef SOCK_CLOEXEC + auto sock = + socket(rp->ai_family, rp->ai_socktype | SOCK_CLOEXEC, rp->ai_protocol); +#else auto sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); +#endif + #endif if (sock == INVALID_SOCKET) { continue; } -#ifndef _WIN32 +#if !defined _WIN32 && !defined SOCK_CLOEXEC if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) { close_socket(sock); continue; @@ -6505,7 +6528,16 @@ inline bool Server::listen_internal() { #ifndef _WIN32 } #endif + +#if defined _WIN32 + // sockets conneced via WASAccept inherit flags NO_HANDLE_INHERIT, + // OVERLAPPED + socket_t sock = WSAAccept(svr_sock_, nullptr, nullptr, nullptr, 0); +#elif defined SOCK_CLOEXEC + socket_t sock = accept4(svr_sock_, nullptr, nullptr, SOCK_CLOEXEC); +#else socket_t sock = accept(svr_sock_, nullptr, nullptr); +#endif if (sock == INVALID_SOCKET) { if (errno == EMFILE) { @@ -8189,7 +8221,8 @@ inline Result ClientImpl::Patch(const std::string &path, inline Result ClientImpl::Patch(const std::string &path, const std::string &body, - const std::string &content_type, Progress progress) { + const std::string &content_type, + Progress progress) { return Patch(path, Headers(), body, content_type, progress); } @@ -8540,13 +8573,29 @@ inline SSL *ssl_new(socket_t sock, SSL_CTX *ctx, std::mutex &ctx_mutex, return ssl; } -inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl, +inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl, socket_t sock, bool shutdown_gracefully) { // sometimes we may want to skip this to try to avoid SIGPIPE if we know // the remote has closed the network connection // Note that it is not always possible to avoid SIGPIPE, this is merely a // best-efforts. - if (shutdown_gracefully) { SSL_shutdown(ssl); } + if (shutdown_gracefully) { +#ifdef _WIN32 + SSL_shutdown(ssl); +#else + timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, + reinterpret_cast(&tv), sizeof(tv)); + + auto ret = SSL_shutdown(ssl); + while (ret == 0) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + ret = SSL_shutdown(ssl); + } +#endif + } std::lock_guard guard(ctx_mutex); SSL_free(ssl); @@ -8788,17 +8837,17 @@ inline bool SSLServer::is_valid() const { return ctx_; } inline SSL_CTX *SSLServer::ssl_context() const { return ctx_; } -inline void SSLServer::update_certs (X509 *cert, EVP_PKEY *private_key, - X509_STORE *client_ca_cert_store) { +inline void SSLServer::update_certs(X509 *cert, EVP_PKEY *private_key, + X509_STORE *client_ca_cert_store) { - std::lock_guard guard(ctx_mutex_); + std::lock_guard guard(ctx_mutex_); - SSL_CTX_use_certificate (ctx_, cert); - SSL_CTX_use_PrivateKey (ctx_, private_key); + SSL_CTX_use_certificate(ctx_, cert); + SSL_CTX_use_PrivateKey(ctx_, private_key); - if (client_ca_cert_store != nullptr) { - SSL_CTX_set_cert_store (ctx_, client_ca_cert_store); - } + if (client_ca_cert_store != nullptr) { + SSL_CTX_set_cert_store(ctx_, client_ca_cert_store); + } } inline bool SSLServer::process_and_close_socket(socket_t sock) { @@ -8825,7 +8874,7 @@ inline bool SSLServer::process_and_close_socket(socket_t sock) { // Shutdown gracefully if the result seemed successful, non-gracefully if // the connection appeared to be closed. const bool shutdown_gracefully = ret; - detail::ssl_delete(ctx_mutex_, ssl, shutdown_gracefully); + detail::ssl_delete(ctx_mutex_, ssl, sock, shutdown_gracefully); } detail::shutdown_socket(sock); @@ -9111,7 +9160,8 @@ inline void SSLClient::shutdown_ssl_impl(Socket &socket, return; } if (socket.ssl) { - detail::ssl_delete(ctx_mutex_, socket.ssl, shutdown_gracefully); + detail::ssl_delete(ctx_mutex_, socket.ssl, socket.sock, + shutdown_gracefully); socket.ssl = nullptr; } assert(socket.ssl == nullptr); @@ -9306,7 +9356,7 @@ inline Client::Client(const std::string &scheme_host_port, cli_ = detail::make_unique(scheme_host_port, 80, client_cert_path, client_key_path); } -} +} // namespace detail inline Client::Client(const std::string &host, int port) : cli_(detail::make_unique(host, port)) {} @@ -9586,7 +9636,8 @@ inline Result Client::Patch(const std::string &path, const char *body, } inline Result Client::Patch(const std::string &path, const char *body, size_t content_length, - const std::string &content_type, Progress progress) { + const std::string &content_type, + Progress progress) { return cli_->Patch(path, body, content_length, content_type, progress); } inline Result Client::Patch(const std::string &path, const Headers &headers, @@ -9596,15 +9647,18 @@ inline Result Client::Patch(const std::string &path, const Headers &headers, } inline Result Client::Patch(const std::string &path, const Headers &headers, const char *body, size_t content_length, - const std::string &content_type, Progress progress) { - return cli_->Patch(path, headers, body, content_length, content_type, progress); + const std::string &content_type, + Progress progress) { + return cli_->Patch(path, headers, body, content_length, content_type, + progress); } inline Result Client::Patch(const std::string &path, const std::string &body, const std::string &content_type) { return cli_->Patch(path, body, content_type); } inline Result Client::Patch(const std::string &path, const std::string &body, - const std::string &content_type, Progress progress) { + const std::string &content_type, + Progress progress) { return cli_->Patch(path, body, content_type, progress); } inline Result Client::Patch(const std::string &path, const Headers &headers, @@ -9614,7 +9668,8 @@ inline Result Client::Patch(const std::string &path, const Headers &headers, } inline Result Client::Patch(const std::string &path, const Headers &headers, const std::string &body, - const std::string &content_type, Progress progress) { + const std::string &content_type, + Progress progress) { return cli_->Patch(path, headers, body, content_type, progress); } inline Result Client::Patch(const std::string &path, size_t content_length, @@ -9653,7 +9708,8 @@ inline Result Client::Delete(const std::string &path, const char *body, } inline Result Client::Delete(const std::string &path, const char *body, size_t content_length, - const std::string &content_type, Progress progress) { + const std::string &content_type, + Progress progress) { return cli_->Delete(path, body, content_length, content_type, progress); } inline Result Client::Delete(const std::string &path, const Headers &headers, @@ -9663,15 +9719,18 @@ inline Result Client::Delete(const std::string &path, const Headers &headers, } inline Result Client::Delete(const std::string &path, const Headers &headers, const char *body, size_t content_length, - const std::string &content_type, Progress progress) { - return cli_->Delete(path, headers, body, content_length, content_type, progress); + const std::string &content_type, + Progress progress) { + return cli_->Delete(path, headers, body, content_length, content_type, + progress); } inline Result Client::Delete(const std::string &path, const std::string &body, const std::string &content_type) { return cli_->Delete(path, body, content_type); } inline Result Client::Delete(const std::string &path, const std::string &body, - const std::string &content_type, Progress progress) { + const std::string &content_type, + Progress progress) { return cli_->Delete(path, body, content_type, progress); } inline Result Client::Delete(const std::string &path, const Headers &headers, @@ -9681,7 +9740,8 @@ inline Result Client::Delete(const std::string &path, const Headers &headers, } inline Result Client::Delete(const std::string &path, const Headers &headers, const std::string &body, - const std::string &content_type, Progress progress) { + const std::string &content_type, + Progress progress) { return cli_->Delete(path, headers, body, content_type, progress); } inline Result Client::Options(const std::string &path) {