Compare commits

...

6 Commits

Author SHA1 Message Date
yhirose
c5c54b31e2 Release v0.16.2 2024-08-08 11:48:50 -04:00
Mark Mentovai
69c84c9597 BoringSSL compatibility fixes (#1892)
This patch is necessary to build cpp-httplib in Crashpad, itself in
Chromium, using BoringSSL. Details at [1].

The fixes include:
 - Library version check: tolerate BoringSSL as an alternative to
   OpenSSL 3.
 - Don’t call `OPENSSL_thread_stop`, which is not in BoringSSL.
 - Use `SSL_get_peer_certificate` (deprecated in OpenSSL 3), the old
   name for `SSL_get1_peer_certificate`, because the new name is not in
   BoringSSL.
 - Call `SSL_set_tlsext_host_name` directly instead of making an
   `SSL_ctrl` call that BoringSSL does not support. The feared
   -Wold-style-cast warning that occurs when buidling with OpenSSL is
   not triggered in BoringSSL.

[1] 1a62a01825
2024-08-08 11:47:56 -04:00
yhirose
ae63b89cbf Use SOCK_CLOEXEC instead of __linux__ 2024-08-06 17:31:55 -04:00
yhirose
ff038f98b7 Merge branch 'thread-safe-cloexec' of github.com:kdombroski/cpp-httplib into kdombroski-thread-safe-cloexec 2024-08-06 17:22:43 -04:00
Karen Dombroski
fb739dbaec threadsafe accept on windows, linux
* Windows has WSAAccept() which will create sockets inheriting flags from
  the server socket

* Linux has accept4() which has a flags argument supporting SOCK_CLOEXEC
2024-05-01 21:58:58 +12:00
Karen Dombroski
50fce538c6 threadsafe CLOEXEC on platforms that support it
SOCK_CLOEXEC is a flag available on some platforms to enable creation of
sockets with CLOEXEC already set
2024-05-01 21:46:50 +12:00

View File

@@ -8,7 +8,7 @@
#ifndef CPPHTTPLIB_HTTPLIB_H
#define CPPHTTPLIB_HTTPLIB_H
#define CPPHTTPLIB_VERSION "0.16.1"
#define CPPHTTPLIB_VERSION "0.16.2"
/*
* Configuration
@@ -269,7 +269,12 @@ using socket_t = int;
#include <iostream>
#include <sstream>
#if OPENSSL_VERSION_NUMBER < 0x30000000L
#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
#endif
@@ -727,7 +732,7 @@ private:
fn();
}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#if defined(CPPHTTPLIB_OPENSSL_SUPPORT) && !defined(OPENSSL_IS_BORINGSSL)
OPENSSL_thread_stop();
#endif
}
@@ -3251,7 +3256,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 +3272,10 @@ socket_t create_socket(const std::string &host, const std::string &ip, int port,
hints.ai_addrlen = static_cast<socklen_t>(
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 +3320,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 +6526,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) {
@@ -9096,11 +9126,14 @@ inline bool SSLClient::initialize_ssl(Socket &socket, Error &error) {
return true;
},
[&](SSL *ssl2) {
#if defined(OPENSSL_IS_BORINGSSL)
SSL_set_tlsext_host_name(ssl2, host_.c_str());
#else
// NOTE: Direct call instead of using the OpenSSL macro to suppress
// -Wold-style-cast warning
// SSL_set_tlsext_host_name(ssl2, host_.c_str());
SSL_ctrl(ssl2, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name,
static_cast<void *>(const_cast<char *>(host_.c_str())));
#endif
return true;
});
@@ -9321,7 +9354,7 @@ inline Client::Client(const std::string &scheme_host_port,
cli_ = detail::make_unique<ClientImpl>(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<ClientImpl>(host, port)) {}