in net/http/client.cpp [200:278]
int do_roundtrip(Operation* op, Timeout tmo) {
op->status_code = -1;
if (tmo.timeout() == 0)
LOG_ERROR_RETURN(ETIMEDOUT, ROUNDTRIP_FAILED, "connection timedout");
auto &req = op->req;
ISocketStream* s;
if (m_proxy && !m_proxy_url.empty())
s = get_dialer().dial(m_proxy_url, tmo.timeout());
else if (!op->uds_path.empty())
s = get_dialer().dial(op->uds_path, tmo.timeout());
else
s = get_dialer().dial(req, tmo.timeout());
if (!s) {
if (errno == ECONNREFUSED || errno == ENOENT) {
LOG_ERROR_RETURN(0, ROUNDTRIP_FAST_RETRY, "connection refused")
}
LOG_ERROR_RETURN(0, ROUNDTRIP_NEED_RETRY, "connection failed");
}
SocketStream_ptr sock(s);
LOG_DEBUG("Sending request ` `", req.verb(), req.target());
if (req.send_header(sock.get()) < 0) {
sock->close();
req.reset_status();
LOG_ERROR_RETURN(0, ROUNDTRIP_NEED_RETRY, "send header failed, retry");
}
sock->timeout(tmo.timeout());
if (op->body_buffer_size > 0) {
// send body_buffer
if (req.write(op->body_buffer, op->body_buffer_size) < 0) {
sock->close();
req.reset_status();
LOG_ERROR_RETURN(0, ROUNDTRIP_NEED_RETRY, "send body buffer failed, retry");
}
} else if (op->body_stream) {
// send body_stream
if (req.write_stream(op->body_stream) < 0) {
sock->close();
req.reset_status();
LOG_ERROR_RETURN(0, ROUNDTRIP_NEED_RETRY, "send body stream failed, retry");
}
} else {
// call body_writer
if (op->body_writer(&req) < 0) {
sock->close();
req.reset_status();
LOG_ERROR_RETURN(0, ROUNDTRIP_NEED_RETRY, "failed to call body writer, retry");
}
}
if (req.send() < 0) {
sock->close();
req.reset_status();
LOG_ERROR_RETURN(0, ROUNDTRIP_NEED_RETRY, "failed to ensure send");
}
LOG_DEBUG("Request sent, wait for response ` `", req.verb(), req.target());
auto space = req.get_remain_space();
auto &resp = op->resp;
if (space.second > kMinimalHeadersSize) {
resp.reset(space.first, space.second, false, sock.release(), true, req.verb());
} else {
auto buf = malloc(kMinimalHeadersSize);
resp.reset((char *)buf, kMinimalHeadersSize, true, sock.release(), true, req.verb());
}
if (op->resp.receive_header(tmo.timeout()) != 0) {
req.reset_status();
LOG_ERROR_RETURN(0, ROUNDTRIP_NEED_RETRY, "read response header failed");
}
op->status_code = resp.status_code();
LOG_DEBUG("Got response ` ` code=` || content_length=`", req.verb(),
req.target(), resp.status_code(), resp.headers.content_length());
if (m_cookie_jar) m_cookie_jar->get_cookies_from_headers(req.host(), &resp);
if (resp.status_code() < 400 && resp.status_code() >= 300 && op->follow)
return redirect(op);
return ROUNDTRIP_SUCCESS;
}