Compare commits

..

22 Commits

Author SHA1 Message Date
yhirose
6ad25b6cf0 Fix #566 2020-07-12 20:41:02 -04:00
yhirose
3dff60eb16 Fix #565 2020-07-10 08:18:28 -04:00
yhirose
5038314b21 Fix #564 2020-07-08 13:56:06 -04:00
yhirose
6e1297cab0 Fix #150 (#556) 2020-07-07 18:55:46 -04:00
yhirose
7de743c962 Code format 2020-07-04 00:11:32 -04:00
Umiade
964fb5e5ca Fix: regex can't match when proxy was set to some web debugger(e.g. Fiddler) (#553)
Co-authored-by: Umiade <hanyuchao@corp.netease.com>
2020-07-03 07:17:04 -04:00
yhirose
c4f3f9529b Fix #534 (#546) 2020-07-02 21:57:50 -04:00
Ilya Tsybulsky
887def9490 Fix logger never called when write_content_with_provider returns false (#549) 2020-07-01 17:09:43 -04:00
Ilya Tsybulsky
bad6b2d22f fix-the-code-won't compile-with-sdl-checks-on (#550) 2020-07-01 17:09:19 -04:00
rundong08
3d47a51430 Fixed comparison of integers of different signs. (#544) 2020-06-29 21:19:56 -04:00
Ron Klein
0a2cb20223 fix documentation typo (#539)
fix "adress" --> "address"
2020-06-22 18:12:22 -04:00
yhirose
ce502a73e1 Fix #531 2020-06-22 14:56:18 -04:00
yhirose
010e4479f4 Fixed test errors due to httpbin.org 2020-06-22 14:53:20 -04:00
Ahmet Karaahmetoğlu
70e193374a Fix #530 (#535) 2020-06-21 15:08:40 -04:00
yhirose
6b22409217 Code format 2020-06-18 23:33:07 -04:00
yhirose
969cccd52a Use && for parameter of boundary 2020-06-18 23:32:09 -04:00
yhirose
4a9c048bbc Fixed problem with set_socket_options 2020-06-18 23:31:41 -04:00
yhirose
bfabbec8c7 Fix #528 2020-06-18 12:20:01 -04:00
yhirose
3e9c06cf79 Fixed #527 2020-06-18 12:18:43 -04:00
yhirose
29677540ae Removed unnecessary yeid. 2020-06-16 21:33:10 -04:00
yhirose
71fcfeb912 Removed unnecessary code 2020-06-16 21:21:03 -04:00
yhirose
c7d22e451f Fixed timeout calculation bugs 2020-06-16 21:20:47 -04:00
5 changed files with 207 additions and 83 deletions

View File

@@ -50,8 +50,9 @@
-------------------------------------------------------------------------------
FindPython3 requires Cmake v3.12
ARCH_INDEPENDENT option of write_basic_package_version_file() requires Cmake v3.14
]]
cmake_minimum_required(VERSION 3.12.0 FATAL_ERROR)
cmake_minimum_required(VERSION 3.14.0 FATAL_ERROR)
# Gets the latest tag as a string like "v0.6.6"
# Can silently fail if git isn't on the system

View File

@@ -287,7 +287,7 @@ Client Example
int main(void)
{
// IMPORTANT: 1st parameter must be a hostname or an IP adress string.
// IMPORTANT: 1st parameter must be a hostname or an IP address string.
httplib::Client cli("localhost", 1234);
auto res = cli.Get("/hi");

251
httplib.h
View File

@@ -72,6 +72,10 @@
#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH ((std::numeric_limits<size_t>::max)())
#endif
#ifndef CPPHTTPLIB_TCP_NODELAY
#define CPPHTTPLIB_TCP_NODELAY false
#endif
#ifndef CPPHTTPLIB_RECV_BUFSIZ
#define CPPHTTPLIB_RECV_BUFSIZ size_t(4096u)
#endif
@@ -148,6 +152,8 @@ using ssize_t = int;
#ifdef _MSC_VER
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "cryptui.lib")
#endif
#ifndef strcasecmp
@@ -166,6 +172,7 @@ using socket_t = SOCKET;
#include <ifaddrs.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#ifdef CPPHTTPLIB_USE_POLL
#include <poll.h>
#endif
@@ -573,6 +580,7 @@ public:
void set_expect_100_continue_handler(Expect100ContinueHandler handler);
void set_logger(Logger logger);
void set_tcp_nodelay(bool on);
void set_socket_options(SocketOptions socket_options);
void set_keep_alive_max_count(size_t count);
@@ -661,6 +669,8 @@ private:
Handler error_handler_;
Logger logger_;
Expect100ContinueHandler expect_100_continue_handler_;
bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY;
SocketOptions socket_options_ = default_socket_options;
};
@@ -802,6 +812,9 @@ public:
void stop();
void set_tcp_nodelay(bool on);
void set_socket_options(SocketOptions socket_options);
CPPHTTPLIB_DEPRECATED void set_timeout_sec(time_t timeout_sec);
void set_connection_timeout(time_t sec, time_t usec = 0);
void set_read_timeout(time_t sec, time_t usec = 0);
@@ -876,6 +889,9 @@ protected:
bool keep_alive_ = false;
bool follow_location_ = false;
bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY;
SocketOptions socket_options_ = nullptr;
bool compress_ = false;
bool decompress_ = true;
@@ -909,6 +925,8 @@ protected:
#endif
keep_alive_ = rhs.keep_alive_;
follow_location_ = rhs.follow_location_;
tcp_nodelay_ = rhs.tcp_nodelay_;
socket_options_ = rhs.socket_options_;
compress_ = rhs.compress_;
decompress_ = rhs.decompress_;
interface_ = rhs.interface_;
@@ -1046,6 +1064,8 @@ private:
bool connect_with_proxy(Socket &sock, Response &res, bool &success);
bool initialize_ssl(Socket &socket);
bool load_certs();
bool verify_host(X509 *server_cert) const;
bool verify_host_with_subject_alt_name(X509 *server_cert) const;
bool verify_host_with_common_name(X509 *server_cert) const;
@@ -1053,12 +1073,14 @@ private:
SSL_CTX *ctx_;
std::mutex ctx_mutex_;
std::once_flag initialize_cert_;
std::vector<std::string> host_components_;
std::string ca_cert_file_path_;
std::string ca_cert_dir_path_;
X509_STORE *ca_cert_store_ = nullptr;
bool server_certificate_verification_ = false;
bool server_certificate_verification_ = true;
long verify_result_ = 0;
friend class Client;
@@ -1297,6 +1319,12 @@ public:
void stop() { cli_->stop(); }
void set_tcp_nodelay(bool on) { cli_->set_tcp_nodelay(on); }
void set_socket_options(SocketOptions socket_options) {
cli_->set_socket_options(socket_options);
}
Client2 &set_connection_timeout(time_t sec, time_t usec) {
cli_->set_connection_timeout(sec, usec);
return *this;
@@ -1850,26 +1878,19 @@ private:
size_t position = 0;
};
inline bool keep_alive(socket_t sock, std::function<bool()> is_shutting_down) {
inline bool keep_alive(socket_t sock) {
using namespace std::chrono;
auto start = steady_clock::now();
while (true) {
auto val = select_read(sock, 0, 10000);
if (is_shutting_down && is_shutting_down()) {
return false;
} else if (val < 0) {
if (val < 0) {
return false;
} else if (val == 0) {
auto current = steady_clock::now();
auto sec = duration_cast<seconds>(current - start);
if (sec.count() > CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND) {
return false;
} else if (sec.count() == CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND) {
auto usec = duration_cast<nanoseconds>(current - start);
if (usec.count() > CPPHTTPLIB_KEEPALIVE_TIMEOUT_USECOND) {
return false;
}
}
auto duration = duration_cast<milliseconds>(current - start);
auto timeout = CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND * 1000 +
CPPHTTPLIB_KEEPALIVE_TIMEOUT_USECOND / 1000;
if (duration.count() > timeout) { return false; }
std::this_thread::sleep_for(std::chrono::milliseconds(1));
} else {
return true;
@@ -1877,14 +1898,14 @@ inline bool keep_alive(socket_t sock, std::function<bool()> is_shutting_down) {
}
}
template <typename T, typename U>
template <typename T>
inline bool process_server_socket_core(socket_t sock,
size_t keep_alive_max_count,
T is_shutting_down, U callback) {
T callback) {
assert(keep_alive_max_count > 0);
auto ret = false;
auto count = keep_alive_max_count;
while (count > 0 && keep_alive(sock, is_shutting_down)) {
while (count > 0 && keep_alive(sock)) {
auto close_connection = count == 1;
auto connection_closed = false;
ret = callback(close_connection, connection_closed);
@@ -1894,14 +1915,14 @@ inline bool process_server_socket_core(socket_t sock,
return ret;
}
template <typename T, typename U>
inline bool
process_server_socket(socket_t sock, size_t keep_alive_max_count,
time_t read_timeout_sec, time_t read_timeout_usec,
time_t write_timeout_sec, time_t write_timeout_usec,
T is_shutting_down, U callback) {
template <typename T>
inline bool process_server_socket(socket_t sock, size_t keep_alive_max_count,
time_t read_timeout_sec,
time_t read_timeout_usec,
time_t write_timeout_sec,
time_t write_timeout_usec, T callback) {
return process_server_socket_core(
sock, keep_alive_max_count, is_shutting_down,
sock, keep_alive_max_count,
[&](bool close_connection, bool connection_closed) {
SocketStream strm(sock, read_timeout_sec, read_timeout_usec,
write_timeout_sec, write_timeout_usec);
@@ -1929,7 +1950,7 @@ inline int shutdown_socket(socket_t sock) {
template <typename BindOrConnect>
socket_t create_socket(const char *host, int port, int socket_flags,
SocketOptions socket_options,
bool tcp_nodelay, SocketOptions socket_options,
BindOrConnect bind_or_connect) {
// Get address info
struct addrinfo hints;
@@ -1978,18 +1999,14 @@ socket_t create_socket(const char *host, int port, int socket_flags,
if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) { continue; }
#endif
if (tcp_nodelay) {
int yes = 1;
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&yes),
sizeof(yes));
}
if (socket_options) { socket_options(sock); }
// Make 'reuse address' option available
int yes = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&yes),
sizeof(yes));
#ifdef SO_REUSEPORT
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast<char *>(&yes),
sizeof(yes));
#endif
if (rp->ai_family == AF_INET6) {
int no = 0;
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char *>(&no),
@@ -2074,11 +2091,12 @@ inline std::string if2ip(const std::string &ifn) {
#endif
inline socket_t create_client_socket(const char *host, int port,
bool tcp_nodelay,
SocketOptions socket_options,
time_t timeout_sec, time_t timeout_usec,
const std::string &intf) {
return create_socket(
host, port, 0, socket_options,
host, port, 0, tcp_nodelay, socket_options,
[&](socket_t sock, struct addrinfo &ai) -> bool {
if (!intf.empty()) {
#ifndef _WIN32
@@ -2762,7 +2780,7 @@ inline std::string params_to_query_str(const Params &params) {
if (it != params.begin()) { query += "&"; }
query += it->first;
query += "=";
query += detail::encode_url(it->second);
query += encode_url(it->second);
}
return query;
@@ -2787,9 +2805,12 @@ inline bool parse_multipart_boundary(const std::string &content_type,
std::string &boundary) {
auto pos = content_type.find("boundary=");
if (pos == std::string::npos) { return false; }
boundary = content_type.substr(pos + 9);
return true;
if (boundary.length() >= 2 && boundary.front() == '"' &&
boundary.back() == '"') {
boundary = boundary.substr(1, boundary.size() - 2);
}
return !boundary.empty();
}
inline bool parse_range_header(const std::string &s, Ranges &ranges) {
@@ -2830,7 +2851,7 @@ class MultipartFormDataParser {
public:
MultipartFormDataParser() = default;
void set_boundary(std::string boundary) { boundary_ = std::move(boundary); }
void set_boundary(std::string &&boundary) { boundary_ = boundary; }
bool is_valid() const { return is_valid_; }
@@ -2854,9 +2875,7 @@ public:
auto pattern = dash_ + boundary_ + crlf_;
if (pattern.size() > buf_.size()) { return true; }
auto pos = buf_.find(pattern);
if (pos != 0) {
return false;
}
if (pos != 0) { return false; }
buf_.erase(0, pattern.size());
off_ += pattern.size();
state_ = 1;
@@ -2898,6 +2917,7 @@ public:
pos = buf_.find(crlf_);
}
if (state_ != 3) { return true; }
break;
}
case 3: { // Body
{
@@ -3207,6 +3227,33 @@ inline std::string SHA_512(const std::string &s) {
#endif
#ifdef _WIN32
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
// NOTE: This code came up with the following stackoverflow post:
// https://stackoverflow.com/questions/9507184/can-openssl-on-windows-use-the-system-certificate-store
inline bool load_system_certs_on_windows(X509_STORE *store) {
auto hStore = CertOpenSystemStoreW((HCRYPTPROV_LEGACY)NULL, L"ROOT");
if (!hStore) { return false; }
PCCERT_CONTEXT pContext = NULL;
while (pContext = CertEnumCertificatesInStore(hStore, pContext)) {
auto encoded_cert =
static_cast<const unsigned char *>(pContext->pbCertEncoded);
auto x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded);
if (x509) {
X509_STORE_add_cert(store, x509);
X509_free(x509);
}
}
CertFreeCertificateContext(pContext);
CertCloseStore(hStore, 0);
return true;
}
#endif
class WSInit {
public:
WSInit() {
@@ -3480,10 +3527,11 @@ inline ssize_t Stream::write(const std::string &s) {
template <typename... Args>
inline ssize_t Stream::write_format(const char *fmt, const Args &... args) {
std::array<char, 2048> buf;
const auto bufsiz = 2048;
std::array<char, bufsiz> buf;
#if defined(_MSC_VER) && _MSC_VER < 1900
auto sn = _snprintf_s(buf, bufsiz, buf.size() - 1, fmt, args...);
auto sn = _snprintf_s(buf, bufsiz - 1, buf.size() - 1, fmt, args...);
#else
auto sn = snprintf(buf.data(), buf.size() - 1, fmt, args...);
#endif
@@ -3570,7 +3618,7 @@ inline bool BufferStream::is_readable() const { return true; }
inline bool BufferStream::is_writable() const { return true; }
inline ssize_t BufferStream::read(char *ptr, size_t size) {
#if defined(_MSC_VER) && _MSC_VER < 1900
#if defined(_MSC_VER) && _MSC_VER <= 1900
auto len_read = buffer._Copy_s(ptr, size, size, position);
#else
auto len_read = buffer.copy(ptr, size, position);
@@ -3697,6 +3745,12 @@ inline void Server::set_error_handler(Handler handler) {
error_handler_ = std::move(handler);
}
inline void Server::set_tcp_nodelay(bool on) { tcp_nodelay_ = on; }
inline void Server::set_socket_options(SocketOptions socket_options) {
socket_options_ = socket_options;
}
inline void Server::set_logger(Logger logger) { logger_ = std::move(logger); }
inline void
@@ -3886,13 +3940,14 @@ inline bool Server::write_response(Stream &strm, bool close_connection,
strm.write(data.data(), data.size());
// Body
auto ret = true;
if (req.method != "HEAD") {
if (!res.body.empty()) {
if (!strm.write(res.body)) { return false; }
if (!strm.write(res.body)) { ret = false; }
} else if (res.content_provider_) {
if (!write_content_with_provider(strm, req, res, boundary,
content_type)) {
return false;
ret = false;
}
}
}
@@ -3900,7 +3955,7 @@ inline bool Server::write_response(Stream &strm, bool close_connection,
// Log
if (logger_) { logger_(req, res); }
return true;
return ret;
}
inline bool
@@ -4063,7 +4118,7 @@ inline socket_t
Server::create_server_socket(const char *host, int port, int socket_flags,
SocketOptions socket_options) const {
return detail::create_socket(
host, port, socket_flags, socket_options,
host, port, socket_flags, tcp_nodelay_, socket_options,
[](socket_t sock, struct addrinfo &ai) -> bool {
if (::bind(sock, ai.ai_addr, static_cast<socklen_t>(ai.ai_addrlen))) {
return false;
@@ -4341,13 +4396,11 @@ inline bool Server::process_and_close_socket(socket_t sock) {
auto ret = detail::process_server_socket(
sock, keep_alive_max_count_, read_timeout_sec_, read_timeout_usec_,
write_timeout_sec_, write_timeout_usec_,
[this]() { return this->svr_sock_ == INVALID_SOCKET; },
[this](Stream &strm, bool close_connection, bool &connection_closed) {
return process_request(strm, close_connection, connection_closed,
nullptr);
});
std::this_thread::sleep_for(std::chrono::milliseconds(1));
detail::shutdown_socket(sock);
detail::close_socket(sock);
return ret;
@@ -4363,7 +4416,7 @@ inline Client::Client(const std::string &host, int port)
inline Client::Client(const std::string &host, int port,
const std::string &client_cert_path,
const std::string &client_key_path)
: /*cli_sock_(INVALID_SOCKET),*/ host_(host), port_(port),
: host_(host), port_(port),
host_and_port_(host_ + ":" + std::to_string(port_)),
client_cert_path_(client_cert_path), client_key_path_(client_key_path) {}
@@ -4373,12 +4426,12 @@ inline bool Client::is_valid() const { return true; }
inline socket_t Client::create_client_socket() const {
if (!proxy_host_.empty()) {
return detail::create_client_socket(proxy_host_.c_str(), proxy_port_,
nullptr, connection_timeout_sec_,
connection_timeout_usec_, interface_);
return detail::create_client_socket(
proxy_host_.c_str(), proxy_port_, tcp_nodelay_, socket_options_,
connection_timeout_sec_, connection_timeout_usec_, interface_);
}
return detail::create_client_socket(host_.c_str(), port_, nullptr,
connection_timeout_sec_,
return detail::create_client_socket(host_.c_str(), port_, tcp_nodelay_,
socket_options_, connection_timeout_sec_,
connection_timeout_usec_, interface_);
}
@@ -4404,7 +4457,7 @@ inline bool Client::read_response_line(Stream &strm, Response &res) {
if (!line_reader.getline()) { return false; }
const static std::regex re("(HTTP/1\\.[01]) (\\d+?) .*\r\n");
const static std::regex re("(HTTP/1\\.[01]) (\\d+).*?\r\n");
std::cmatch m;
if (std::regex_match(line_reader.ptr(), m, re)) {
@@ -5109,6 +5162,12 @@ inline void Client::set_keep_alive(bool on) { keep_alive_ = on; }
inline void Client::set_follow_location(bool on) { follow_location_ = on; }
inline void Client::set_tcp_nodelay(bool on) { tcp_nodelay_ = on; }
inline void Client::set_socket_options(SocketOptions socket_options) {
socket_options_ = socket_options;
}
inline void Client::set_compress(bool on) { compress_ = on; }
inline void Client::set_decompress(bool on) { decompress_ = on; }
@@ -5183,9 +5242,9 @@ inline bool
process_server_socket_ssl(SSL *ssl, socket_t sock, size_t keep_alive_max_count,
time_t read_timeout_sec, time_t read_timeout_usec,
time_t write_timeout_sec, time_t write_timeout_usec,
std::function<bool()> is_shutting_down, T callback) {
T callback) {
return process_server_socket_core(
sock, keep_alive_max_count, is_shutting_down,
sock, keep_alive_max_count,
[&](bool close_connection, bool connection_closed) {
SSLSocketStream strm(sock, ssl, read_timeout_sec, read_timeout_usec,
write_timeout_sec, write_timeout_usec);
@@ -5263,7 +5322,24 @@ inline SSLSocketStream::SSLSocketStream(socket_t sock, SSL *ssl,
: sock_(sock), ssl_(ssl), read_timeout_sec_(read_timeout_sec),
read_timeout_usec_(read_timeout_usec),
write_timeout_sec_(write_timeout_sec),
write_timeout_usec_(write_timeout_usec) {}
write_timeout_usec_(write_timeout_usec) {
{
timeval tv;
tv.tv_sec = static_cast<long>(read_timeout_sec);
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(read_timeout_usec);
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<char *>(&tv),
sizeof(tv));
}
{
timeval tv;
tv.tv_sec = static_cast<long>(write_timeout_sec);
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(write_timeout_usec);
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<char *>(&tv),
sizeof(tv));
}
}
inline SSLSocketStream::~SSLSocketStream() {}
@@ -5377,7 +5453,6 @@ inline bool SSLServer::process_and_close_socket(socket_t sock) {
auto ret = detail::process_server_socket_ssl(
ssl, sock, keep_alive_max_count_, read_timeout_sec_, read_timeout_usec_,
write_timeout_sec_, write_timeout_usec_,
[this]() { return this->svr_sock_ == INVALID_SOCKET; },
[this, ssl](Stream &strm, bool close_connection,
bool &connection_closed) {
return process_request(strm, close_connection, connection_closed,
@@ -5518,23 +5593,44 @@ inline bool SSLClient::connect_with_proxy(Socket &socket, Response &res,
return true;
}
inline bool SSLClient::load_certs() {
bool ret = true;
std::call_once(initialize_cert_, [&]() {
std::lock_guard<std::mutex> guard(ctx_mutex_);
if (!ca_cert_file_path_.empty()) {
if (!SSL_CTX_load_verify_locations(ctx_, ca_cert_file_path_.c_str(),
nullptr)) {
ret = false;
}
} else if (!ca_cert_dir_path_.empty()) {
if (!SSL_CTX_load_verify_locations(ctx_, nullptr,
ca_cert_dir_path_.c_str())) {
ret = false;
}
} else if (ca_cert_store_ != nullptr) {
if (SSL_CTX_get_cert_store(ctx_) != ca_cert_store_) {
SSL_CTX_set_cert_store(ctx_, ca_cert_store_);
}
} else {
#ifdef _WIN32
detail::load_system_certs_on_windows(SSL_CTX_get_cert_store(ctx_));
#else
SSL_CTX_set_default_verify_paths(ctx_);
#endif
}
});
return ret;
}
inline bool SSLClient::initialize_ssl(Socket &socket) {
auto ssl = detail::ssl_new(
socket.sock, ctx_, ctx_mutex_,
[&](SSL *ssl) {
if (ca_cert_file_path_.empty() && ca_cert_store_ == nullptr) {
SSL_CTX_set_verify(ctx_, SSL_VERIFY_NONE, nullptr);
} else if (!ca_cert_file_path_.empty()) {
if (!SSL_CTX_load_verify_locations(ctx_, ca_cert_file_path_.c_str(),
nullptr)) {
return false;
}
SSL_CTX_set_verify(ctx_, SSL_VERIFY_PEER, nullptr);
} else if (ca_cert_store_ != nullptr) {
if (SSL_CTX_get_cert_store(ctx_) != ca_cert_store_) {
SSL_CTX_set_cert_store(ctx_, ca_cert_store_);
}
SSL_CTX_set_verify(ctx_, SSL_VERIFY_PEER, nullptr);
if (server_certificate_verification_) {
if (!load_certs()) { return false; }
SSL_set_verify(ssl, SSL_VERIFY_NONE, nullptr);
}
if (SSL_connect(ssl) != 1) { return false; }
@@ -5646,7 +5742,7 @@ SSLClient::verify_host_with_subject_alt_name(X509 *server_cert) const {
auto count = sk_GENERAL_NAME_num(alt_names);
for (auto i = 0; i < count && !dsn_matched; i++) {
for (decltype(count) i = 0; i < count && !dsn_matched; i++) {
auto val = sk_GENERAL_NAME_value(alt_names, i);
if (val->type == type) {
auto name = (const char *)ASN1_STRING_get0_data(val->d.ia5);
@@ -5724,3 +5820,4 @@ inline bool SSLClient::check_host_name(const char *pattern,
} // namespace httplib
#endif // CPPHTTPLIB_HTTPLIB_H

View File

@@ -578,6 +578,7 @@ TEST(DigestAuthTest, FromHTTPWatch) {
}
#endif
#if 0
TEST(AbsoluteRedirectTest, Redirect) {
auto host = "httpbin.org";
@@ -636,6 +637,7 @@ TEST(TooManyRedirectTest, Redirect) {
auto res = cli.Get("/redirect/21");
ASSERT_TRUE(res == nullptr);
}
#endif
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
TEST(YahooRedirectTest, Redirect) {
@@ -651,6 +653,7 @@ TEST(YahooRedirectTest, Redirect) {
EXPECT_EQ(200, res->status);
}
#if 0
TEST(HttpsToHttpRedirectTest, Redirect) {
httplib::SSLClient cli("httpbin.org");
cli.set_follow_location(true);
@@ -659,6 +662,7 @@ TEST(HttpsToHttpRedirectTest, Redirect) {
ASSERT_TRUE(res != nullptr);
EXPECT_EQ(200, res->status);
}
#endif
TEST(RedirectToDifferentPort, Redirect) {
Server svr8080;
@@ -761,6 +765,9 @@ protected:
svr_(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE)
#endif
{
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
cli_.enable_server_certificate_verification(false);
#endif
}
virtual void SetUp() {
@@ -2315,7 +2322,7 @@ TEST_F(ServerTest, MultipartFormDataGzip) {
static bool send_request(time_t read_timeout_sec, const std::string &req,
std::string *resp = nullptr) {
auto client_sock =
detail::create_client_socket(HOST, PORT, nullptr,
detail::create_client_socket(HOST, PORT, false, nullptr,
/*timeout_sec=*/5, 0, std::string());
if (client_sock == INVALID_SOCKET) { return false; }
@@ -2623,6 +2630,9 @@ protected:
svr_(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE)
#endif
{
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
cli_.enable_server_certificate_verification(false);
#endif
}
virtual void SetUp() {
@@ -2700,6 +2710,9 @@ protected:
svr_(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE)
#endif
{
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
cli_.enable_server_certificate_verification(false);
#endif
}
virtual void SetUp() {
@@ -2759,6 +2772,7 @@ TEST(SSLClientTest, ServerCertificateVerification1) {
TEST(SSLClientTest, ServerCertificateVerification2) {
SSLClient cli("google.com");
cli.enable_server_certificate_verification(true);
cli.set_ca_cert_path("hello");
auto res = cli.Get("/");
ASSERT_TRUE(res == nullptr);
}
@@ -2815,8 +2829,10 @@ TEST(SSLClientServerTest, ClientCertPresent) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
httplib::SSLClient cli(HOST, PORT, CLIENT_CERT_FILE, CLIENT_PRIVATE_KEY_FILE);
auto res = cli.Get("/test");
cli.enable_server_certificate_verification(false);
cli.set_connection_timeout(30);
auto res = cli.Get("/test");
ASSERT_TRUE(res != nullptr);
ASSERT_EQ(200, res->status);
@@ -2884,8 +2900,10 @@ TEST(SSLClientServerTest, MemoryClientCertPresent) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
httplib::SSLClient cli(HOST, PORT, client_cert, client_private_key);
auto res = cli.Get("/test");
cli.enable_server_certificate_verification(false);
cli.set_connection_timeout(30);
auto res = cli.Get("/test");
ASSERT_TRUE(res != nullptr);
ASSERT_EQ(200, res->status);
@@ -2930,8 +2948,10 @@ TEST(SSLClientServerTest, TrustDirOptional) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
httplib::SSLClient cli(HOST, PORT, CLIENT_CERT_FILE, CLIENT_PRIVATE_KEY_FILE);
auto res = cli.Get("/test");
cli.enable_server_certificate_verification(false);
cli.set_connection_timeout(30);
auto res = cli.Get("/test");
ASSERT_TRUE(res != nullptr);
ASSERT_EQ(200, res->status);
@@ -2983,6 +3003,7 @@ TEST(YahooRedirectTest3, SimpleInterface) {
EXPECT_EQ(200, res->status);
}
#if 0
TEST(HttpsToHttpRedirectTest2, SimpleInterface) {
auto res =
httplib::Client2("https://httpbin.org")
@@ -2993,3 +3014,4 @@ TEST(HttpsToHttpRedirectTest2, SimpleInterface) {
EXPECT_EQ(200, res->status);
}
#endif
#endif

View File

@@ -52,6 +52,7 @@ void RedirectProxyText(Client& cli, const char *path, bool basic) {
EXPECT_EQ(200, res->status);
}
#if 0
TEST(RedirectTest, HTTPBinNoSSLBasic) {
Client cli("httpbin.org");
RedirectProxyText(cli, "/redirect/2", true);
@@ -73,6 +74,7 @@ TEST(RedirectTest, HTTPBinSSLDigest) {
RedirectProxyText(cli, "/redirect/2", false);
}
#endif
#endif
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
TEST(RedirectTest, YouTubeNoSSLBasic) {
@@ -260,6 +262,7 @@ void KeepAliveTest(Client& cli, bool basic) {
}
}
#if 0
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
TEST(KeepAliveTest, NoSSLWithBasic) {
Client cli("httpbin.org");
@@ -281,3 +284,4 @@ TEST(KeepAliveTest, SSLWithDigest) {
KeepAliveTest(cli, false);
}
#endif
#endif