mirror of
https://github.com/LostRuins/koboldcpp.git
synced 2026-10-03 11:35:46 +00:00
vendor : update cpp-httplib to 0.57.0 (#29214)
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
parent
ec91ab5add
commit
6f41ac59e0
3 changed files with 77 additions and 25 deletions
|
|
@ -5,7 +5,7 @@ import os
|
|||
import sys
|
||||
import subprocess
|
||||
|
||||
HTTPLIB_VERSION = "refs/tags/v0.56.0"
|
||||
HTTPLIB_VERSION = "refs/tags/v0.57.0"
|
||||
|
||||
# used by examples/gguf-hash, these repos have no release tag, so we pin a commit
|
||||
XXHASH_COMMIT = "9f465f1ea932d6ad9a26cd77496311ffa544cd68"
|
||||
|
|
|
|||
95
vendor/cpp-httplib/httplib.cpp
vendored
95
vendor/cpp-httplib/httplib.cpp
vendored
|
|
@ -1248,6 +1248,13 @@ bool parse_trailers(stream_line_reader &line_reader, Headers &dest,
|
|||
// to look up.
|
||||
split(trailer_header.data(), trailer_header.data() + trailer_header.size(),
|
||||
',', [&](const char *b, const char *e) {
|
||||
// A legitimate message declares only a handful of trailers. Cap the
|
||||
// set so a peer cannot grow it without bound: an oversized set only
|
||||
// arises from an attempt to force many colliding names into
|
||||
// quadratic lookups (case_ignore::hash is unkeyed).
|
||||
if (declared_trailers.size() >= CPPHTTPLIB_HEADER_MAX_COUNT) {
|
||||
return;
|
||||
}
|
||||
std::string key(b, e);
|
||||
if (prohibited_trailers.find(key) == prohibited_trailers.end()) {
|
||||
declared_trailers.insert(key);
|
||||
|
|
@ -1258,6 +1265,8 @@ bool parse_trailers(stream_line_reader &line_reader, Headers &dest,
|
|||
size_t trailer_header_count = 0;
|
||||
while (strcmp(line_reader.ptr(), "\r\n") != 0) {
|
||||
if (line_reader.size() > CPPHTTPLIB_HEADER_MAX_LENGTH) { return false; }
|
||||
// Count every received trailer field, not only the declared ones stored in
|
||||
// dest, so undeclared fields cannot keep this loop running past the limit.
|
||||
if (trailer_header_count >= CPPHTTPLIB_HEADER_MAX_COUNT) { return false; }
|
||||
|
||||
constexpr auto line_terminator_len = 2;
|
||||
|
|
@ -1270,12 +1279,13 @@ bool parse_trailers(stream_line_reader &line_reader, Headers &dest,
|
|||
if (declared_trailers.find(key) !=
|
||||
declared_trailers.end()) {
|
||||
dest.emplace(key, val);
|
||||
trailer_header_count++;
|
||||
}
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
trailer_header_count++;
|
||||
|
||||
if (!line_reader.getline()) { return false; }
|
||||
}
|
||||
|
||||
|
|
@ -8626,7 +8636,10 @@ bool Server::write_response_core(Stream &strm, bool close_connection,
|
|||
// Prepare additional headers
|
||||
if (close_connection ||
|
||||
detail::has_header_token(req.headers, "Connection", "close") ||
|
||||
400 <= res.status) { // Don't leave connections open after errors
|
||||
400 <= res.status || // Don't leave connections open after errors
|
||||
// The client withholds the body until `100 Continue`, which was never
|
||||
// sent, so whether and when the body follows is unknown.
|
||||
(req.expect_100_continue_pending_ && detail::has_framed_body(req))) {
|
||||
res.set_header("Connection", "close");
|
||||
} else {
|
||||
std::string s = "timeout=";
|
||||
|
|
@ -8877,6 +8890,13 @@ bool Server::read_content_core(
|
|||
}
|
||||
#endif
|
||||
|
||||
// The client is waiting for this before it sends the body.
|
||||
if (req.expect_100_continue_pending_) {
|
||||
req.expect_100_continue_pending_ = false;
|
||||
detail::write_response_line(strm, StatusCode::Continue_100);
|
||||
strm.write("\r\n");
|
||||
}
|
||||
|
||||
if (!detail::read_content(strm, req, payload_max_length_, res.status, nullptr,
|
||||
out, true)) {
|
||||
return false;
|
||||
|
|
@ -9714,19 +9734,20 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
|
|||
// case-insensitive, and a 100-continue expectation in an HTTP/1.0 request
|
||||
// must be ignored. An expectation we do not recognize is left alone; the
|
||||
// 417 the section allows for one is a MAY, not a requirement.
|
||||
//
|
||||
// `100 Continue` itself is deferred until the body is actually read (see
|
||||
// read_content_core), so a request rejected by a later handler never
|
||||
// invites the client to send a body nobody will read.
|
||||
if (req.version != "HTTP/1.0" &&
|
||||
detail::has_header_token(req.headers, "Expect", "100-continue")) {
|
||||
int status = StatusCode::Continue_100;
|
||||
if (expect_100_continue_handler_) {
|
||||
status = expect_100_continue_handler_(req, res);
|
||||
}
|
||||
switch (status) {
|
||||
case StatusCode::Continue_100:
|
||||
case StatusCode::ExpectationFailed_417:
|
||||
detail::write_response_line(strm, status);
|
||||
strm.write("\r\n");
|
||||
break;
|
||||
default:
|
||||
if (status == StatusCode::Continue_100) {
|
||||
req.expect_100_continue_pending_ = true;
|
||||
} else {
|
||||
if (res.status == -1) { res.status = status; }
|
||||
connection_closed = true;
|
||||
return write_response(strm, true, req, res);
|
||||
}
|
||||
|
|
@ -9739,18 +9760,25 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
|
|||
};
|
||||
|
||||
// WebSocket upgrade
|
||||
// Check pre_routing_handler_ before upgrading so that authentication
|
||||
// and other middleware can reject the request with an HTTP response
|
||||
// (e.g., 401) before the protocol switches.
|
||||
// Run pre_routing_handler_ and pre_request_handler_ before upgrading so
|
||||
// that authentication and other middleware can reject the request with an
|
||||
// HTTP response (e.g., 401) before the protocol switches.
|
||||
if (detail::is_websocket_upgrade(req)) {
|
||||
if (pre_routing_handler_ &&
|
||||
pre_routing_handler_(req, res) == HandlerResponse::Handled) {
|
||||
if (res.status == -1) { res.status = StatusCode::OK_200; }
|
||||
return write_response(strm, close_connection, req, res);
|
||||
return write_response_with_content(strm, close_connection, req, res);
|
||||
}
|
||||
// Find matching WebSocket handler
|
||||
for (const auto &entry : websocket_handlers_) {
|
||||
if (entry.matcher->match(req)) {
|
||||
req.matched_route = entry.matcher->pattern();
|
||||
if (pre_request_handler_ &&
|
||||
pre_request_handler_(req, res) == HandlerResponse::Handled) {
|
||||
if (res.status == -1) { res.status = StatusCode::OK_200; }
|
||||
return write_response_with_content(strm, close_connection, req, res);
|
||||
}
|
||||
|
||||
// Compute accept key
|
||||
auto client_key = req.get_header_value("Sec-WebSocket-Key");
|
||||
auto accept_key = detail::websocket_accept_key(client_key);
|
||||
|
|
@ -10610,22 +10638,45 @@ ssize_t ChunkedDecoder::read_payload(char *buf, size_t len,
|
|||
stream_line_reader lr(strm, line_buf, sizeof(line_buf));
|
||||
if (!lr.getline()) { return -1; }
|
||||
|
||||
// Everything below is bounded by eol rather than by the buffer's NUL, so
|
||||
// the line terminator is never mistaken for line content.
|
||||
const char *eol = lr.ptr() + lr.size();
|
||||
if (lr.end_with_crlf()) {
|
||||
eol -= 2;
|
||||
} else if (eol != lr.ptr() && eol[-1] == '\n') {
|
||||
// Only reachable under CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR, where
|
||||
// getline() ends the line on a bare LF. That LF is the terminator, so it
|
||||
// has to come off here or the check below would reject the line.
|
||||
eol -= 1;
|
||||
}
|
||||
|
||||
// RFC 9112 §7.1: chunk-size = 1*HEXDIG
|
||||
const char *p = lr.ptr();
|
||||
int v = 0;
|
||||
if (!is_hex(*p, v)) { return -1; }
|
||||
if (p == eol || !is_hex(*p, v)) { return -1; }
|
||||
|
||||
size_t chunk_len = 0;
|
||||
constexpr size_t chunk_len_max = (std::numeric_limits<size_t>::max)();
|
||||
for (; is_hex(*p, v); ++p) {
|
||||
for (; p < eol && is_hex(*p, v); ++p) {
|
||||
if (chunk_len > (chunk_len_max >> 4)) { return -1; }
|
||||
chunk_len = (chunk_len << 4) | static_cast<size_t>(v);
|
||||
}
|
||||
|
||||
while (is_space_or_tab(*p)) {
|
||||
while (p < eol && is_space_or_tab(*p)) {
|
||||
++p;
|
||||
}
|
||||
if (*p != '\0' && *p != ';' && *p != '\r' && *p != '\n') { return -1; }
|
||||
|
||||
// RFC 9112 §7.1.1: only a chunk-ext may sit between the size and the line
|
||||
// terminator, and it is built from tokens and quoted-strings, so it never
|
||||
// holds a CR, LF or any other control character. getline() reads up to the
|
||||
// CRLF, so a bare LF left in here would be swallowed as extension text
|
||||
// while an intermediary that ends the line on it delimits the chunks
|
||||
// differently, and the two disagree on where the body ends (request
|
||||
// smuggling).
|
||||
if (p < eol && *p != ';') { return -1; }
|
||||
for (; p < eol; ++p) {
|
||||
if (!is_space_or_tab(*p) && !fields::is_field_vchar(*p)) { return -1; }
|
||||
}
|
||||
|
||||
if (chunk_len == 0) {
|
||||
chunk_remaining = 0;
|
||||
|
|
@ -14650,11 +14701,11 @@ void shutdown(session_t session, bool graceful) {
|
|||
|
||||
auto ssl = static_cast<SSL *>(session);
|
||||
if (graceful) {
|
||||
// First call sends close_notify
|
||||
if (SSL_shutdown(ssl) == 0) {
|
||||
// Second call waits for peer's close_notify
|
||||
SSL_shutdown(ssl);
|
||||
}
|
||||
// Send close_notify without waiting for the peer's. The connection is
|
||||
// closed right after this, so a unidirectional shutdown is enough, and an
|
||||
// idle peer that never answers would otherwise hold this thread until the
|
||||
// read timeout. The other backends do not wait either.
|
||||
SSL_shutdown(ssl);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
5
vendor/cpp-httplib/httplib.h
vendored
5
vendor/cpp-httplib/httplib.h
vendored
|
|
@ -8,8 +8,8 @@
|
|||
#ifndef CPPHTTPLIB_HTTPLIB_H
|
||||
#define CPPHTTPLIB_HTTPLIB_H
|
||||
|
||||
#define CPPHTTPLIB_VERSION "0.56.0"
|
||||
#define CPPHTTPLIB_VERSION_NUM "0x003800"
|
||||
#define CPPHTTPLIB_VERSION "0.57.0"
|
||||
#define CPPHTTPLIB_VERSION_NUM "0x003900"
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0A00
|
||||
|
|
@ -1756,6 +1756,7 @@ struct Request {
|
|||
|
||||
// private members...
|
||||
bool body_consumed_ = false;
|
||||
bool expect_100_continue_pending_ = false;
|
||||
size_t redirect_count_ = CPPHTTPLIB_REDIRECT_MAX_COUNT;
|
||||
size_t content_length_ = 0;
|
||||
ContentProvider content_provider_;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue