Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ option(LLAMA_TESTS_INSTALL "llama: install tests" ON)

# 3rd party libs
option(LLAMA_OPENSSL "llama: use openssl to support HTTPS" ON)
option(LLAMA_ZLIB "llama: use zlib to support HTTP gzip compression" ON)
option(LLAMA_SUBPROCESS "llama-common: use subprocess, required by server tools and server router mode" ${LLAMA_SUBPROCESS_DEFAULT})
option(LLAMA_LLGUIDANCE "llama-common: include LLGuidance library for structured output in common utils" OFF)

Expand Down
5 changes: 5 additions & 0 deletions tools/server/server-http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ bool server_http_context::init(const common_params & params) {
});

srv->set_error_handler([](const httplib::Request &, httplib::Response & res) {
// a provider-backed response (e.g. proxied from a child server) already
// carries its error body; set_content() on top would conflict with it
if (res.content_provider_) {
return;
}
if (res.status == 404) {
res.set_content(
safe_json_to_str(json {
Expand Down
26 changes: 25 additions & 1 deletion tools/server/server-models.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2483,6 +2483,17 @@ server_http_proxy::server_http_proxy(
msg.content_type = value;
continue;
}
if (lowered == "content-encoding") {
// strip codings the httplib client already decoded; unknown
// codings pass through undecoded and keep the header
bool decoded = false;
#ifdef CPPHTTPLIB_ZLIB_SUPPORT
decoded |= to_lower_copy(string_strip(value)) == "gzip";
#endif
if (decoded) {
continue;
}
}
msg.headers[key] = value;
}
return msg;
Expand Down Expand Up @@ -2525,12 +2536,25 @@ server_http_proxy::server_http_proxy(
{
req.method = method;
req.path = path;
// explicit identity: with the header absent, the httplib client injects
// its own default and transparently decompresses the response
req.set_header("Accept-Encoding", "identity");
for (const auto & [key, value] : headers) {
const auto lowered = to_lower_copy(key);
if (lowered == "accept-encoding") {
// disable Accept-Encoding to avoid compressed responses
continue;
}
if (lowered == "content-encoding") {
// the httplib server already decoded the incoming body; forwarding
// the header with the plain body would make the child decode it again
bool decoded = false;
#ifdef CPPHTTPLIB_ZLIB_SUPPORT
decoded |= to_lower_copy(string_strip(value)) == "gzip";
#endif
if (decoded) {
continue;
}
}
if (lowered == "transfer-encoding") {
// the body is already decoded
continue;
Expand Down
12 changes: 12 additions & 0 deletions vendor/cpp-httplib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ target_compile_definitions(${TARGET} PRIVATE
CPPHTTPLIB_TCP_NODELAY=1
)

if (LLAMA_ZLIB)
find_package(ZLIB)
if (ZLIB_FOUND)
message(STATUS "ZLIB found: ${ZLIB_VERSION_STRING}")
# PUBLIC: the define changes httplib.h declarations, so all consumers must agree
target_compile_definitions(${TARGET} PUBLIC CPPHTTPLIB_ZLIB_SUPPORT)
target_link_libraries(${TARGET} PUBLIC ZLIB::ZLIB)
else()
message(WARNING "ZLIB not found, HTTP gzip compression disabled")
endif()
endif()

set(OPENSSL_NO_ASM ON CACHE BOOL "Disable OpenSSL ASM code when building BoringSSL or LibreSSL")

if (LLAMA_BUILD_BORINGSSL)
Expand Down
Loading