]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
HTTP storage: Implement timeout support (#896)
authorGregor Jasny <gregor.jasny@logmein.com>
Wed, 14 Jul 2021 09:36:48 +0000 (11:36 +0200)
committerGitHub <noreply@github.com>
Wed, 14 Jul 2021 09:36:48 +0000 (11:36 +0200)
Closes #888.

doc/MANUAL.adoc
src/storage/secondary/HttpStorage.cpp
src/storage/secondary/HttpStorage.hpp

index 6cd2959081a314cfa046cdc487c17b5d2336a93f..87ad7449392847c96a7325b9d303a2ada8d76acc 100644 (file)
@@ -947,9 +947,13 @@ Examples:
 * `http://localhost:8080/`
 * `http://someusername:p4ssw0rd@example.com/cache`
 
+Optional attributes:
+
+* *connect-timeout*: Timeout (in ms) for network connection. The default is 100.
+* *operation-timeout*: Timeout (in ms) for HTTP requests. The default is 10000.
+
 Known issues and limitations:
 
-* There are no HTTP timeouts implemented or configured.
 * HTTPS is not yet supported.
 * URLs containing IPv6 addresses like `http://[::1]/` are not supported.
 
index 3d16e42b4ca10812bd29c2d82bfe4385aaacd718..07c35f93cf255492d1677c0aa72bd0161be6d62a 100644 (file)
@@ -35,6 +35,9 @@ namespace secondary {
 
 namespace {
 
+const auto DEFAULT_CONNECT_TIMEOUT = std::chrono::milliseconds{100};
+const auto DEFAULT_OPERATION_TIMEOUT = std::chrono::milliseconds{10000};
+
 nonstd::string_view
 to_string(const httplib::Error error)
 {
@@ -107,19 +110,48 @@ make_client(const Url& url)
   return client;
 }
 
+std::chrono::milliseconds
+parse_timeout_attribute(const AttributeMap& attributes,
+                        const std::string& name,
+                        const std::chrono::milliseconds default_value)
+{
+  const auto it = attributes.find(name);
+  if (it == attributes.end()) {
+    return default_value;
+  } else {
+    auto timeout_in_ms =
+      Util::parse_unsigned(it->second, 1, 1000 * 3600, "timeout");
+    return std::chrono::milliseconds{timeout_in_ms};
+  }
+}
+
 } // namespace
 
-HttpStorage::HttpStorage(const Url& url, const AttributeMap&)
+HttpStorage::HttpStorage(const Url& url, const AttributeMap& attributes)
   : m_url_path(get_url_path(url)),
     m_http_client(make_client(url))
 {
   m_http_client->set_default_headers(
     {{"User-Agent", FMT("{}/{}", CCACHE_NAME, CCACHE_VERSION)}});
   m_http_client->set_keep_alive(true);
+  configure_timeouts(attributes);
 }
 
 HttpStorage::~HttpStorage() = default;
 
+void
+HttpStorage::configure_timeouts(const AttributeMap& attributes)
+{
+  const auto connection_timeout = parse_timeout_attribute(
+    attributes, "connect-timeout", DEFAULT_CONNECT_TIMEOUT);
+  const auto operation_timeout = parse_timeout_attribute(
+    attributes, "operation-timeout", DEFAULT_OPERATION_TIMEOUT);
+
+  m_http_client->set_connection_timeout(connection_timeout);
+  m_http_client->set_read_timeout(operation_timeout);
+  m_http_client->set_write_timeout(operation_timeout);
+}
+
 nonstd::expected<nonstd::optional<std::string>, SecondaryStorage::Error>
 HttpStorage::get(const Digest& key)
 {
index f9d46ba23174fd8dce2ed218c2a4b8364c1101c0..ca1a573d0006de7c01e3b669dd045ff4c4c3b80a 100644 (file)
@@ -50,6 +50,7 @@ private:
   const std::string m_url_path;
   std::unique_ptr<httplib::Client> m_http_client;
 
+  void configure_timeouts(const AttributeMap& attributes);
   std::string get_entry_path(const Digest& key) const;
 };