in net/http/client.cpp [280:323]
int call(Operation* /*IN, OUT*/ op) override {
auto content_length = op->req.headers.content_length();
auto encoding = op->req.headers["Transfer-Encoding"];
if ((content_length != 0) && (encoding == "chunked")) {
op->status_code = -1;
LOG_ERROR_RETURN(EINVAL, ROUNDTRIP_FAILED,
"Content-Length and Transfer-Encoding conflicted");
}
op->req.headers.merge(m_common_headers);
op->req.headers.insert("User-Agent", m_user_agent.empty() ? std::string_view(USERAGENT)
: std::string_view(m_user_agent));
op->req.headers.insert("Connection", "keep-alive");
if (m_cookie_jar && m_cookie_jar->set_cookies_to_headers(&op->req) != 0)
LOG_ERROR_RETURN(0, -1, "set_cookies_to_headers failed");
Timeout tmo(std::min(op->timeout.timeout(), m_timeout));
int retry = 0, followed = 0, ret = 0;
uint64_t sleep_interval = 0;
while (followed <= op->follow && retry <= op->retry && tmo.timeout() != 0) {
ret = do_roundtrip(op, tmo);
if (ret == ROUNDTRIP_SUCCESS || ret == ROUNDTRIP_FAILED) break;
switch (ret) {
case ROUNDTRIP_NEED_RETRY:
photon::thread_usleep(sleep_interval * 1000UL);
sleep_interval = (sleep_interval + 500) * 2;
++retry;
break;
case ROUNDTRIP_FAST_RETRY:
++retry;
break;
case ROUNDTRIP_REDIRECT:
retry = 0;
++followed;
break;
default:
break;
}
if (tmo.timeout() == 0)
LOG_ERROR_RETURN(ETIMEDOUT, -1, "connection timedout");
if (followed > op->follow || retry > op->retry)
LOG_ERRNO_RETURN(0, -1, "connection failed");
}
if (ret != ROUNDTRIP_SUCCESS) LOG_ERROR_RETURN(0, -1,"too many retry, roundtrip failed");
return 0;
}