Skip to content

Commit b68a83e

Browse files
authored
vendor : update cpp-httplib to 0.34.0 (ggml-org#19830)
Signed-off-by: Adrien Gallouët <angt@huggingface.co>
1 parent d8aeb65 commit b68a83e

3 files changed

Lines changed: 80 additions & 35 deletions

File tree

scripts/sync_vendor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import sys
66
import subprocess
77

8-
HTTPLIB_VERSION = "refs/tags/v0.33.1"
8+
HTTPLIB_VERSION = "refs/tags/v0.34.0"
99

1010
vendor = {
1111
"https://github.com/nlohmann/json/releases/latest/download/json.hpp": "vendor/nlohmann/json.hpp",

vendor/cpp-httplib/httplib.cpp

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,6 +1660,7 @@ class SocketStream final : public Stream {
16601660
bool is_readable() const override;
16611661
bool wait_readable() const override;
16621662
bool wait_writable() const override;
1663+
bool is_peer_alive() const override;
16631664
ssize_t read(char *ptr, size_t size) override;
16641665
ssize_t write(const char *ptr, size_t size) override;
16651666
void get_remote_ip_and_port(std::string &ip, int &port) const override;
@@ -3313,10 +3314,10 @@ bool write_content_with_progress(Stream &strm,
33133314
return ok;
33143315
};
33153316

3316-
data_sink.is_writable = [&]() -> bool { return strm.wait_writable(); };
3317+
data_sink.is_writable = [&]() -> bool { return strm.is_peer_alive(); };
33173318

33183319
while (offset < end_offset && !is_shutting_down()) {
3319-
if (!strm.wait_writable()) {
3320+
if (!strm.wait_writable() || !strm.is_peer_alive()) {
33203321
error = Error::Write;
33213322
return false;
33223323
} else if (!content_provider(offset, end_offset - offset, data_sink)) {
@@ -3328,6 +3329,11 @@ bool write_content_with_progress(Stream &strm,
33283329
}
33293330
}
33303331

3332+
if (offset < end_offset) { // exited due to is_shutting_down(), not completion
3333+
error = Error::Write;
3334+
return false;
3335+
}
3336+
33313337
error = Error::Success;
33323338
return true;
33333339
}
@@ -3367,20 +3373,21 @@ write_content_without_length(Stream &strm,
33673373
return ok;
33683374
};
33693375

3370-
data_sink.is_writable = [&]() -> bool { return strm.wait_writable(); };
3376+
data_sink.is_writable = [&]() -> bool { return strm.is_peer_alive(); };
33713377

33723378
data_sink.done = [&](void) { data_available = false; };
33733379

33743380
while (data_available && !is_shutting_down()) {
3375-
if (!strm.wait_writable()) {
3381+
if (!strm.wait_writable() || !strm.is_peer_alive()) {
33763382
return false;
33773383
} else if (!content_provider(offset, 0, data_sink)) {
33783384
return false;
33793385
} else if (!ok) {
33803386
return false;
33813387
}
33823388
}
3383-
return true;
3389+
return !data_available; // true only if done() was called, false if shutting
3390+
// down
33843391
}
33853392

33863393
template <typename T, typename U>
@@ -3416,7 +3423,7 @@ write_content_chunked(Stream &strm, const ContentProvider &content_provider,
34163423
return ok;
34173424
};
34183425

3419-
data_sink.is_writable = [&]() -> bool { return strm.wait_writable(); };
3426+
data_sink.is_writable = [&]() -> bool { return strm.is_peer_alive(); };
34203427

34213428
auto done_with_trailer = [&](const Headers *trailer) {
34223429
if (!ok) { return; }
@@ -3466,7 +3473,7 @@ write_content_chunked(Stream &strm, const ContentProvider &content_provider,
34663473
};
34673474

34683475
while (data_available && !is_shutting_down()) {
3469-
if (!strm.wait_writable()) {
3476+
if (!strm.wait_writable() || !strm.is_peer_alive()) {
34703477
error = Error::Write;
34713478
return false;
34723479
} else if (!content_provider(offset, 0, data_sink)) {
@@ -3478,6 +3485,11 @@ write_content_chunked(Stream &strm, const ContentProvider &content_provider,
34783485
}
34793486
}
34803487

3488+
if (data_available) { // exited due to is_shutting_down(), not done()
3489+
error = Error::Write;
3490+
return false;
3491+
}
3492+
34813493
error = Error::Success;
34823494
return true;
34833495
}
@@ -4646,6 +4658,7 @@ class SSLSocketStream final : public Stream {
46464658
bool is_readable() const override;
46474659
bool wait_readable() const override;
46484660
bool wait_writable() const override;
4661+
bool is_peer_alive() const override;
46494662
ssize_t read(char *ptr, size_t size) override;
46504663
ssize_t write(const char *ptr, size_t size) override;
46514664
void get_remote_ip_and_port(std::string &ip, int &port) const override;
@@ -6069,8 +6082,11 @@ bool SocketStream::wait_readable() const {
60696082
}
60706083

60716084
bool SocketStream::wait_writable() const {
6072-
return select_write(sock_, write_timeout_sec_, write_timeout_usec_) > 0 &&
6073-
is_socket_alive(sock_);
6085+
return select_write(sock_, write_timeout_sec_, write_timeout_usec_) > 0;
6086+
}
6087+
6088+
bool SocketStream::is_peer_alive() const {
6089+
return detail::is_socket_alive(sock_);
60746090
}
60756091

60766092
ssize_t SocketStream::read(char *ptr, size_t size) {
@@ -6401,7 +6417,11 @@ bool SSLSocketStream::wait_readable() const {
64016417

64026418
bool SSLSocketStream::wait_writable() const {
64036419
return select_write(sock_, write_timeout_sec_, write_timeout_usec_) > 0 &&
6404-
is_socket_alive(sock_) && !tls::is_peer_closed(session_, sock_);
6420+
!tls::is_peer_closed(session_, sock_);
6421+
}
6422+
6423+
bool SSLSocketStream::is_peer_alive() const {
6424+
return !tls::is_peer_closed(session_, sock_);
64056425
}
64066426

64076427
ssize_t SSLSocketStream::read(char *ptr, size_t size) {
@@ -6925,35 +6945,33 @@ bool Server::write_response_core(Stream &strm, bool close_connection,
69256945
if (post_routing_handler_) { post_routing_handler_(req, res); }
69266946

69276947
// Response line and headers
6928-
{
6929-
detail::BufferStream bstrm;
6930-
if (!detail::write_response_line(bstrm, res.status)) { return false; }
6931-
if (header_writer_(bstrm, res.headers) <= 0) { return false; }
6948+
detail::BufferStream bstrm;
6949+
if (!detail::write_response_line(bstrm, res.status)) { return false; }
6950+
if (header_writer_(bstrm, res.headers) <= 0) { return false; }
69326951

6933-
// Flush buffer
6934-
auto &data = bstrm.get_buffer();
6935-
detail::write_data(strm, data.data(), data.size());
6952+
// Combine small body with headers to reduce write syscalls
6953+
if (req.method != "HEAD" && !res.body.empty() && !res.content_provider_) {
6954+
bstrm.write(res.body.data(), res.body.size());
69366955
}
69376956

6938-
// Body
6957+
// Log before writing to avoid race condition with client-side code that
6958+
// accesses logger-captured data immediately after receiving the response.
6959+
output_log(req, res);
6960+
6961+
// Flush buffer
6962+
auto &data = bstrm.get_buffer();
6963+
if (!detail::write_data(strm, data.data(), data.size())) { return false; }
6964+
6965+
// Streaming body
69396966
auto ret = true;
6940-
if (req.method != "HEAD") {
6941-
if (!res.body.empty()) {
6942-
if (!detail::write_data(strm, res.body.data(), res.body.size())) {
6943-
ret = false;
6944-
}
6945-
} else if (res.content_provider_) {
6946-
if (write_content_with_provider(strm, req, res, boundary, content_type)) {
6947-
res.content_provider_success_ = true;
6948-
} else {
6949-
ret = false;
6950-
}
6967+
if (req.method != "HEAD" && res.content_provider_) {
6968+
if (write_content_with_provider(strm, req, res, boundary, content_type)) {
6969+
res.content_provider_success_ = true;
6970+
} else {
6971+
ret = false;
69516972
}
69526973
}
69536974

6954-
// Log
6955-
output_log(req, res);
6956-
69576975
return ret;
69586976
}
69596977

vendor/cpp-httplib/httplib.h

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#ifndef CPPHTTPLIB_HTTPLIB_H
99
#define CPPHTTPLIB_HTTPLIB_H
1010

11-
#define CPPHTTPLIB_VERSION "0.33.1"
12-
#define CPPHTTPLIB_VERSION_NUM "0x002101"
11+
#define CPPHTTPLIB_VERSION "0.34.0"
12+
#define CPPHTTPLIB_VERSION_NUM "0x002200"
1313

1414
/*
1515
* Platform compatibility check
@@ -1038,6 +1038,32 @@ make_file_provider(const std::string &name, const std::string &filepath,
10381038
return fdp;
10391039
}
10401040

1041+
inline std::pair<size_t, ContentProvider>
1042+
make_file_body(const std::string &filepath) {
1043+
std::ifstream f(filepath, std::ios::binary | std::ios::ate);
1044+
if (!f) { return {0, ContentProvider{}}; }
1045+
auto size = static_cast<size_t>(f.tellg());
1046+
1047+
ContentProvider provider = [filepath](size_t offset, size_t length,
1048+
DataSink &sink) -> bool {
1049+
std::ifstream f(filepath, std::ios::binary);
1050+
if (!f) { return false; }
1051+
f.seekg(static_cast<std::streamoff>(offset));
1052+
if (!f.good()) { return false; }
1053+
char buf[8192];
1054+
while (length > 0) {
1055+
auto to_read = (std::min)(sizeof(buf), length);
1056+
f.read(buf, static_cast<std::streamsize>(to_read));
1057+
auto n = static_cast<size_t>(f.gcount());
1058+
if (n == 0) { break; }
1059+
if (!sink.write(buf, n)) { return false; }
1060+
length -= n;
1061+
}
1062+
return true;
1063+
};
1064+
return {size, std::move(provider)};
1065+
}
1066+
10411067
using ContentReceiverWithProgress = std::function<bool(
10421068
const char *data, size_t data_length, size_t offset, size_t total_length)>;
10431069

@@ -1352,6 +1378,7 @@ class Stream {
13521378
virtual bool is_readable() const = 0;
13531379
virtual bool wait_readable() const = 0;
13541380
virtual bool wait_writable() const = 0;
1381+
virtual bool is_peer_alive() const { return wait_writable(); }
13551382

13561383
virtual ssize_t read(char *ptr, size_t size) = 0;
13571384
virtual ssize_t write(const char *ptr, size_t size) = 0;

0 commit comments

Comments
 (0)