Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to properly timeout #2034

Open
marcovc opened this issue Jan 28, 2025 · 5 comments
Open

How to properly timeout #2034

marcovc opened this issue Jan 28, 2025 · 5 comments

Comments

@marcovc
Copy link

marcovc commented Jan 28, 2025

Hi,

I've finally had some time to investigate the issue reported here, and created a small example:

A client that wants to have a reply in at most 2100 ms:

#include <httplib.h>

int main()
{

  httplib::Client http_client("http://127.0.0.1:8082");
  auto timeout = std::chrono::milliseconds{2100};
  http_client.set_connection_timeout(timeout);
  http_client.set_read_timeout(timeout);
  http_client.set_write_timeout(timeout);
  auto start = std::chrono::steady_clock::now();
  http_client.Get("/");
  auto end = std::chrono::steady_clock::now();
  auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
  std::cout << "Elapsed time: " << elapsed.count() << "ms\n";
}

A simple server to test (in python):

from http.server import BaseHTTPRequestHandler, HTTPServer
import time

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == "/":
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.end_headers()
            for i in range(5):
                time.sleep(1)
                self.wfile.write(f"Response part {i+1}\n".encode('utf-8'))            
        else:
            self.send_response(404)
            self.end_headers()

def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
    server_address = ('', 8082)
    httpd = server_class(server_address, handler_class)
    print("Starting httpd server on port 8082...")
    httpd.serve_forever()

if __name__ == "__main__":
    run()

It will print something like

Elapsed time: 5001ms

while I was expecting something close to

Elapsed time: 2100ms

Perhaps there is another way to set a timeout for the request?

Thanks

@TalkySafe143
Copy link

Hi, the piece of code that set the socket option is this:

cpp-httplib/httplib.h

Lines 3744 to 3748 in 282f2fe

timeval tv;
tv.tv_sec = static_cast<long>(read_timeout_sec);
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(read_timeout_usec);
setsockopt(sock2, SOL_SOCKET, SO_RCVTIMEO,
reinterpret_cast<const void *>(&tv), sizeof(tv));

The socket use SO_RCVTIMEO and SO_SNDTIMEO for setting the timeout using timeval struct. But, the documentation of setsockopt using SO_RCVTIMEO says:

In the current implementation, this timer is restarted each time additional data are received by the protocol, and thus the limit is in effect an inactivity timer.

Your python server is writing a response to the socket each second five times, if you modify the server to sleep $5&lt;$ seconds, you will have your timeout as you expect.

Maybe could be a good feature make a timeout different to the setsockopt implementation to expect that kind of results.

@TalkySafe143
Copy link

It could be good that @yhirose mention this on the README file 💯

@marcovc
Copy link
Author

marcovc commented Feb 3, 2025 via email

@yhirose
Copy link
Owner

yhirose commented Feb 6, 2025

@marcovc could you clarify the status of this issue? If it's not an issue on cpp-httplib, I would like to close it.

@marcovc
Copy link
Author

marcovc commented Feb 6, 2025

Hi,

This is my second and last attempt to point out that there is no way to set a global timeout in httplib (client). If you feel that is not an important feature to have in your library, feel free to close it.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants