Loading src/http.cpp +34 −5 Original line number Diff line number Diff line Loading @@ -218,8 +218,10 @@ netplus::TlsSessionCache& libhttppp::HttpClient::tlsSessionCache() { return cache; } libhttppp::HttpClient::HttpClient(const HttpUrl& desturl, int vers) libhttppp::HttpClient::HttpClient(const HttpUrl& desturl, int vers, int timeoutSec) : _url(desturl), _vers(vers){ _recvTimeoutSec = timeoutSec; _sendTimeoutSec = timeoutSec; try { if(vers == 3) { if (!tryHttp3First()) { Loading Loading @@ -382,12 +384,40 @@ void libhttppp::HttpClient::resetConnection(){ } } else { _cltsock = std::make_unique<netplus::tcp>(-1); _cltsock->connect(_url.getHost(), _url.getPort(), false); _cltsock->setNonBlock(); _connectTcp(*_cltsock); _isH2 = false; } } // Plain-TCP connect bounded by _recvTimeoutSec instead of the OS default // connect timeout (which can be minutes) -- a fully unreachable host (dead // container, wrong IP, dropped SYNs) would otherwise hang the caller far // longer than any configured setTimeout() would suggest. void libhttppp::HttpClient::_connectTcp(netplus::socket &sock) { try { sock.connect(_url.getHost(), _url.getPort(), true); // Connected immediately (rare for TCP, but handle it) return; } catch (netplus::NetException &e) { if (e.getErrorType() != netplus::NetException::Note) throw; } if (!_sw.waitWrite(sock, _recvTimeoutSec * 1000)) { HTTPException he; he[HTTPException::Error] << "tcp connect timeout after " << _recvTimeoutSec << "s"; throw he; } int err = 0; socklen_t errlen = sizeof(err); if (::getsockopt(sock.fd(), SOL_SOCKET, SO_ERROR, &err, &errlen) != 0 || err != 0) { HTTPException he; he[HTTPException::Error] << "tcp connect failed: " << strerror(err); throw he; } } void libhttppp::HttpClient::reconnect(){ // Reset HTTP/2 and HTTP/3 connection state on reconnect Loading Loading @@ -462,8 +492,7 @@ void libhttppp::HttpClient::reconnect(){ } } else { _cltsock = std::make_unique<netplus::tcp>(-1); _cltsock->connect(_url.getHost(), _url.getPort(), false); _cltsock->setNonBlock(); _connectTcp(*_cltsock); _isH2 = false; } } Loading src/http.h +9 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,11 @@ namespace libhttppp { class HttpClient{ public: HttpClient( const HttpUrl &desturl, int vers = 2); // timeoutSec bounds the constructor's own eager connection attempt // (see resetConnection()) in addition to being the initial value // setTimeout() would otherwise set afterward -- too late to affect // that first connect. HttpClient( const HttpUrl &desturl, int vers = 2, int timeoutSec = 60); ~HttpClient()=default; void reconnect(); void setTimeout(int timeout_sec); Loading Loading @@ -146,6 +150,10 @@ namespace libhttppp { static netplus::TlsSessionCache& tlsSessionCache(); private: void _ensureConnected(); // Non-blocking connect + waitWrite, bounded by _recvTimeoutSec, so an // unreachable host (dead container, wrong IP, dropped SYNs) fails // within the configured timeout instead of the OS default (minutes). void _connectTcp(netplus::socket &sock); bool tryHttp3First(); int readchunk(const char *data,int datasize,int &pos); Loading Loading
src/http.cpp +34 −5 Original line number Diff line number Diff line Loading @@ -218,8 +218,10 @@ netplus::TlsSessionCache& libhttppp::HttpClient::tlsSessionCache() { return cache; } libhttppp::HttpClient::HttpClient(const HttpUrl& desturl, int vers) libhttppp::HttpClient::HttpClient(const HttpUrl& desturl, int vers, int timeoutSec) : _url(desturl), _vers(vers){ _recvTimeoutSec = timeoutSec; _sendTimeoutSec = timeoutSec; try { if(vers == 3) { if (!tryHttp3First()) { Loading Loading @@ -382,12 +384,40 @@ void libhttppp::HttpClient::resetConnection(){ } } else { _cltsock = std::make_unique<netplus::tcp>(-1); _cltsock->connect(_url.getHost(), _url.getPort(), false); _cltsock->setNonBlock(); _connectTcp(*_cltsock); _isH2 = false; } } // Plain-TCP connect bounded by _recvTimeoutSec instead of the OS default // connect timeout (which can be minutes) -- a fully unreachable host (dead // container, wrong IP, dropped SYNs) would otherwise hang the caller far // longer than any configured setTimeout() would suggest. void libhttppp::HttpClient::_connectTcp(netplus::socket &sock) { try { sock.connect(_url.getHost(), _url.getPort(), true); // Connected immediately (rare for TCP, but handle it) return; } catch (netplus::NetException &e) { if (e.getErrorType() != netplus::NetException::Note) throw; } if (!_sw.waitWrite(sock, _recvTimeoutSec * 1000)) { HTTPException he; he[HTTPException::Error] << "tcp connect timeout after " << _recvTimeoutSec << "s"; throw he; } int err = 0; socklen_t errlen = sizeof(err); if (::getsockopt(sock.fd(), SOL_SOCKET, SO_ERROR, &err, &errlen) != 0 || err != 0) { HTTPException he; he[HTTPException::Error] << "tcp connect failed: " << strerror(err); throw he; } } void libhttppp::HttpClient::reconnect(){ // Reset HTTP/2 and HTTP/3 connection state on reconnect Loading Loading @@ -462,8 +492,7 @@ void libhttppp::HttpClient::reconnect(){ } } else { _cltsock = std::make_unique<netplus::tcp>(-1); _cltsock->connect(_url.getHost(), _url.getPort(), false); _cltsock->setNonBlock(); _connectTcp(*_cltsock); _isH2 = false; } } Loading
src/http.h +9 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,11 @@ namespace libhttppp { class HttpClient{ public: HttpClient( const HttpUrl &desturl, int vers = 2); // timeoutSec bounds the constructor's own eager connection attempt // (see resetConnection()) in addition to being the initial value // setTimeout() would otherwise set afterward -- too late to affect // that first connect. HttpClient( const HttpUrl &desturl, int vers = 2, int timeoutSec = 60); ~HttpClient()=default; void reconnect(); void setTimeout(int timeout_sec); Loading Loading @@ -146,6 +150,10 @@ namespace libhttppp { static netplus::TlsSessionCache& tlsSessionCache(); private: void _ensureConnected(); // Non-blocking connect + waitWrite, bounded by _recvTimeoutSec, so an // unreachable host (dead container, wrong IP, dropped SYNs) fails // within the configured timeout instead of the OS default (minutes). void _connectTcp(netplus::socket &sock); bool tryHttp3First(); int readchunk(const char *data,int datasize,int &pos); Loading