From 58602a28d2c92b603208f3e01c14c169d28cc7b0 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 2 Jul 2026 00:53:24 +0300 Subject: yhttpd: port ychat fixes, get it building + stable in Docker (task 9s0) Ports the ychat revival fixes (unsigned/size_t npos truncation, ofstream == NULL, tool::trim OOB, CGI popen -> execve, www.yChat.org links, g++ version gate, config.pl -I., NCURSES/CLI-disabled build) so yhttpd builds on modern GCC in a Rocky Linux 9 container, plus yhttpd-specific fixes found while verifying it under concurrent load: - listen() backlog was hardcoded to 1; bumped to SOMAXCONN. - sock::_close() closed sockets with unread request bytes still in the kernel receive buffer (read_http() only reads the GET line), so Linux sent an abortive RST instead of a FIN, racing the client's read of the response ("connection reset by peer" even though it was delivered). Fixed with a non-blocking, bounded drain before close() - confirmed via tcpdump: RSTs on every response before, zero after, across 140+ requests / concurrent bursts of 20. - Removed a duplicate _make_server_socket() call in start() (wrap.cpp's init_wrapper() already makes it before start() runs) that leaked a fd and would have double-initialized SSL if OPENSSL is ever enabled; caught by fresh-context review, documented honestly in DOCKER.md. - src/configure's dependency-checker predates 64-bit multilib distros (only checked /usr/lib, never /usr/lib64) and was missing an ncur move-aside entry for the NCURSES-disabled build. Added Dockerfile/.dockerignore/DOCKER.md documenting the build, the fixes, and the one known-but-unfixed landmine (a SIGILL heap corruption in sock::_close that reproduces on newer host GCC/glibc but not in the container - latent, not fixed). Co-Authored-By: Claude Sonnet 5 --- yhttpd/src/reqp.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'yhttpd/src/reqp.cpp') diff --git a/yhttpd/src/reqp.cpp b/yhttpd/src/reqp.cpp index df9de5d..4ce30d9 100644 --- a/yhttpd/src/reqp.cpp +++ b/yhttpd/src/reqp.cpp @@ -22,7 +22,7 @@ void reqp::get_request_parameters( string s_parameters, map& map_params ) { string s_tmp; - unsigned i_pos, i_pos2; + size_t i_pos, i_pos2; while( (i_pos = s_parameters.find("&")) != string::npos ) { @@ -46,7 +46,7 @@ reqp::get_request_parameters( string s_parameters, map& map_param string reqp::get_url( string s_req, map &map_params, int& i_postpayloadoffset ) { - unsigned i_pos, i_pos2; + size_t i_pos, i_pos2; string s_vars( "" ); string s_ret; int i_req; @@ -111,7 +111,6 @@ reqp::get_url( string s_req, map &map_params, int& i_postpayload if ( s_ret.empty() ) s_ret = wrap::CONF->get_elem( "httpd.startsite" ); - else s_ret = remove_dots(s_ret); @@ -211,7 +210,7 @@ reqp::url_decode( string s_url ) string reqp::get_from_header( string s_req, string s_hdr ) { - unsigned i_pos[2]; + size_t i_pos[2]; if ( (i_pos[0] = s_req.find( s_hdr, 0 )) == string::npos ) return ""; @@ -274,7 +273,7 @@ string reqp::remove_dots( string s_ret ) { // remove ".." from the request. - unsigned i_pos; + size_t i_pos; if ( (i_pos = s_ret.find( ".." )) != string::npos ) return remove_dots(s_ret.substr(0, i_pos)); -- cgit v1.2.3