diff --git a/fs/test/CMakeLists.txt b/fs/test/CMakeLists.txt index 6eb5b9c5..fb7421b1 100644 --- a/fs/test/CMakeLists.txt +++ b/fs/test/CMakeLists.txt @@ -12,6 +12,6 @@ add_executable(test-filecopy test_filecopy.cpp) target_link_libraries(test-filecopy PRIVATE photon_shared) add_test(NAME test-filecopy COMMAND $) -add_executable(test-throttled test_throttledfile.cpp) -target_link_libraries(test-throttled PRIVATE photon_shared) -add_test(NAME test-throttled COMMAND $) \ No newline at end of file +add_executable(test-throttle-file test_throttledfile.cpp) +target_link_libraries(test-throttle-file PRIVATE photon_shared) +add_test(NAME test-throttle-file COMMAND $) \ No newline at end of file diff --git a/net/http/client.cpp b/net/http/client.cpp index 23ea5c25..802eb873 100644 --- a/net/http/client.cpp +++ b/net/http/client.cpp @@ -38,6 +38,7 @@ class PooledDialer { bool tls_ctx_ownership; std::unique_ptr tcpsock; std::unique_ptr tlssock; + std::unique_ptr udssock; std::unique_ptr resolver; //etsocket seems not support multi thread very well, use tcp_socket now. need to find out why @@ -49,6 +50,7 @@ class PooledDialer { auto tls_cli = new_tls_client(tls_ctx, new_tcp_socket_client(), true); tcpsock.reset(new_tcp_socket_pool(tcp_cli, -1, true)); tlssock.reset(new_tcp_socket_pool(tls_cli, -1, true)); + udssock.reset(new_uds_client()); } ~PooledDialer() { @@ -63,6 +65,8 @@ class PooledDialer { ISocketStream* dial(const T& x, uint64_t timeout = -1UL) { return dial(x.host_no_port(), x.port(), x.secure(), timeout); } + + ISocketStream* dial(std::string_view uds_path, uint64_t timeout = -1UL); }; ISocketStream* PooledDialer::dial(std::string_view host, uint16_t port, bool secure, uint64_t timeout) { @@ -96,6 +100,14 @@ ISocketStream* PooledDialer::dial(std::string_view host, uint16_t port, bool sec return nullptr; } +ISocketStream* PooledDialer::dial(std::string_view uds_path, uint64_t timeout) { + udssock->timeout(timeout); + auto stream = udssock->connect(uds_path.data()); + if (!stream) + LOG_ERRNO_RETURN(0, nullptr, "failed to dial to unix socket `", uds_path); + return stream; +} + constexpr uint64_t code3xx() { return 0; } template constexpr uint64_t code3xx(uint64_t x, Ts...xs) @@ -164,9 +176,13 @@ class ClientImpl : public Client { if (tmo.timeout() == 0) LOG_ERROR_RETURN(ETIMEDOUT, ROUNDTRIP_FAILED, "connection timedout"); auto &req = op->req; - auto s = (m_proxy && !m_proxy_url.empty()) - ? m_dialer.dial(m_proxy_url, tmo.timeout()) - : m_dialer.dial(req, tmo.timeout()); + ISocketStream* s; + if (m_proxy && !m_proxy_url.empty()) + s = m_dialer.dial(m_proxy_url, tmo.timeout()); + else if (!op->uds_path.empty()) + s = m_dialer.dial(op->uds_path, tmo.timeout()); + else + s = m_dialer.dial(req, tmo.timeout()); if (!s) { if (errno == ECONNREFUSED || errno == ENOENT) { LOG_ERROR_RETURN(0, ROUNDTRIP_FAST_RETRY, "connection refused") diff --git a/net/http/client.h b/net/http/client.h index 350766e3..e83e8fd4 100644 --- a/net/http/client.h +++ b/net/http/client.h @@ -48,7 +48,9 @@ class Client : public Object { uint16_t retry = 5; // default retry: 5 at most Response resp; // response int status_code = -1; // status code in response - bool enable_proxy; + bool enable_proxy = false; + std::string_view uds_path; // If set, Unix Domain Socket will be used instead of TCP. + // URL should still be the format of http://localhost/xxx IStream* body_stream = nullptr; // use body_stream as body using BodyWriter = Delegate; // or call body_writer if body_stream BodyWriter body_writer = {}; // is not set @@ -68,6 +70,11 @@ class Client : public Object { if (!_client) return -1; return _client->call(this); } + int call(std::string_view unix_socket_path) { + if (!_client) return -1; + uds_path = unix_socket_path; + return _client->call(this); + } protected: Client* _client;