Commit c1f9dc10 by xiongziliang

完善http服务器功能

parent d1607bcf
...@@ -47,3 +47,7 @@ splitPacket: ...@@ -47,3 +47,7 @@ splitPacket:
_remain_data.clear(); _remain_data.clear();
} }
} }
void HttpRequestSplitter::setContentLen(int64_t content_len) {
_content_len = content_len;
}
...@@ -35,6 +35,11 @@ protected: ...@@ -35,6 +35,11 @@ protected:
* @param content * @param content
*/ */
virtual void onRecvContent(const string &content) = 0; virtual void onRecvContent(const string &content) = 0;
/**
* 设置content len
*/
void setContentLen(int64_t content_len);
private: private:
string _remain_data; string _remain_data;
int64_t _content_len = 0; int64_t _content_len = 0;
......
...@@ -618,27 +618,20 @@ inline bool HttpSession::emitHttpEvent(bool doInvoke){ ...@@ -618,27 +618,20 @@ inline bool HttpSession::emitHttpEvent(bool doInvoke){
return consumed; return consumed;
} }
inline bool HttpSession::Handle_Req_POST(int64_t &content_len) { inline bool HttpSession::Handle_Req_POST(int64_t &content_len) {
//////////////获取HTTP POST Content///////////// GET_CONFIG_AND_REGISTER(uint64_t,maxReqSize,Config::Http::kMaxReqSize);
GET_CONFIG_AND_REGISTER(uint32_t,reqSize,Config::Http::kMaxReqSize); GET_CONFIG_AND_REGISTER(int,maxReqCnt,Config::Http::kMaxReqCount);
int realContentLen = m_parser["Content-Length"].empty() ? -1 : atoi(m_parser["Content-Length"].data());
int iContentLen = realContentLen;
if(iContentLen > reqSize){
//Content大小超过限制,那么我们把这个http post请求当做不限制content长度来处理
//这种情况下,用于文件post很有必要,否则内存可能溢出
iContentLen = -1;
}
GET_CONFIG_AND_REGISTER(uint32_t,reqCnt,Config::Http::kMaxReqCount); int64_t totalContentLen = m_parser["Content-Length"].empty() ? -1 : atoll(m_parser["Content-Length"].data());
bool bClose = (strcasecmp(m_parser["Connection"].data(),"close") == 0) || ( ++m_iReqCnt > reqCnt); bool bClose = (strcasecmp(m_parser["Connection"].data(),"close") == 0) || ( ++m_iReqCnt > maxReqCnt);
if(iContentLen == 0){ if(totalContentLen == 0){
emitHttpEvent(true); emitHttpEvent(true);
return !bClose; return !bClose;
} }
if(iContentLen > 0){ if(totalContentLen > 0 && totalContentLen < maxReqSize ){
//返回固定长度的content //返回固定长度的content
content_len = iContentLen; content_len = totalContentLen;
auto parserCopy = m_parser; auto parserCopy = m_parser;
m_contentCallBack = [this,parserCopy,bClose](const string &content){ m_contentCallBack = [this,parserCopy,bClose](const string &content){
//恢复http头 //恢复http头
...@@ -659,10 +652,29 @@ inline bool HttpSession::Handle_Req_POST(int64_t &content_len) { ...@@ -659,10 +652,29 @@ inline bool HttpSession::Handle_Req_POST(int64_t &content_len) {
//返回不固定长度的content //返回不固定长度的content
content_len = -1; content_len = -1;
auto parserCopy = m_parser; auto parserCopy = m_parser;
m_contentCallBack = [this,parserCopy,realContentLen](const string &content){ std::shared_ptr<int64_t> recvedContentLen = std::make_shared<int64_t>(0);
onRecvUnlimitedContent(parserCopy,content,realContentLen); m_contentCallBack = [this,parserCopy,totalContentLen,recvedContentLen,bClose](const string &content){
*(recvedContentLen) += content.size();
onRecvUnlimitedContent(parserCopy,content,totalContentLen,*(recvedContentLen));
if(*(recvedContentLen) < totalContentLen){
//数据还没接收完毕
//m_contentCallBack是可持续的,后面还要处理后续content数据 //m_contentCallBack是可持续的,后面还要处理后续content数据
return true; return true;
}
//数据接收完毕
if(!bClose){
//keep-alive类型连接
//content接收完毕,后续都是http header
setContentLen(0);
return false;
}
//连接类型是close类型,收完content就关闭连接
shutdown();
return false ;
}; };
} }
return true; return true;
......
...@@ -88,9 +88,10 @@ protected: ...@@ -88,9 +88,10 @@ protected:
* 这个函数可用于处理大文件上传、http-flv推流 * 这个函数可用于处理大文件上传、http-flv推流
* @param header http请求头 * @param header http请求头
* @param content content分片数据 * @param content content分片数据
* @param content_size content大小,如果为0则是不限长度content * @param totalSize content总大小,如果为0则是不限长度content
* @param recvedSize 已收数据大小
*/ */
virtual void onRecvUnlimitedContent(const Parser &header,const string &content,int64_t content_size){ virtual void onRecvUnlimitedContent(const Parser &header,const string &content,int64_t totalSize,int64_t recvedSize){
WarnL << "content数据长度过大,无法处理,请重载HttpSession::onRecvUnlimitedContent"; WarnL << "content数据长度过大,无法处理,请重载HttpSession::onRecvUnlimitedContent";
shutdown(); shutdown();
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论