mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-14 20:15:58 +08:00
HTTP: 重写http相关超时管理机制
This commit is contained in:
@@ -15,8 +15,7 @@
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
void HttpClient::sendRequest(const string &url, float timeout_sec, float recv_timeout_sec) {
|
||||
_recv_timeout_second = recv_timeout_sec;
|
||||
void HttpClient::sendRequest(const string &url) {
|
||||
clearResponse();
|
||||
_url = url;
|
||||
auto protocol = FindField(url.data(), NULL, "://");
|
||||
@@ -73,7 +72,6 @@ void HttpClient::sendRequest(const string &url, float timeout_sec, float recv_ti
|
||||
bool host_changed = (_last_host != host + ":" + to_string(port)) || (_is_https != is_https);
|
||||
_last_host = host + ":" + to_string(port);
|
||||
_is_https = is_https;
|
||||
_timeout_second = timeout_sec;
|
||||
|
||||
auto cookies = HttpCookieStorage::Instance().get(_last_host, _path);
|
||||
_StrPrinter printer;
|
||||
@@ -86,7 +84,7 @@ void HttpClient::sendRequest(const string &url, float timeout_sec, float recv_ti
|
||||
}
|
||||
|
||||
if (!alive() || host_changed) {
|
||||
startConnect(host, port, timeout_sec);
|
||||
startConnect(host, port, _wait_header_ms);
|
||||
} else {
|
||||
SockException ex;
|
||||
onConnect_l(ex);
|
||||
@@ -95,22 +93,22 @@ void HttpClient::sendRequest(const string &url, float timeout_sec, float recv_ti
|
||||
|
||||
void HttpClient::clear() {
|
||||
_url.clear();
|
||||
_header.clear();
|
||||
_user_set_header.clear();
|
||||
_body.reset();
|
||||
_method.clear();
|
||||
_path.clear();
|
||||
clearResponse();
|
||||
}
|
||||
|
||||
void HttpClient::clearResponse() {
|
||||
_complete = false;
|
||||
_header_recved = false;
|
||||
_recved_body_size = 0;
|
||||
_total_body_size = 0;
|
||||
_parser.Clear();
|
||||
_chunked_splitter = nullptr;
|
||||
_recv_timeout_ticker.resetTime();
|
||||
_total_timeout_ticker.resetTime();
|
||||
_wait_header.resetTime();
|
||||
_wait_body.resetTime();
|
||||
_wait_complete.resetTime();
|
||||
HttpRequestSplitter::reset();
|
||||
}
|
||||
|
||||
@@ -152,7 +150,6 @@ void HttpClient::onConnect(const SockException &ex) {
|
||||
}
|
||||
|
||||
void HttpClient::onConnect_l(const SockException &ex) {
|
||||
_recv_timeout_ticker.resetTime();
|
||||
if (ex) {
|
||||
onDisconnect(ex);
|
||||
return;
|
||||
@@ -164,12 +161,14 @@ void HttpClient::onConnect_l(const SockException &ex) {
|
||||
printer << pr.first + ": ";
|
||||
printer << pr.second + "\r\n";
|
||||
}
|
||||
_header.clear();
|
||||
_path.clear();
|
||||
SockSender::send(printer << "\r\n");
|
||||
onFlush();
|
||||
}
|
||||
|
||||
void HttpClient::onRecv(const Buffer::Ptr &pBuf) {
|
||||
_recv_timeout_ticker.resetTime();
|
||||
_wait_body.resetTime();
|
||||
HttpRequestSplitter::input(pBuf->data(), pBuf->size());
|
||||
}
|
||||
|
||||
@@ -192,12 +191,13 @@ ssize_t HttpClient::onRecvHeader(const char *data, size_t len) {
|
||||
}
|
||||
if (onRedirectUrl(new_url, _parser.Url() == "302")) {
|
||||
setMethod("GET");
|
||||
HttpClient::sendRequest(new_url, _timeout_second, _recv_timeout_second);
|
||||
HttpClient::sendRequest(new_url);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
checkCookie(_parser.getHeader());
|
||||
_header_recved = true;
|
||||
_total_body_size = onResponseHeader(_parser.Url(), _parser.getHeader());
|
||||
|
||||
if (!_parser["Content-Length"].empty()) {
|
||||
@@ -225,8 +225,8 @@ ssize_t HttpClient::onRecvHeader(const char *data, size_t len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//当_totalBodySize != 0时到达这里,代表后续有content
|
||||
//虽然我们在_totalBodySize >0 时知道content的确切大小,
|
||||
//当_total_body_size != 0时到达这里,代表后续有content
|
||||
//虽然我们在_total_body_size >0 时知道content的确切大小,
|
||||
//但是由于我们没必要等content接收完毕才回调onRecvContent(因为这样浪费内存并且要多次拷贝数据)
|
||||
//所以返回-1代表我们接下来分段接收content
|
||||
_recved_body_size = 0;
|
||||
@@ -265,7 +265,6 @@ void HttpClient::onRecvContent(const char *data, size_t len) {
|
||||
}
|
||||
|
||||
void HttpClient::onFlush() {
|
||||
_recv_timeout_ticker.resetTime();
|
||||
GET_CONFIG(uint32_t, send_buf_size, Http::kSendBufSize);
|
||||
while (_body && _body->remainSize() && !isSocketBusy()) {
|
||||
auto buffer = _body->readData(send_buf_size);
|
||||
@@ -282,20 +281,36 @@ void HttpClient::onFlush() {
|
||||
}
|
||||
|
||||
void HttpClient::onManager() {
|
||||
if (_recv_timeout_ticker.elapsedTime() > _recv_timeout_second * 1000 && _total_body_size < 0 && !_chunked_splitter) {
|
||||
//如果Content-Length未指定 但接收数据超时
|
||||
//则认为本次http请求完成
|
||||
onResponseCompleted_l();
|
||||
//onManager回调在连接中或已连接状态才会调用
|
||||
|
||||
if (_wait_complete_ms > 0) {
|
||||
//设置了总超时时间
|
||||
if (!_complete && _wait_complete.elapsedTime() > _wait_complete_ms) {
|
||||
//等待http回复完毕超时
|
||||
shutdown(SockException(Err_timeout, "wait http response complete timeout"));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (waitResponse() && _timeout_second > 0 && _total_timeout_ticker.elapsedTime() > _timeout_second * 1000) {
|
||||
//超时
|
||||
shutdown(SockException(Err_timeout, "http request timeout"));
|
||||
//未设置总超时时间
|
||||
if (!_header_recved) {
|
||||
//等待header中
|
||||
if (_wait_header.elapsedTime() > _wait_header_ms) {
|
||||
//等待header中超时
|
||||
shutdown(SockException(Err_timeout, "wait http response header timeout"));
|
||||
return;
|
||||
}
|
||||
} else if (_wait_body_ms > 0 && _wait_body.elapsedTime() > _wait_body_ms) {
|
||||
//等待body中,等待超时
|
||||
shutdown(SockException(Err_timeout, "wait http response body timeout"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void HttpClient::onResponseCompleted_l() {
|
||||
_complete = true;
|
||||
_wait_complete.resetTime();
|
||||
onResponseCompleted();
|
||||
}
|
||||
|
||||
@@ -303,6 +318,10 @@ bool HttpClient::waitResponse() const {
|
||||
return !_complete && alive();
|
||||
}
|
||||
|
||||
bool HttpClient::isHttps() const {
|
||||
return _is_https;
|
||||
}
|
||||
|
||||
void HttpClient::checkCookie(HttpClient::HttpHeader &headers) {
|
||||
//Set-Cookie: IPTV_SERVER=8E03927B-CC8C-4389-BC00-31DBA7EC7B49;expires=Sun, Sep 23 2018 15:07:31 GMT;path=/index/api/
|
||||
for (auto it_set_cookie = headers.find("Set-Cookie"); it_set_cookie != headers.end(); ++it_set_cookie) {
|
||||
@@ -340,4 +359,17 @@ void HttpClient::checkCookie(HttpClient::HttpHeader &headers) {
|
||||
}
|
||||
}
|
||||
|
||||
void HttpClient::setHeaderTimeout(size_t timeout_ms) {
|
||||
CHECK(timeout_ms > 0);
|
||||
_wait_header_ms = timeout_ms;
|
||||
}
|
||||
|
||||
void HttpClient::setBodyTimeout(size_t timeout_ms) {
|
||||
_wait_body_ms = timeout_ms;
|
||||
}
|
||||
|
||||
void HttpClient::setCompleteTimeout(size_t timeout_ms) {
|
||||
_wait_complete_ms = timeout_ms;
|
||||
}
|
||||
|
||||
} /* namespace mediakit */
|
||||
|
||||
Reference in New Issue
Block a user