From 7544ba056215504826e1f71ed780d7a4e3cd4572 Mon Sep 17 00:00:00 2001 From: Jacob Nilsson Date: Mon, 23 Mar 2026 10:02:20 +0100 Subject: [PATCH 1/2] http server fixes --- include/netkit-c/sock/sync_sock.h | 1 + include/netkit/http/request_handler.hpp | 499 +++++++++++---------- include/netkit/sock/basic_sync_sock.hpp | 2 +- include/netkit/sock/sync_sock.hpp | 7 +- src/c/sock/sync_sock.cpp | 32 ++ src/sock/openssl/ssl_sync_sock_openssl.cpp | 2 +- src/sock/sync_sock.cpp | 2 +- 7 files changed, 293 insertions(+), 252 deletions(-) diff --git a/include/netkit-c/sock/sync_sock.h b/include/netkit-c/sock/sync_sock.h index a4a4114..f982e18 100644 --- a/include/netkit-c/sock/sync_sock.h +++ b/include/netkit-c/sock/sync_sock.h @@ -27,6 +27,7 @@ NETKIT_C_API netkit_recv_result_t* netkit_recv_result_create(void); NETKIT_C_API void netkit_recv_result_destroy(netkit_recv_result_t* recv_result); NETKIT_C_API netkit_recv_status_t netkit_sync_sock_recv(netkit_sync_sock_t* sock, netkit_recv_result_t* out, int timeout_seconds, const char* match, size_t eof); +NETKIT_C_API netkit_recv_status_t netkit_sync_sock_basic_recv(netkit_sync_sock_t* sock, netkit_recv_result_t* out); NETKIT_C_API void netkit_sync_sock_close(netkit_sync_sock_t* sock); NETKIT_C_API netkit_sock_addr_t* netkit_sync_sock_get_peer(netkit_sync_sock_t* sock); diff --git a/include/netkit/http/request_handler.hpp b/include/netkit/http/request_handler.hpp index 5af38d6..9f2d0f9 100644 --- a/include/netkit/http/request_handler.hpp +++ b/include/netkit/http/request_handler.hpp @@ -139,306 +139,309 @@ namespace netkit::http::server { return; } - if (settings.read_from_session_file == nullptr) { - settings.read_from_session_file = default_read_from_session_file; - } - if (settings.write_to_session_file == nullptr) { - settings.write_to_session_file = default_write_to_session_file; - } + bool close = false; - request req{}; - std::string raw{}; - std::string headers = client_sock->recv(5, "\r\n\r\n").data; - const auto headers_vec = get_headers(headers); - if (headers.empty()) { - return; - } - raw += headers; - - bool is_chunked = false; - std::size_t content_length = 0; - - auto status_line = get_status_line(headers); - req.method = status_line.method; - - std::istringstream header_stream(headers); - std::string line; - while (std::getline(header_stream, line) && line != "\r") { - if (line.starts_with("Transfer-Encoding:") && line.find("chunked") != std::string::npos) { - is_chunked = true; - } else if (line.starts_with("Content-Length:")) { - try { - content_length = std::stoul(line.substr(15)); - } catch (...) { - break; - } - } else if (line.starts_with("Expect:") && line.find("100-continue") != std::string::npos) { - client_sock->send("HTTP/1.1 100 Continue\r\n\r\n"); - } else if (line.starts_with("Expect:") && line.find("100-continue") == std::string::npos) { - std::string response = "HTTP/1.1 417 Expectation Failed\r\n" - "Content-Length: 0\r\n" - "Connection: close\r\n" - "\r\n"; - - client_sock->send(response); - return; - } else if (line.starts_with("Upgrade:") && line.find("websocket") != std::string::npos) { - std::string response = "HTTP/1.1 426 Upgrade Required\r\n" - "Content-Length: 0\r\n" - "Connection: close\r\n" - "\r\n"; - - client_sock->send(response); - return; - } else if (line.starts_with("Connection:") && line.find("close") != std::string::npos) { - std::string response = "HTTP/1.1 200 OK\r\n" - "Content-Length: 0\r\n" - "Connection: close\r\n" - "\r\n"; + while (!close) { + if (settings.read_from_session_file == nullptr) { + settings.read_from_session_file = default_read_from_session_file; + } + if (settings.write_to_session_file == nullptr) { + settings.write_to_session_file = default_write_to_session_file; + } - client_sock->send(response); + request req{}; + std::string raw{}; + std::string headers = client_sock->recv(5, "\r\n\r\n").data; + const auto headers_vec = get_headers(headers); + if (headers.empty()) { return; } - } + raw += headers; + + bool is_chunked = false; + std::size_t content_length = 0; + + auto status_line = get_status_line(headers); + req.method = status_line.method; + + std::istringstream header_stream(headers); + std::string line; + while (std::getline(header_stream, line) && line != "\r") { + if (line.starts_with("Transfer-Encoding:") && line.find("chunked") != std::string::npos) { + is_chunked = true; + } else if (line.starts_with("Content-Length:")) { + try { + content_length = std::stoul(line.substr(15)); + } catch (...) { + break; + } + } else if (line.starts_with("Expect:") && line.find("100-continue") != std::string::npos) { + client_sock->send("HTTP/1.1 100 Continue\r\n\r\n"); + } else if (line.starts_with("Expect:") && line.find("100-continue") == std::string::npos) { + std::string response = "HTTP/1.1 417 Expectation Failed\r\n" + "Content-Length: 0\r\n" + "Connection: close\r\n" + "\r\n"; + + client_sock->send(response); + return; + } else if (line.starts_with("Upgrade:") && line.find("websocket") != std::string::npos) { + std::string response = "HTTP/1.1 426 Upgrade Required\r\n" + "Content-Length: 0\r\n" + "Connection: close\r\n" + "\r\n"; + + client_sock->send(response); + return; + } else if (line.starts_with("Connection:") && line.find("close") != std::string::npos) { + close = true; + } + } - if (is_chunked && (req.method == "POST" || req.method == "PUT" || req.method == "PATCH" || req.method == "DELETE")) { - std::string chunked = client_sock->overflow_bytes(); - client_sock->clear_overflow_bytes(); + if (is_chunked && (req.method == "POST" || req.method == "PUT" || req.method == "PATCH" || req.method == "DELETE")) { + std::string chunked = client_sock->overflow_bytes(); + client_sock->clear_overflow_bytes(); - while (chunked.find("0\r\n\r\n") == std::string::npos) { - auto res = client_sock->recv(5, "", 0); // no eof - if (res.status == sock::recv_status::closed) break; - if (res.status == sock::recv_status::timeout) throw socket_error("recv timeout"); - if (res.data.empty()) continue; - chunked += res.data; - } + while (chunked.find("0\r\n\r\n") == std::string::npos) { + auto res = client_sock->recv(5, "", 0); // no eof + if (res.status == sock::recv_status::closed) break; + if (res.status == sock::recv_status::timeout) close = true; + if (res.data.empty()) continue; + chunked += res.data; + } - std::string decoded = utility::decode_chunked(chunked); - raw = headers + decoded; - req.raw_body = raw; - req.body = decoded; - } else if (req.method == "POST" || req.method == "PUT" || req.method == "PATCH" || req.method == "DELETE") { - std::string body = client_sock->overflow_bytes(); - client_sock->clear_overflow_bytes(); - - while (body.size() < content_length) { - auto res = client_sock->recv(30, "", 0); - if (res.status == sock::recv_status::closed) break; - if (res.status == sock::recv_status::timeout) throw socket_error("recv timeout"); - if (res.data.empty()) continue; - body += res.data; - } + std::string decoded = utility::decode_chunked(chunked); + raw = headers + decoded; + req.raw_body = raw; + req.body = decoded; + } else if (req.method == "POST" || req.method == "PUT" || req.method == "PATCH" || req.method == "DELETE") { + std::string body = client_sock->overflow_bytes(); + client_sock->clear_overflow_bytes(); + + while (body.size() < content_length) { + auto res = client_sock->recv(5, "", 0); + if (res.status == sock::recv_status::closed) break; + if (res.status == sock::recv_status::timeout) close = true; + if (res.data.empty()) continue; + body += res.data; + } - req.body = body; - req.raw_body = headers + body; - } else { - req.raw_body = headers; - } + req.body = body; + req.raw_body = headers + body; + } else { + req.raw_body = headers; + } - if (req.raw_body.empty() || req.raw_body.size() > settings.max_request_size) { - return; - } + if (req.raw_body.empty() || req.raw_body.size() > settings.max_request_size) { + return; + } - req.ip_address = [&]() -> std::string { - if (settings.trust_x_forwarded_for) { - for (const auto& it : headers_vec) { - if (it.first == "X-Forwarded-For") { - auto ips = netkit::utility::split(it.second, ","); - for (const auto& ip : ips) { - if (netkit::network::is_ipv4(ip) || netkit::network::is_ipv6(ip)) { - return ip; + req.ip_address = [&]() -> std::string { + if (settings.trust_x_forwarded_for) { + for (const auto& it : headers_vec) { + if (it.first == "X-Forwarded-For") { + auto ips = netkit::utility::split(it.second, ","); + for (const auto& ip : ips) { + if (netkit::network::is_ipv4(ip) || netkit::network::is_ipv6(ip)) { + return ip; + } } } } } - } - return {}; - }(); + return {}; + }(); - if (req.ip_address.empty()) { - req.ip_address = client_sock->get_peer().get_ip(); - } + if (req.ip_address.empty()) { + req.ip_address = client_sock->get_peer().get_ip(); + } - if (!netkit::network::is_ipv4(req.ip_address) && !netkit::network::is_ipv6(req.ip_address)) { - throw parsing_error("invalid IP address: " + req.ip_address); - } + if (!netkit::network::is_ipv4(req.ip_address) && !netkit::network::is_ipv6(req.ip_address)) { + throw parsing_error("invalid IP address: " + req.ip_address); + } - if (std::ranges::find(settings.blacklisted_ips, req.ip_address) != settings.blacklisted_ips.end()) { - return; - } + if (std::ranges::find(settings.blacklisted_ips, req.ip_address) != settings.blacklisted_ips.end()) { + return; + } - req.version = [&]() { - if (status_line.http_version == "HTTP/1.0") { - return 10; - } else if (status_line.http_version == "HTTP/1.1") { - return 11; + req.version = [&]() { + if (status_line.http_version == "HTTP/1.0") { + return 10; + } else if (status_line.http_version == "HTTP/1.1") { + return 11; + } else { + throw parsing_error("unsupported HTTP version: " + status_line.http_version); + } + }(); + auto full_path = status_line.path; + if (full_path.empty() || full_path[0] != '/') { + throw parsing_error("invalid path: " + full_path); + } + auto query_pos = full_path.find('?'); + if (query_pos != std::string::npos) { + req.endpoint = full_path.substr(0, query_pos); + auto query_str = full_path.substr(query_pos + 1); + req.query = netkit::utility::parse_fields(query_str); } else { - throw parsing_error("unsupported HTTP version: " + status_line.http_version); + req.endpoint = full_path; } - }(); - auto full_path = status_line.path; - if (full_path.empty() || full_path[0] != '/') { - throw parsing_error("invalid path: " + full_path); - } - auto query_pos = full_path.find('?'); - if (query_pos != std::string::npos) { - req.endpoint = full_path.substr(0, query_pos); - auto query_str = full_path.substr(query_pos + 1); - req.query = netkit::utility::parse_fields(query_str); - } else { - req.endpoint = full_path; - } - req.fields = netkit::utility::parse_fields(req.body); - for (const auto& it : headers_vec) { - if (it.first == "Content-Type") { - req.content_type = it.second; - } else if (it.first == "User-Agent") { - req.user_agent = it.second; - } else if (it.first == "Cookie") { - req.cookies = get_cookies_from_request(it.second); + req.fields = netkit::utility::parse_fields(req.body); + for (const auto& it : headers_vec) { + if (it.first == "Content-Type") { + req.content_type = it.second; + } else if (it.first == "User-Agent") { + req.user_agent = it.second; + } else if (it.first == "Cookie") { + req.cookies = get_cookies_from_request(it.second); + } } - } - std::string session_id{}; - bool session_id_found = false; - for (const auto& it : req.cookies) { - if (it.name == settings.session_cookie_name && !it.value.empty() && settings.enable_session) { - session_id = it.value; - session_id_found = true; - break; + std::string session_id{}; + bool session_id_found = false; + for (const auto& it : req.cookies) { + if (it.name == settings.session_cookie_name && !it.value.empty() && settings.enable_session) { + session_id = it.value; + session_id_found = true; + break; + } } - } - bool erase_associated = false; - if (session_id_found) { - std::erase(session_id, '/'); - std::filesystem::path session_file = settings.session_directory + "/session_" + session_id + ".txt"; - req.session = settings.read_from_session_file(session_file.string()); - req.session_id = session_id; + bool erase_associated = false; + if (session_id_found) { + std::erase(session_id, '/'); + std::filesystem::path session_file = settings.session_directory + "/session_" + session_id + ".txt"; + req.session = settings.read_from_session_file(session_file.string()); + req.session_id = session_id; - if (!std::filesystem::exists(session_file)) { - erase_associated = true; - // remove associated session cookies and session cookie from request - for (const auto& it : settings.associated_session_cookies) { + if (!std::filesystem::exists(session_file)) { + erase_associated = true; + // remove associated session cookies and session cookie from request + for (const auto& it : settings.associated_session_cookies) { + req.cookies.erase( + std::remove_if(req.cookies.begin(), req.cookies.end(), + [&it](const cookie& cookie) { + return cookie.name == it; + }), + req.cookies.end() + ); + } req.cookies.erase( std::remove_if(req.cookies.begin(), req.cookies.end(), - [&it](const cookie& cookie) { - return cookie.name == it; + [this, &settings](const cookie& cookie) { + return cookie.name == settings.session_cookie_name; }), req.cookies.end() ); + + req.session.clear(); + req.session_id.clear(); + } else { + req.session = settings.read_from_session_file(session_file.string()); + req.session_id = session_id; } - req.cookies.erase( - std::remove_if(req.cookies.begin(), req.cookies.end(), - [this, &settings](const cookie& cookie) { - return cookie.name == settings.session_cookie_name; - }), - req.cookies.end() - ); - - req.session.clear(); - req.session_id.clear(); - } else { - req.session = settings.read_from_session_file(session_file.string()); - req.session_id = session_id; } - } - auto response = callback(req); - std::stringstream net_response; - net_response << "HTTP/1.1 " << response.http_status << " " << netkit::http::get_message(response.http_status).value_or("Unknown") << "\r\n"; - if (!response.content_type.empty()) net_response << "Content-Type: " << response.content_type << "\r\n"; - if (!response.allow_origin.empty()) net_response << "Access-Control-Allow-Origin: " << response.allow_origin << "\r\n"; - if (!response.location.empty()) { - net_response << "Location: " << response.location << "\r\n"; - } - if (!response.headers.empty()) { - for (const auto& it : response.headers) { - net_response << it.name << ": " << it.data << "\r\n"; + auto response = callback(req); + std::stringstream net_response; + net_response << "HTTP/1.1 " << response.http_status << " " << netkit::http::get_message(response.http_status).value_or("Unknown") << "\r\n"; + if (!response.content_type.empty()) net_response << "Content-Type: " << response.content_type << "\r\n"; + if (!response.allow_origin.empty()) net_response << "Access-Control-Allow-Origin: " << response.allow_origin << "\r\n"; + if (!response.location.empty()) { + net_response << "Location: " << response.location << "\r\n"; + } + if (!response.headers.empty()) { + for (const auto& it : response.headers) { + net_response << it.name << ": " << it.data << "\r\n"; + } + } + if (response.redirection == redirect_type::temporary) { + net_response << "Cache-Control: no-cache\r\n"; + } else if (response.redirection == redirect_type::permanent) { + net_response << "Cache-Control: no-store\r\n"; } - } - if (response.redirection == redirect_type::temporary) { - net_response << "Cache-Control: no-cache\r\n"; - } else if (response.redirection == redirect_type::permanent) { - net_response << "Cache-Control: no-store\r\n"; - } - if (!session_id_found && settings.enable_session) { - session_id = utility::generate_random_string(); - response.cookies.push_back({.name = settings.session_cookie_name, .value = session_id, .expires = 0, .path = "/", .same_site = "Strict", .http_only = true, .secure = settings.session_is_secure}); - } else if (settings.enable_session) { - std::string session_file = settings.session_directory + "/session_" + session_id + ".txt"; - std::unordered_map stored = settings.read_from_session_file(session_file); + if (!session_id_found && settings.enable_session) { + session_id = utility::generate_random_string(); + response.cookies.push_back({.name = settings.session_cookie_name, .value = session_id, .expires = 0, .path = "/", .same_site = "Strict", .http_only = true, .secure = settings.session_is_secure}); + } else if (settings.enable_session) { + std::string session_file = settings.session_directory + "/session_" + session_id + ".txt"; + std::unordered_map stored = settings.read_from_session_file(session_file); - for (const auto& it : response.session) { - stored[it.first] = it.second; + for (const auto& it : response.session) { + stored[it.first] = it.second; + } + + settings.write_to_session_file(session_file, stored); } - settings.write_to_session_file(session_file, stored); - } + for (const auto& it : response.cookies) { + std::string cookie_str = it.name + "=" + it.value + "; "; + if (it.expires != 0) { + cookie_str += "Expires=" + utility::convert_unix_millis_to_gmt(it.expires) + "; "; + } else { + cookie_str += "Expires=session; "; + } + if (it.http_only) { + cookie_str += "HttpOnly; "; + } + if (it.secure) { + cookie_str += "Secure; "; + } + if (!it.path.empty()) { + cookie_str += "Path=" + it.path + "; "; + } + if (!it.domain.empty()) { + cookie_str += "Domain=" + it.domain + "; "; + } + if (!it.same_site.empty() && (it.same_site == "Strict" || it.same_site == "Lax" || it.same_site == "None")) { + cookie_str += "SameSite=" + it.same_site + "; "; + } + for (const auto& attribute : it.attributes) { + cookie_str += attribute + "; "; + } + for (const auto& attribute : it.extra_attributes) { + cookie_str += attribute.first + "=" + attribute.second + "; "; + } - for (const auto& it : response.cookies) { - std::string cookie_str = it.name + "=" + it.value + "; "; - if (it.expires != 0) { - cookie_str += "Expires=" + utility::convert_unix_millis_to_gmt(it.expires) + "; "; - } else { - cookie_str += "Expires=session; "; + net_response << "Set-Cookie: " << cookie_str << "\r\n"; } - if (it.http_only) { - cookie_str += "HttpOnly; "; - } - if (it.secure) { - cookie_str += "Secure; "; - } - if (!it.path.empty()) { - cookie_str += "Path=" + it.path + "; "; - } - if (!it.domain.empty()) { - cookie_str += "Domain=" + it.domain + "; "; - } - if (!it.same_site.empty() && (it.same_site == "Strict" || it.same_site == "Lax" || it.same_site == "None")) { - cookie_str += "SameSite=" + it.same_site + "; "; - } - for (const auto& attribute : it.attributes) { - cookie_str += attribute + "; "; - } - for (const auto& attribute : it.extra_attributes) { - cookie_str += attribute.first + "=" + attribute.second + "; "; + + if (erase_associated) { + for (const auto& it : settings.associated_session_cookies) { + response.delete_cookies.push_back(it); + } } - net_response << "Set-Cookie: " << cookie_str << "\r\n"; - } + for (const auto& it : response.delete_cookies) { + std::string cookie_str = it + "=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; "; + net_response << "Set-Cookie: " << cookie_str << "\r\n"; + } - if (erase_associated) { - for (const auto& it : settings.associated_session_cookies) { - response.delete_cookies.push_back(it); + if (response.stop) { + return; } - } - for (const auto& it : response.delete_cookies) { - std::string cookie_str = it + "=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; "; - net_response << "Set-Cookie: " << cookie_str << "\r\n"; - } + for (const auto& it : response.headers) { + net_response << it.name << ": " << it.data << "\r\n"; + } - if (response.stop) { - return; - } + if (close) { + net_response << "Connection: close\r\n"; + } - for (const auto& it : response.headers) { - net_response << it.name << ": " << it.data << "\r\n"; - } + if (!response.body.empty()) { + net_response << "Content-Length: " << response.body.size() << "\r\n"; + } else { + net_response << "Content-Length: 0\r\n"; + } - net_response << "Connection: close\r\n"; + net_response << "\r\n"; + net_response << response.body; - if (!response.body.empty()) { - net_response << "Content-Length: " << response.body.size() << "\r\n"; + client_sock->send(net_response.str()); } - net_response << "\r\n"; - net_response << response.body; - - client_sock->send(net_response.str()); client_sock->close(); } }; diff --git a/include/netkit/sock/basic_sync_sock.hpp b/include/netkit/sock/basic_sync_sock.hpp index 34fec54..7dae063 100644 --- a/include/netkit/sock/basic_sync_sock.hpp +++ b/include/netkit/sock/basic_sync_sock.hpp @@ -37,7 +37,7 @@ namespace netkit::sock { [[nodiscard]] virtual recv_result recv(int timeout_seconds, const std::string& match) = 0; [[nodiscard]] virtual recv_result recv(int timeout_seconds, const std::string& match, size_t eof) = 0; [[nodiscard]] virtual recv_result recv(int timeout_seconds, size_t eof) = 0; - [[nodiscard]] virtual recv_result primitive_recv() = 0; + [[nodiscard]] virtual recv_result recv() = 0; [[nodiscard]] virtual std::string overflow_bytes() const = 0; virtual addr& get_addr() = 0; [[nodiscard]] virtual const addr& get_addr() const = 0; diff --git a/include/netkit/sock/sync_sock.hpp b/include/netkit/sock/sync_sock.hpp index c29c5e9..bb99e75 100644 --- a/include/netkit/sock/sync_sock.hpp +++ b/include/netkit/sock/sync_sock.hpp @@ -124,7 +124,12 @@ namespace netkit::sock { * @return The received data as a sock_recv_result object. */ [[nodiscard]] recv_result recv(int timeout_seconds, const std::string& match, size_t eof) override; - [[nodiscard]] recv_result primitive_recv() override; + /** + * @brief Receive data from the server. + * @note This is a recv() implementation that behaves like a Unix recv() call would. + * @return The received data as a sock_recv_result object. + */ + [[nodiscard]] recv_result recv() override; /* @brief Receive data from the server. * @param timeout_seconds The timeout in seconds (-1 means wait indefinitely). diff --git a/src/c/sock/sync_sock.cpp b/src/c/sock/sync_sock.cpp index ef858da..59b0b29 100644 --- a/src/c/sock/sync_sock.cpp +++ b/src/c/sock/sync_sock.cpp @@ -304,6 +304,38 @@ extern "C" NETKIT_C_API netkit_recv_status_t netkit_sync_sock_recv(netkit_sync_s } } +extern "C" NETKIT_C_API netkit_recv_status_t netkit_sync_sock_basic_recv(netkit_sync_sock_t* sock, netkit_recv_result_t* out) { + if (!sock || !out) { + return RECV_ERROR; + } + + try { + auto ret = sock->impl->recv(); + delete[] out->data; + + out->size = ret.data.size(); + out->data = new char[out->size + 1]; + + std::memcpy(out->data, ret.data.data(), out->size); + out->data[out->size] = '\0'; + + switch (ret.status) { + case netkit::sock::recv_status::success: + return RECV_SUCCESS; + case netkit::sock::recv_status::timeout: + return RECV_TIMEOUT; + case netkit::sock::recv_status::closed: + return RECV_CLOSED; + default: + return RECV_ERROR; + } + } catch (const std::exception& e) { + return RECV_ERROR; + } catch (...) { + return RECV_ERROR; + } +} + extern "C" NETKIT_C_API void netkit_sync_sock_close(netkit_sync_sock_t* sock) { if (!sock) { return; diff --git a/src/sock/openssl/ssl_sync_sock_openssl.cpp b/src/sock/openssl/ssl_sync_sock_openssl.cpp index 93291bb..36f7bc9 100644 --- a/src/sock/openssl/ssl_sync_sock_openssl.cpp +++ b/src/sock/openssl/ssl_sync_sock_openssl.cpp @@ -345,7 +345,7 @@ void netkit::sock::ssl_sync_sock::drain_write_bio() const { } void netkit::sock::ssl_sync_sock::feed_read_bio_blocking() const { - auto res = underlying_sock_->primitive_recv(); + auto res = underlying_sock_->recv(); if (res.status == sock::recv_status::closed) { if (!handshake_complete_) { diff --git a/src/sock/sync_sock.cpp b/src/sock/sync_sock.cpp index f1e4103..5614c7a 100644 --- a/src/sock/sync_sock.cpp +++ b/src/sock/sync_sock.cpp @@ -514,7 +514,7 @@ netkit::sock::recv_result netkit::sock::sync_sock::recv(const int timeout_second } } -netkit::sock::recv_result netkit::sock::sync_sock::primitive_recv() { +netkit::sock::recv_result netkit::sock::sync_sock::recv() { for (;;) { char buf[8192]; ssize_t n = ::recv(this->sockfd, buf, sizeof(buf), 0); From 15448c5b870c16dbebfdc6cb003f1eccdd009927 Mon Sep 17 00:00:00 2001 From: Jacob Nilsson Date: Tue, 24 Mar 2026 10:02:55 +0100 Subject: [PATCH 2/2] fix --- src/sock/sync_sock.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sock/sync_sock.cpp b/src/sock/sync_sock.cpp index 5614c7a..37959df 100644 --- a/src/sock/sync_sock.cpp +++ b/src/sock/sync_sock.cpp @@ -619,7 +619,7 @@ netkit::sock::recv_result netkit::sock::sync_sock::recv(const int timeout_second } } -netkit::sock::recv_result netkit::sock::sync_sock::primitive_recv() { +netkit::sock::recv_result netkit::sock::sync_sock::recv() { constexpr size_t buffer_size = 8192; char buf[buffer_size]; @@ -679,4 +679,4 @@ void netkit::sock::sync_sock::close() { #endif [[nodiscard]] netkit::sock::addr netkit::sock::sync_sock::get_peer() const { return netkit::sock::get_peer(this->sockfd); -} \ No newline at end of file +}