mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-29 14:45:55 +08:00
优化http处理无content字段时的逻辑
This commit is contained in:
parent
022838a7d3
commit
57dcb63b6b
@ -138,7 +138,7 @@ void HttpClient::onRecvBytes(const char *data, int size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::onErr(const SockException &ex) {
|
void HttpClient::onErr(const SockException &ex) {
|
||||||
if (ex.getErrCode() == Err_eof && _totalBodySize == INT64_MAX) {
|
if (ex.getErrCode() == Err_eof && _totalBodySize < 0) {
|
||||||
//如果Content-Length未指定 但服务器断开链接
|
//如果Content-Length未指定 但服务器断开链接
|
||||||
//则认为本次http请求完成
|
//则认为本次http请求完成
|
||||||
onResponseCompleted_l();
|
onResponseCompleted_l();
|
||||||
@ -148,52 +148,53 @@ void HttpClient::onErr(const SockException &ex) {
|
|||||||
|
|
||||||
int64_t HttpClient::onRecvHeader(const char *data, uint64_t len) {
|
int64_t HttpClient::onRecvHeader(const char *data, uint64_t len) {
|
||||||
_parser.Parse(data);
|
_parser.Parse(data);
|
||||||
onResponseHeader(_parser.Url(), _parser.getValues());
|
|
||||||
checkCookie(_parser.getValues());
|
checkCookie(_parser.getValues());
|
||||||
|
_totalBodySize = onResponseHeader(_parser.Url(), _parser.getValues());
|
||||||
|
|
||||||
if(_parser["Content-Length"].empty()){
|
if(!_parser["Content-Length"].empty()){
|
||||||
//没有Content-Length字段
|
//有Content-Length字段时忽略onResponseHeader的返回值
|
||||||
auto ret = onResponseCompleted_l();
|
_totalBodySize = atoll(_parser["Content-Length"].data());
|
||||||
if(ret){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
//如果http回复未声明Content-Length字段,但是却有content内容,那说明可能是个不限长度的content
|
|
||||||
_totalBodySize = INT64_MAX;
|
|
||||||
_recvedBodySize = 0;
|
|
||||||
//返回-1代表不限制content回复大小
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//有Content-Length字段
|
|
||||||
_recvedBodySize = 0;
|
|
||||||
_totalBodySize = atoll(_parser["Content-Length"].data());
|
|
||||||
|
|
||||||
if(_totalBodySize == 0){
|
if(_totalBodySize == 0){
|
||||||
//content长度为0,本次http请求结束
|
//后续没content,本次http请求结束
|
||||||
onResponseCompleted_l();
|
onResponseCompleted_l();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//虽然我们知道content的确切大小,
|
//当_totalBodySize != 0时到达这里,代表后续有content
|
||||||
|
//虽然我们在_totalBodySize >0 时知道content的确切大小,
|
||||||
//但是由于我们没必要等content接收完毕才回调onRecvContent(因为这样浪费内存并且要多次拷贝数据)
|
//但是由于我们没必要等content接收完毕才回调onRecvContent(因为这样浪费内存并且要多次拷贝数据)
|
||||||
//所以返回-1代表我们接下来分段接收content
|
//所以返回-1代表我们接下来分段接收content
|
||||||
|
_recvedBodySize = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::onRecvContent(const char *data, uint64_t len) {
|
void HttpClient::onRecvContent(const char *data, uint64_t len) {
|
||||||
auto recvedBodySize = _recvedBodySize + len;
|
auto recvedBodySize = _recvedBodySize + len;
|
||||||
if (recvedBodySize < _totalBodySize) {
|
if(_totalBodySize < 0){
|
||||||
|
//不限长度的content,最大支持INT64_MAX个字节
|
||||||
|
onResponseBody(data, len, recvedBodySize, INT64_MAX);
|
||||||
|
_recvedBodySize = recvedBodySize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//固定长度的content
|
||||||
|
if ( recvedBodySize < _totalBodySize ) {
|
||||||
|
//content还未接收完毕
|
||||||
onResponseBody(data, len, recvedBodySize, _totalBodySize);
|
onResponseBody(data, len, recvedBodySize, _totalBodySize);
|
||||||
_recvedBodySize = recvedBodySize;
|
_recvedBodySize = recvedBodySize;
|
||||||
} else {
|
return;
|
||||||
onResponseBody(data, _totalBodySize - _recvedBodySize, _totalBodySize, _totalBodySize);
|
}
|
||||||
bool biggerThanExpected = recvedBodySize > _totalBodySize;
|
|
||||||
onResponseCompleted_l();
|
//content接收完毕
|
||||||
if(biggerThanExpected) {
|
onResponseBody(data, _totalBodySize - _recvedBodySize, _totalBodySize, _totalBodySize);
|
||||||
//声明的content数据比真实的小,那么我们只截取前面部分的并断开链接
|
bool biggerThanExpected = recvedBodySize > _totalBodySize;
|
||||||
shutdown();
|
onResponseCompleted_l();
|
||||||
onDisconnect(SockException(Err_other, "http response content size bigger than expected"));
|
if(biggerThanExpected) {
|
||||||
}
|
//声明的content数据比真实的小,那么我们只截取前面部分的并断开链接
|
||||||
|
shutdown();
|
||||||
|
onDisconnect(SockException(Err_other, "http response content size bigger than expected"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +215,7 @@ void HttpClient::onSend() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::onManager() {
|
void HttpClient::onManager() {
|
||||||
if (_aliveTicker.elapsedTime() > 3 * 1000 && _totalBodySize == INT64_MAX) {
|
if (_aliveTicker.elapsedTime() > 3 * 1000 && _totalBodySize < 0) {
|
||||||
//如果Content-Length未指定 但接收数据超时
|
//如果Content-Length未指定 但接收数据超时
|
||||||
//则认为本次http请求完成
|
//则认为本次http请求完成
|
||||||
onResponseCompleted_l();
|
onResponseCompleted_l();
|
||||||
@ -227,14 +228,11 @@ void HttpClient::onManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpClient::onResponseCompleted_l() {
|
void HttpClient::onResponseCompleted_l() {
|
||||||
_totalBodySize = 0;
|
_totalBodySize = 0;
|
||||||
_recvedBodySize = 0;
|
_recvedBodySize = 0;
|
||||||
bool ret = onResponseCompleted();
|
HttpRequestSplitter::reset();
|
||||||
if(ret){
|
onResponseCompleted();
|
||||||
HttpRequestSplitter::reset();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::checkCookie(const HttpClient::HttpHeader &headers) {
|
void HttpClient::checkCookie(const HttpClient::HttpHeader &headers) {
|
||||||
|
@ -247,9 +247,13 @@ protected:
|
|||||||
* 收到http回复头
|
* 收到http回复头
|
||||||
* @param status 状态码,譬如:200 OK
|
* @param status 状态码,譬如:200 OK
|
||||||
* @param headers http头
|
* @param headers http头
|
||||||
|
* @return 返回后续content的长度;-1:后续数据全是content;>=0:固定长度content
|
||||||
|
* 需要指出的是,在http头中带有Content-Length字段时,该返回值无效
|
||||||
*/
|
*/
|
||||||
virtual void onResponseHeader(const string &status,const HttpHeader &headers){
|
virtual int64_t onResponseHeader(const string &status,const HttpHeader &headers){
|
||||||
DebugL << status;
|
DebugL << status;
|
||||||
|
//无Content-Length字段时默认后面全是content
|
||||||
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -265,11 +269,9 @@ protected:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 接收http回复完毕,
|
* 接收http回复完毕,
|
||||||
* @return 是否真的结束数据接收
|
|
||||||
*/
|
*/
|
||||||
virtual bool onResponseCompleted(){
|
virtual void onResponseCompleted(){
|
||||||
DebugL;
|
DebugL;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -295,7 +297,7 @@ protected:
|
|||||||
virtual void onSend() override;
|
virtual void onSend() override;
|
||||||
virtual void onManager() override;
|
virtual void onManager() override;
|
||||||
private:
|
private:
|
||||||
bool onResponseCompleted_l();
|
void onResponseCompleted_l();
|
||||||
void checkCookie(const HttpHeader &headers );
|
void checkCookie(const HttpHeader &headers );
|
||||||
protected:
|
protected:
|
||||||
bool _isHttps;
|
bool _isHttps;
|
||||||
|
@ -63,7 +63,7 @@ void HttpDownloader::startDownload(const string& url, const string& filePath,boo
|
|||||||
sendRequest(url,timeOutSecond);
|
sendRequest(url,timeOutSecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpDownloader::onResponseHeader(const string& status,const HttpHeader& headers) {
|
int64_t HttpDownloader::onResponseHeader(const string& status,const HttpHeader& headers) {
|
||||||
if(status != "200" && status != "206"){
|
if(status != "200" && status != "206"){
|
||||||
//失败
|
//失败
|
||||||
shutdown();
|
shutdown();
|
||||||
@ -75,6 +75,8 @@ void HttpDownloader::onResponseHeader(const string& status,const HttpHeader& hea
|
|||||||
_onResult = nullptr;
|
_onResult = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//后续全部是content
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpDownloader::onResponseBody(const char* buf, size_t size, size_t recvedSize, size_t totalSize) {
|
void HttpDownloader::onResponseBody(const char* buf, size_t size, size_t recvedSize, size_t totalSize) {
|
||||||
@ -83,7 +85,7 @@ void HttpDownloader::onResponseBody(const char* buf, size_t size, size_t recvedS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpDownloader::onResponseCompleted() {
|
void HttpDownloader::onResponseCompleted() {
|
||||||
closeFile();
|
closeFile();
|
||||||
//InfoL << "md5Sum:" << getMd5Sum(_filePath);
|
//InfoL << "md5Sum:" << getMd5Sum(_filePath);
|
||||||
_bDownloadSuccess = true;
|
_bDownloadSuccess = true;
|
||||||
@ -91,7 +93,6 @@ bool HttpDownloader::onResponseCompleted() {
|
|||||||
_onResult(Err_success,"success",_filePath.data());
|
_onResult(Err_success,"success",_filePath.data());
|
||||||
_onResult = nullptr;
|
_onResult = nullptr;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpDownloader::onDisconnect(const SockException &ex) {
|
void HttpDownloader::onDisconnect(const SockException &ex) {
|
||||||
|
@ -47,9 +47,9 @@ public:
|
|||||||
_onResult = cb;
|
_onResult = cb;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void onResponseHeader(const string &status,const HttpHeader &headers) override;
|
int64_t onResponseHeader(const string &status,const HttpHeader &headers) override;
|
||||||
void onResponseBody(const char *buf,size_t size,size_t recvedSize,size_t totalSize) override;
|
void onResponseBody(const char *buf,size_t size,size_t recvedSize,size_t totalSize) override;
|
||||||
bool onResponseCompleted() override;
|
void onResponseCompleted() override;
|
||||||
void onDisconnect(const SockException &ex) override;
|
void onDisconnect(const SockException &ex) override;
|
||||||
void closeFile();
|
void closeFile();
|
||||||
private:
|
private:
|
||||||
|
@ -34,20 +34,21 @@ HttpRequester::~HttpRequester(){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpRequester::onResponseHeader(const string &status,const HttpHeader &headers) {
|
int64_t HttpRequester::onResponseHeader(const string &status,const HttpHeader &headers) {
|
||||||
_strRecvBody.clear();
|
_strRecvBody.clear();
|
||||||
|
//后续全部是content
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpRequester::onResponseBody(const char *buf,size_t size,size_t recvedSize,size_t totalSize) {
|
void HttpRequester::onResponseBody(const char *buf,size_t size,size_t recvedSize,size_t totalSize) {
|
||||||
_strRecvBody.append(buf,size);
|
_strRecvBody.append(buf,size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpRequester::onResponseCompleted() {
|
void HttpRequester::onResponseCompleted() {
|
||||||
if(_onResult){
|
if(_onResult){
|
||||||
_onResult(SockException(),responseStatus(),responseHeader(),_strRecvBody);
|
_onResult(SockException(),responseStatus(),responseHeader(),_strRecvBody);
|
||||||
_onResult = nullptr;
|
_onResult = nullptr;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpRequester::onDisconnect(const SockException &ex){
|
void HttpRequester::onDisconnect(const SockException &ex){
|
||||||
|
@ -40,9 +40,9 @@ public:
|
|||||||
virtual ~HttpRequester();
|
virtual ~HttpRequester();
|
||||||
void startRequester(const string &url,const HttpRequesterResult &onResult,float timeOutSecond = 10);
|
void startRequester(const string &url,const HttpRequesterResult &onResult,float timeOutSecond = 10);
|
||||||
private:
|
private:
|
||||||
void onResponseHeader(const string &status,const HttpHeader &headers) override;
|
int64_t onResponseHeader(const string &status,const HttpHeader &headers) override;
|
||||||
void onResponseBody(const char *buf,size_t size,size_t recvedSize,size_t totalSize) override;
|
void onResponseBody(const char *buf,size_t size,size_t recvedSize,size_t totalSize) override;
|
||||||
bool onResponseCompleted() override;
|
void onResponseCompleted() override;
|
||||||
void onDisconnect(const SockException &ex) override;
|
void onDisconnect(const SockException &ex) override;
|
||||||
private:
|
private:
|
||||||
string _strRecvBody;
|
string _strRecvBody;
|
||||||
|
Loading…
Reference in New Issue
Block a user