Update cpp-httplib to c5c54b31e2bf (0.16.2)

This includes an upstreamed version of the Crashpad-local 1a62a0182557
(https://chromium-review.googlesource.com/c/5769752) for BoringSSL
compatibility.

50fce538c685 threadsafe CLOEXEC on platforms that support it
fb739dbaecf3 threadsafe accept on windows, linux
ed0719f2bcb5 Code format
521529d24d38 Fix #1481 (with content provider) (#1527)
e00fd06355e8 Release v0.16.1
ff038f98b701 Merge branch 'thread-safe-cloexec' of
             github.com:kdombroski/cpp-httplib into kdombroski-thread-
             safe-cloexec
ae63b89cbf70 Use SOCK_CLOEXEC instead of __linux__
69c84c9597c3 BoringSSL compatibility fixes (#1892)
c5c54b31e2bf Release v0.16.2

Change-Id: I01485010de53ae599e22c8ce3c9d6af046d47c24
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5769660
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
Mark Mentovai 2024-08-08 12:03:38 -04:00
parent 1a62a01825
commit 6159a43ff1
2 changed files with 100 additions and 39 deletions

View File

@ -1,7 +1,8 @@
Name: cpp-httplib Name: cpp-httplib
Short Name: cpp-httplib Short Name: cpp-httplib
URL: https://github.com/yhirose/cpp-httplib URL: https://github.com/yhirose/cpp-httplib
Revision: 6a848b1a16437fe216cb26a14ee9fcb5c5785464 Version: 0.16.2
Revision: c5c54b31e2bf8bd37ceba2715de756d1132e3685
License: MIT License: MIT
License File: cpp-httplib/LICENSE License File: cpp-httplib/LICENSE
Security Critical: no (test only) Security Critical: no (test only)

View File

@ -8,7 +8,7 @@
#ifndef CPPHTTPLIB_HTTPLIB_H #ifndef CPPHTTPLIB_HTTPLIB_H
#define CPPHTTPLIB_HTTPLIB_H #define CPPHTTPLIB_HTTPLIB_H
#define CPPHTTPLIB_VERSION "0.16.0" #define CPPHTTPLIB_VERSION "0.16.2"
/* /*
* Configuration * Configuration
@ -117,7 +117,7 @@
#define CPPHTTPLIB_LISTEN_BACKLOG 5 #define CPPHTTPLIB_LISTEN_BACKLOG 5
#endif #endif
#define CPPHTTPLIB_NO_EXCEPTIONS #define CPPHTTPLIB_NO_EXCEPTIONS 1
/* /*
* Headers * Headers
@ -272,6 +272,9 @@ using socket_t = int;
#include <sstream> #include <sstream>
#if defined(OPENSSL_IS_BORINGSSL) #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 #define SSL_get1_peer_certificate SSL_get_peer_certificate
#elif OPENSSL_VERSION_NUMBER < 0x30000000L #elif OPENSSL_VERSION_NUMBER < 0x30000000L
#error Sorry, OpenSSL versions prior to 3.0.0 are not supported #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) #if defined(CPPHTTPLIB_OPENSSL_SUPPORT) && !defined(OPENSSL_IS_BORINGSSL)
OPENSSL_thread_stop (); OPENSSL_thread_stop();
#endif #endif
} }
@ -1828,9 +1831,9 @@ public:
bool is_valid() const override; bool is_valid() const override;
SSL_CTX *ssl_context() const; SSL_CTX *ssl_context() const;
void update_certs (X509 *cert, EVP_PKEY *private_key, void update_certs(X509 *cert, EVP_PKEY *private_key,
X509_STORE *client_ca_cert_store = nullptr); X509_STORE *client_ca_cert_store = nullptr);
private: private:
bool process_and_close_socket(socket_t sock) override; bool process_and_close_socket(socket_t sock) override;
@ -2828,7 +2831,9 @@ inline bool mmap::open(const char *path) {
wpath += path[i]; 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, hFile_ = ::CreateFile2(wpath.c_str(), GENERIC_READ, FILE_SHARE_READ,
OPEN_EXISTING, NULL); OPEN_EXISTING, NULL);
#else #else
@ -2838,7 +2843,8 @@ inline bool mmap::open(const char *path) {
if (hFile_ == INVALID_HANDLE_VALUE) { return false; } 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{}; LARGE_INTEGER size{};
if (!::GetFileSizeEx(hFile_, &size)) { return false; } if (!::GetFileSizeEx(hFile_, &size)) { return false; }
size_ = static_cast<size_t>(size.QuadPart); size_ = static_cast<size_t>(size.QuadPart);
@ -2850,13 +2856,13 @@ inline bool mmap::open(const char *path) {
size_ = (static_cast<size_t>(sizeHigh) << (sizeof(DWORD) * 8)) | sizeLow; size_ = (static_cast<size_t>(sizeHigh) << (sizeof(DWORD) * 8)) | sizeLow;
#endif #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_ = hMapping_ =
::CreateFileMappingFromApp(hFile_, NULL, PAGE_READONLY, size_, NULL); ::CreateFileMappingFromApp(hFile_, NULL, PAGE_READONLY, size_, NULL);
#else #else
hMapping_ = hMapping_ = ::CreateFileMappingW(hFile_, NULL, PAGE_READONLY, size.HighPart,
::CreateFileMappingW(hFile_, NULL, PAGE_READONLY, size.HighPart, size.LowPart, NULL);
size.LowPart, NULL);
#endif #endif
if (hMapping_ == NULL) { if (hMapping_ == NULL) {
@ -2864,7 +2870,8 @@ inline bool mmap::open(const char *path) {
return false; 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); addr_ = ::MapViewOfFileFromApp(hMapping_, FILE_MAP_READ, 0, 0);
#else #else
addr_ = ::MapViewOfFile(hMapping_, FILE_MAP_READ, 0, 0, 0); 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(); const auto addrlen = host.length();
if (addrlen > sizeof(sockaddr_un::sun_path)) { return INVALID_SOCKET; } 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); auto sock = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol);
#endif
if (sock != INVALID_SOCKET) { if (sock != INVALID_SOCKET) {
sockaddr_un addr{}; sockaddr_un addr{};
addr.sun_family = AF_UNIX; 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<socklen_t>( hints.ai_addrlen = static_cast<socklen_t>(
sizeof(addr) - sizeof(addr.sun_path) + addrlen); sizeof(addr) - sizeof(addr.sun_path) + addrlen);
#ifndef SOCK_CLOEXEC
fcntl(sock, F_SETFD, FD_CLOEXEC); fcntl(sock, F_SETFD, FD_CLOEXEC);
#endif
if (socket_options) { socket_options(sock); } if (socket_options) { socket_options(sock); }
if (!bind_or_connect(sock, hints)) { 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); sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
} }
#else #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); auto sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
#endif
#endif #endif
if (sock == INVALID_SOCKET) { continue; } if (sock == INVALID_SOCKET) { continue; }
#ifndef _WIN32 #if !defined _WIN32 && !defined SOCK_CLOEXEC
if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) { if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) {
close_socket(sock); close_socket(sock);
continue; continue;
@ -6505,7 +6528,16 @@ inline bool Server::listen_internal() {
#ifndef _WIN32 #ifndef _WIN32
} }
#endif #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); socket_t sock = accept(svr_sock_, nullptr, nullptr);
#endif
if (sock == INVALID_SOCKET) { if (sock == INVALID_SOCKET) {
if (errno == EMFILE) { if (errno == EMFILE) {
@ -8189,7 +8221,8 @@ inline Result ClientImpl::Patch(const std::string &path,
inline Result ClientImpl::Patch(const std::string &path, inline Result ClientImpl::Patch(const std::string &path,
const std::string &body, 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); 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; 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) { bool shutdown_gracefully) {
// sometimes we may want to skip this to try to avoid SIGPIPE if we know // sometimes we may want to skip this to try to avoid SIGPIPE if we know
// the remote has closed the network connection // the remote has closed the network connection
// Note that it is not always possible to avoid SIGPIPE, this is merely a // Note that it is not always possible to avoid SIGPIPE, this is merely a
// best-efforts. // 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<const void *>(&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<std::mutex> guard(ctx_mutex); std::lock_guard<std::mutex> guard(ctx_mutex);
SSL_free(ssl); 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 SSL_CTX *SSLServer::ssl_context() const { return ctx_; }
inline void SSLServer::update_certs (X509 *cert, EVP_PKEY *private_key, inline void SSLServer::update_certs(X509 *cert, EVP_PKEY *private_key,
X509_STORE *client_ca_cert_store) { X509_STORE *client_ca_cert_store) {
std::lock_guard<std::mutex> guard(ctx_mutex_); std::lock_guard<std::mutex> guard(ctx_mutex_);
SSL_CTX_use_certificate (ctx_, cert); SSL_CTX_use_certificate(ctx_, cert);
SSL_CTX_use_PrivateKey (ctx_, private_key); SSL_CTX_use_PrivateKey(ctx_, private_key);
if (client_ca_cert_store != nullptr) { if (client_ca_cert_store != nullptr) {
SSL_CTX_set_cert_store (ctx_, client_ca_cert_store); SSL_CTX_set_cert_store(ctx_, client_ca_cert_store);
} }
} }
inline bool SSLServer::process_and_close_socket(socket_t sock) { 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 // Shutdown gracefully if the result seemed successful, non-gracefully if
// the connection appeared to be closed. // the connection appeared to be closed.
const bool shutdown_gracefully = ret; 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); detail::shutdown_socket(sock);
@ -9111,7 +9160,8 @@ inline void SSLClient::shutdown_ssl_impl(Socket &socket,
return; return;
} }
if (socket.ssl) { 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; socket.ssl = nullptr;
} }
assert(socket.ssl == nullptr); assert(socket.ssl == nullptr);
@ -9306,7 +9356,7 @@ inline Client::Client(const std::string &scheme_host_port,
cli_ = detail::make_unique<ClientImpl>(scheme_host_port, 80, cli_ = detail::make_unique<ClientImpl>(scheme_host_port, 80,
client_cert_path, client_key_path); client_cert_path, client_key_path);
} }
} } // namespace detail
inline Client::Client(const std::string &host, int port) inline Client::Client(const std::string &host, int port)
: cli_(detail::make_unique<ClientImpl>(host, port)) {} : cli_(detail::make_unique<ClientImpl>(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, inline Result Client::Patch(const std::string &path, const char *body,
size_t content_length, 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); return cli_->Patch(path, body, content_length, content_type, progress);
} }
inline Result Client::Patch(const std::string &path, const Headers &headers, 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, inline Result Client::Patch(const std::string &path, const Headers &headers,
const char *body, size_t content_length, const char *body, size_t content_length,
const std::string &content_type, Progress progress) { const std::string &content_type,
return cli_->Patch(path, headers, body, content_length, content_type, progress); 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, inline Result Client::Patch(const std::string &path, const std::string &body,
const std::string &content_type) { const std::string &content_type) {
return cli_->Patch(path, body, content_type); return cli_->Patch(path, body, content_type);
} }
inline Result Client::Patch(const std::string &path, const std::string &body, 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); return cli_->Patch(path, body, content_type, progress);
} }
inline Result Client::Patch(const std::string &path, const Headers &headers, 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, inline Result Client::Patch(const std::string &path, const Headers &headers,
const std::string &body, 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); return cli_->Patch(path, headers, body, content_type, progress);
} }
inline Result Client::Patch(const std::string &path, size_t content_length, 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, inline Result Client::Delete(const std::string &path, const char *body,
size_t content_length, 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); return cli_->Delete(path, body, content_length, content_type, progress);
} }
inline Result Client::Delete(const std::string &path, const Headers &headers, 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, inline Result Client::Delete(const std::string &path, const Headers &headers,
const char *body, size_t content_length, const char *body, size_t content_length,
const std::string &content_type, Progress progress) { const std::string &content_type,
return cli_->Delete(path, headers, body, content_length, content_type, progress); 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, inline Result Client::Delete(const std::string &path, const std::string &body,
const std::string &content_type) { const std::string &content_type) {
return cli_->Delete(path, body, content_type); return cli_->Delete(path, body, content_type);
} }
inline Result Client::Delete(const std::string &path, const std::string &body, 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); return cli_->Delete(path, body, content_type, progress);
} }
inline Result Client::Delete(const std::string &path, const Headers &headers, 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, inline Result Client::Delete(const std::string &path, const Headers &headers,
const std::string &body, 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); return cli_->Delete(path, headers, body, content_type, progress);
} }
inline Result Client::Options(const std::string &path) { inline Result Client::Options(const std::string &path) {