mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-23 03:10:04 +08:00
Implement size limits on HTTP header number, header size and body size
This commit is contained in:
parent
5a137f8b8e
commit
1e0bbe803a
@ -225,6 +225,12 @@ charSet=utf-8
|
|||||||
keepAliveSecond=30
|
keepAliveSecond=30
|
||||||
#http请求体最大字节数,如果post的body太大,则不适合缓存body在内存
|
#http请求体最大字节数,如果post的body太大,则不适合缓存body在内存
|
||||||
maxReqSize=40960
|
maxReqSize=40960
|
||||||
|
#http header请求最大个数,大于0才校验
|
||||||
|
maxReqHeaderNumber=0
|
||||||
|
#http header请求最大字节数,大于0才校验
|
||||||
|
maxReqHeaderSize=0
|
||||||
|
#http body请求最大字节数,大于0才校验
|
||||||
|
maxReqBodySize=0
|
||||||
#404网页内容,用户可以自定义404网页
|
#404网页内容,用户可以自定义404网页
|
||||||
#notFound=<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>您访问的资源不存在!</h1></center><hr><center>ZLMediaKit-4.0</center></body></html>
|
#notFound=<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>您访问的资源不存在!</h1></center><hr><center>ZLMediaKit-4.0</center></body></html>
|
||||||
#http服务器监听端口
|
#http服务器监听端口
|
||||||
|
@ -164,6 +164,9 @@ namespace Http {
|
|||||||
#define HTTP_FIELD "http."
|
#define HTTP_FIELD "http."
|
||||||
const string kSendBufSize = HTTP_FIELD "sendBufSize";
|
const string kSendBufSize = HTTP_FIELD "sendBufSize";
|
||||||
const string kMaxReqSize = HTTP_FIELD "maxReqSize";
|
const string kMaxReqSize = HTTP_FIELD "maxReqSize";
|
||||||
|
const string kMaxReqHeaderNumber = HTTP_FIELD "maxReqHeaderNumber";
|
||||||
|
const string kMaxReqHeaderSize = HTTP_FIELD "maxReqHeaderSize";
|
||||||
|
const string kMaxReqBodySize = HTTP_FIELD "maxReqBodySize";
|
||||||
const string kKeepAliveSecond = HTTP_FIELD "keepAliveSecond";
|
const string kKeepAliveSecond = HTTP_FIELD "keepAliveSecond";
|
||||||
const string kCharSet = HTTP_FIELD "charSet";
|
const string kCharSet = HTTP_FIELD "charSet";
|
||||||
const string kRootPath = HTTP_FIELD "rootPath";
|
const string kRootPath = HTTP_FIELD "rootPath";
|
||||||
|
@ -254,6 +254,12 @@ namespace Http {
|
|||||||
extern const std::string kSendBufSize;
|
extern const std::string kSendBufSize;
|
||||||
// http 最大请求字节数
|
// http 最大请求字节数
|
||||||
extern const std::string kMaxReqSize;
|
extern const std::string kMaxReqSize;
|
||||||
|
// header最大请求个数
|
||||||
|
extern const std::string kMaxReqHeaderNumber;
|
||||||
|
// header最大请求字节数
|
||||||
|
extern const std::string kMaxReqHeaderSize;
|
||||||
|
// body最大请求字节数
|
||||||
|
extern const std::string kMaxReqBodySize;
|
||||||
// http keep-alive秒数
|
// http keep-alive秒数
|
||||||
extern const std::string kKeepAliveSecond;
|
extern const std::string kKeepAliveSecond;
|
||||||
// http 字符编码
|
// http 字符编码
|
||||||
|
@ -65,6 +65,10 @@ void HttpRequestSplitter::input(const char *data,size_t len) {
|
|||||||
_content_len = onRecvHeader(header_ptr, header_size);
|
_content_len = onRecvHeader(header_ptr, header_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_content_len == 0 && _remain_data_size > 0) {
|
||||||
|
onCheckHeader(ptr,_remain_data_size);
|
||||||
|
}
|
||||||
|
|
||||||
if(_remain_data_size <= 0){
|
if(_remain_data_size <= 0){
|
||||||
//没有剩余数据,清空缓存
|
//没有剩余数据,清空缓存
|
||||||
_remain_data.clear();
|
_remain_data.clear();
|
||||||
|
@ -78,6 +78,13 @@ protected:
|
|||||||
*/
|
*/
|
||||||
virtual const char *onSearchPacketTail(const char *data, size_t len);
|
virtual const char *onSearchPacketTail(const char *data, size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断请求头是否有效
|
||||||
|
* @param data 请求头数据
|
||||||
|
* @param len 请求头长度
|
||||||
|
*/
|
||||||
|
virtual void onCheckHeader(const char *data, size_t len) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置content len
|
* 设置content len
|
||||||
*/
|
*/
|
||||||
|
@ -26,6 +26,9 @@ namespace mediakit {
|
|||||||
HttpSession::HttpSession(const Socket::Ptr &pSock) : Session(pSock) {
|
HttpSession::HttpSession(const Socket::Ptr &pSock) : Session(pSock) {
|
||||||
//设置默认参数
|
//设置默认参数
|
||||||
setMaxReqSize(0);
|
setMaxReqSize(0);
|
||||||
|
setMaxReqHeaderNumber(0);
|
||||||
|
setMaxReqHeaderSize(0);
|
||||||
|
setMaxReqBodySize(0);
|
||||||
setTimeoutSec(0);
|
setTimeoutSec(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +70,8 @@ ssize_t HttpSession::onRecvHeader(const char *header, size_t len) {
|
|||||||
CHECK(_parser.url()[0] == '/');
|
CHECK(_parser.url()[0] == '/');
|
||||||
_origin = _parser["Origin"];
|
_origin = _parser["Origin"];
|
||||||
|
|
||||||
|
onCheckHeader(len, _parser.getHeader().size());
|
||||||
|
|
||||||
urlDecode(_parser);
|
urlDecode(_parser);
|
||||||
auto &cmd = _parser.method();
|
auto &cmd = _parser.method();
|
||||||
auto it = s_func_map.find(cmd);
|
auto it = s_func_map.find(cmd);
|
||||||
@ -140,11 +145,26 @@ ssize_t HttpSession::onRecvHeader(const char *header, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HttpSession::onRecvContent(const char *data, size_t len) {
|
void HttpSession::onRecvContent(const char *data, size_t len) {
|
||||||
|
if (_max_req_body_size > 0 && len > _max_req_body_size) {
|
||||||
|
WarnL << "Http body size is too huge: " << len << " > " << _max_req_body_size
|
||||||
|
<< ", please set " << Http::kMaxReqBodySize << " in config.ini file.";
|
||||||
|
reset();
|
||||||
|
throw std::out_of_range("Http body size is too huge: " + to_string(len));
|
||||||
|
}
|
||||||
|
|
||||||
if (_on_recv_body && !_on_recv_body(data, len)) {
|
if (_on_recv_body && !_on_recv_body(data, len)) {
|
||||||
_on_recv_body = nullptr;
|
_on_recv_body = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HttpSession::onCheckHeader(const char *header, size_t len) {
|
||||||
|
size_t number = 0;
|
||||||
|
if (_max_req_header_number > 0) {
|
||||||
|
number = onSearchHeaderNumber(header, len);
|
||||||
|
}
|
||||||
|
onCheckHeader(len, number);
|
||||||
|
}
|
||||||
|
|
||||||
void HttpSession::onRecv(const Buffer::Ptr &pBuf) {
|
void HttpSession::onRecv(const Buffer::Ptr &pBuf) {
|
||||||
_ticker.resetTime();
|
_ticker.resetTime();
|
||||||
input(pBuf->data(), pBuf->size());
|
input(pBuf->data(), pBuf->size());
|
||||||
@ -182,6 +202,30 @@ void HttpSession::setMaxReqSize(size_t max_req_size) {
|
|||||||
setMaxCacheSize(max_req_size);
|
setMaxCacheSize(max_req_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HttpSession::setMaxReqHeaderNumber(size_t max_req_header_number) {
|
||||||
|
if (!max_req_header_number) {
|
||||||
|
GET_CONFIG(size_t, s_max_req_header_number, Http::kMaxReqHeaderNumber);
|
||||||
|
max_req_header_number = s_max_req_header_number;
|
||||||
|
}
|
||||||
|
_max_req_header_number = max_req_header_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HttpSession::setMaxReqHeaderSize(size_t max_req_header_size) {
|
||||||
|
if (!max_req_header_size) {
|
||||||
|
GET_CONFIG(size_t, s_max_req_header_size, Http::kMaxReqHeaderSize);
|
||||||
|
max_req_header_size = s_max_req_header_size;
|
||||||
|
}
|
||||||
|
_max_req_header_size = max_req_header_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HttpSession::setMaxReqBodySize(size_t max_req_body_size) {
|
||||||
|
if (!max_req_body_size) {
|
||||||
|
GET_CONFIG(size_t, s_max_req_body_size, Http::kMaxReqBodySize);
|
||||||
|
max_req_body_size = s_max_req_body_size;
|
||||||
|
}
|
||||||
|
_max_req_body_size = max_req_body_size;
|
||||||
|
}
|
||||||
|
|
||||||
void HttpSession::onManager() {
|
void HttpSession::onManager() {
|
||||||
if (_ticker.elapsedTime() > _keep_alive_sec * 1000) {
|
if (_ticker.elapsedTime() > _keep_alive_sec * 1000) {
|
||||||
//http超时
|
//http超时
|
||||||
@ -834,4 +878,32 @@ std::shared_ptr<FlvMuxer> HttpSession::getSharedPtr() {
|
|||||||
return dynamic_pointer_cast<FlvMuxer>(shared_from_this());
|
return dynamic_pointer_cast<FlvMuxer>(shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t HttpSession::onSearchHeaderNumber(const char *data, size_t len) {
|
||||||
|
ssize_t number = 0;
|
||||||
|
const char *ptr = data;
|
||||||
|
const char *pos = nullptr;
|
||||||
|
while (pos = strstr(ptr, "\r\n")) {
|
||||||
|
number++;
|
||||||
|
ptr = pos + 2;
|
||||||
|
}
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HttpSession::onCheckHeader(size_t len, size_t number)
|
||||||
|
{
|
||||||
|
if (_max_req_header_size > 0 && len > _max_req_header_size) {
|
||||||
|
WarnL << "Http header size is too huge: " << len << " > " << _max_req_header_size
|
||||||
|
<< ", please set " << Http::kMaxReqHeaderSize << " in config.ini file.";
|
||||||
|
reset();
|
||||||
|
throw std::out_of_range("http header size is invalid: " + to_string(len));
|
||||||
|
|
||||||
|
}
|
||||||
|
if (_max_req_header_number > 0 && number > _max_req_header_number) {
|
||||||
|
WarnL << "Http header number is too huge: " << len << " > " << _max_req_header_number
|
||||||
|
<< ", please set " << Http::kMaxReqHeaderNumber << " in config.ini file.";
|
||||||
|
reset();
|
||||||
|
throw std::out_of_range("http header size is invalid: " + to_string(len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace mediakit */
|
} /* namespace mediakit */
|
||||||
|
@ -49,6 +49,9 @@ public:
|
|||||||
static std::string urlDecodeComponent(const std::string &str);
|
static std::string urlDecodeComponent(const std::string &str);
|
||||||
void setTimeoutSec(size_t second);
|
void setTimeoutSec(size_t second);
|
||||||
void setMaxReqSize(size_t max_req_size);
|
void setMaxReqSize(size_t max_req_size);
|
||||||
|
void setMaxReqHeaderNumber(size_t max_req_header_number);
|
||||||
|
void setMaxReqHeaderSize(size_t max_req_header_size);
|
||||||
|
void setMaxReqBodySize(size_t max_req_body_size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//FlvMuxer override
|
//FlvMuxer override
|
||||||
@ -59,6 +62,7 @@ protected:
|
|||||||
//HttpRequestSplitter override
|
//HttpRequestSplitter override
|
||||||
ssize_t onRecvHeader(const char *data, size_t len) override;
|
ssize_t onRecvHeader(const char *data, size_t len) override;
|
||||||
void onRecvContent(const char *data, size_t len) override;
|
void onRecvContent(const char *data, size_t len) override;
|
||||||
|
void onCheckHeader(const char *data, size_t len) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重载之用于处理不定长度的content
|
* 重载之用于处理不定长度的content
|
||||||
@ -126,6 +130,9 @@ private:
|
|||||||
//设置socket标志
|
//设置socket标志
|
||||||
void setSocketFlags();
|
void setSocketFlags();
|
||||||
|
|
||||||
|
ssize_t onSearchHeaderNumber(const char *data, size_t len);
|
||||||
|
void onCheckHeader(size_t len, size_t number);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MediaInfo _media_info;
|
MediaInfo _media_info;
|
||||||
|
|
||||||
@ -136,6 +143,9 @@ private:
|
|||||||
size_t _keep_alive_sec = 0;
|
size_t _keep_alive_sec = 0;
|
||||||
//最大http请求字节大小
|
//最大http请求字节大小
|
||||||
size_t _max_req_size = 0;
|
size_t _max_req_size = 0;
|
||||||
|
size_t _max_req_header_number = 0;
|
||||||
|
size_t _max_req_header_size = 0;
|
||||||
|
size_t _max_req_body_size = 0;
|
||||||
//消耗的总流量
|
//消耗的总流量
|
||||||
uint64_t _total_bytes_usage = 0;
|
uint64_t _total_bytes_usage = 0;
|
||||||
// http请求中的 Origin字段
|
// http请求中的 Origin字段
|
||||||
|
Loading…
Reference in New Issue
Block a user