| 1119 | } |
| 1120 | |
| 1121 | std::optional<std::string> HTTPClient::Recv(const std::chrono::time_point<std::chrono::steady_clock> deadline) |
| 1122 | { |
| 1123 | auto wait_for_readable{[this](std::chrono::milliseconds timeout) -> bool { |
| 1124 | Sock::Event event{0}; |
| 1125 | if (!m_socket->Wait(timeout, Sock::RecvEvent, &event)) { |
| 1126 | return false; |
| 1127 | } |
| 1128 | return (event & Sock::RecvEvent) != 0; |
| 1129 | }}; |
| 1130 | |
| 1131 | auto time_left = std::chrono::duration_cast<std::chrono::milliseconds>( |
| 1132 | deadline - std::chrono::steady_clock::now()); |
| 1133 | if (time_left.count() <= 0 || !wait_for_readable(time_left)) { |
| 1134 | throw CConnectionFailed{"timeout"}; |
| 1135 | } |
| 1136 | |
| 1137 | char recv_buf[4096]; |
| 1138 | ssize_t nrecv = m_socket->Recv(recv_buf, sizeof(recv_buf), /*flags=*/0); |
| 1139 | |
| 1140 | if (nrecv < 0) { |
| 1141 | int err = WSAGetLastError(); |
| 1142 | if (!IOErrorIsPermanent(err)) { |
| 1143 | return std::nullopt; |
| 1144 | } |
| 1145 | throw CConnectionFailed{strprintf("Read error: %s", NetworkErrorString(err))}; |
| 1146 | } |
| 1147 | |
| 1148 | if (nrecv == 0) { |
| 1149 | throw RecvEOF{"EOF"}; |
| 1150 | } |
| 1151 | |
| 1152 | return std::string{recv_buf, static_cast<size_t>(nrecv)}; |
| 1153 | } |
| 1154 | |
| 1155 | static UniValue CallRPC(BaseRequestHandler* rh, const std::string& strMethod, const std::vector<std::string>& args, const std::string& endpoint, const std::string& username) |
| 1156 | { |
nothing calls this directly
no test coverage detected