优化精简Http服务器代码

This commit is contained in:
xiongziliang 2019-10-29 09:16:52 +08:00
parent 43e1cc69a8
commit 0bff2ad176

View File

@ -138,32 +138,8 @@ HttpResponseInvokerImp::HttpResponseInvokerImp(const HttpResponseInvokerImp::Htt
void HttpResponseInvokerImp::responseFile(const StrCaseMap &requestHeader, void HttpResponseInvokerImp::responseFile(const StrCaseMap &requestHeader,
const StrCaseMap &responseHeader, const StrCaseMap &responseHeader,
const string &filePath) const { const string &filePath) const {
try { StrCaseMap &httpHeader = const_cast<StrCaseMap&>(responseHeader);
struct stat tFileStat; do {
if (filePath.empty() || 0 != stat(filePath.data(), &tFileStat)) {
//文件不存在
throw std::runtime_error("file not exited");
}
auto &strRange = const_cast<StrCaseMap &>(requestHeader)["Range"];
int64_t iRangeStart = 0, iRangeEnd = 0;
iRangeStart = atoll(FindField(strRange.data(), "bytes=", "-").data());
iRangeEnd = atoll(FindField(strRange.data(), "-", "\r\n").data());
if (iRangeEnd == 0) {
iRangeEnd = tFileStat.st_size - 1;
}
const char *pcHttpResult = NULL;
StrCaseMap &httpHeader = const_cast<StrCaseMap&>(responseHeader);
if (strRange.size() == 0) {
//全部下载
pcHttpResult = "200 OK";
} else {
//分节下载
pcHttpResult = "206 Partial Content";
//分节下载返回Content-Range头
httpHeader.emplace("Content-Range", StrPrinter << "bytes " << iRangeStart << "-" << iRangeEnd << "/" << tFileStat.st_size << endl);
}
std::shared_ptr<FILE> fp(fopen(filePath.data(), "rb"), [](FILE *fp) { std::shared_ptr<FILE> fp(fopen(filePath.data(), "rb"), [](FILE *fp) {
if (fp) { if (fp) {
fclose(fp); fclose(fp);
@ -171,16 +147,43 @@ void HttpResponseInvokerImp::responseFile(const StrCaseMap &requestHeader,
}); });
if (!fp) { if (!fp) {
//打开文件失败 //打开文件失败
throw std::runtime_error(StrPrinter << "open file not failed:" << get_uv_errmsg(false)); break;
}
auto &strRange = const_cast<StrCaseMap &>(requestHeader)["Range"];
int64_t iRangeStart = 0;
int64_t iRangeEnd = 0 ;
int64_t fileSize = HttpMultiFormBody::fileSize(fp.get());
const char *pcHttpResult = NULL;
if (strRange.size() == 0) {
//全部下载
pcHttpResult = "200 OK";
iRangeEnd = fileSize - 1;
} else {
//分节下载
pcHttpResult = "206 Partial Content";
iRangeStart = atoll(FindField(strRange.data(), "bytes=", "-").data());
iRangeEnd = atoll(FindField(strRange.data(), "-", "\r\n").data());
if (iRangeEnd == 0) {
iRangeEnd = fileSize - 1;
}
//分节下载返回Content-Range头
httpHeader.emplace("Content-Range", StrPrinter << "bytes " << iRangeStart << "-" << iRangeEnd << "/" << fileSize << endl);
} }
//回复文件 //回复文件
HttpBody::Ptr fileBody = std::make_shared<HttpFileBody>(fp, iRangeStart, iRangeEnd - iRangeStart + 1); HttpBody::Ptr fileBody = std::make_shared<HttpFileBody>(fp, iRangeStart, iRangeEnd - iRangeStart + 1);
(*this)(pcHttpResult, httpHeader, fileBody); (*this)(pcHttpResult, httpHeader, fileBody);
return;
}while(false);
}catch (std::exception &ex){ GET_CONFIG(string,notFound,Http::kNotFound);
(*this)("404 Not Found", responseHeader, ex.what()); GET_CONFIG(string,charSet,Http::kCharSet);
}
auto strContentType = StrPrinter << "text/html; charset=" << charSet << endl;
httpHeader["Content-Type"] = strContentType;
(*this)("404 Not Found", httpHeader, notFound);
} }
HttpResponseInvokerImp::operator bool(){ HttpResponseInvokerImp::operator bool(){
@ -378,7 +381,7 @@ bool HttpSession::checkLiveFlvStream(const function<void()> &cb){
if(!cb) { if(!cb) {
//找到rtmp源发送http头负载后续发送 //找到rtmp源发送http头负载后续发送
sendResponse("200 OK", false, get_mime_type(".flv"),KeyValue(),nullptr,false); sendResponse("200 OK", false, "video/x-flv",KeyValue(),nullptr,false);
}else{ }else{
cb(); cb();
} }
@ -583,11 +586,16 @@ void HttpSession::Handle_Req_GET(int64_t &content_len) {
return; return;
} }
//先看看该http事件是否被拦截
if(emitHttpEvent(false)){ if(emitHttpEvent(false)){
//拦截http api事件
return; return;
} }
if(checkLiveFlvStream()){
//拦截http-flv播放器
return;
}
//事件未被拦截则认为是http下载请求 //事件未被拦截则认为是http下载请求
auto fullUrl = string(HTTP_SCHEMA) + "://" + _parser["Host"] + _parser.FullUrl(); auto fullUrl = string(HTTP_SCHEMA) + "://" + _parser["Host"] + _parser.FullUrl();
_mediaInfo.parse(fullUrl); _mediaInfo.parse(fullUrl);
@ -633,22 +641,9 @@ void HttpSession::Handle_Req_GET(int64_t &content_len) {
} }
}while(0); }while(0);
//访问的是文件
struct stat tFileStat;
if (0 != stat(strFile.data(), &tFileStat)) {
//再看看是否为http-flv直播请求
if(checkLiveFlvStream()){
//若是return
return;
}
//文件不存在
sendNotFound(bClose);
throw SockException(bClose ? Err_shutdown : Err_success,"close connection after send 404 not found on file");
}
auto parser = _parser; auto parser = _parser;
//判断是否有权限访问该文件 //判断是否有权限访问该文件
canAccessPath(_parser.Url(),false,[this,parser,tFileStat,bClose,strFile](const string &errMsg,const HttpServerCookie::Ptr &cookie){ canAccessPath(_parser.Url(),false,[this,parser,bClose,strFile](const string &errMsg,const HttpServerCookie::Ptr &cookie){
if(!errMsg.empty()){ if(!errMsg.empty()){
KeyValue headerOut; KeyValue headerOut;
if(cookie){ if(cookie){
@ -813,8 +808,8 @@ void HttpSession::sendResponse(const char *pcStatus,
} }
if(set_content_len && size >= 0){ if(set_content_len && size >= 0){
//文件长度为定值或者,且不是http-flv设置Content-Length //文件长度为定值或者,且不是http-flv强制设置Content-Length
headerOut.emplace("Content-Length", StrPrinter << size <<endl); headerOut["Content-Length"] = StrPrinter << size << endl;
} }
if(size && !pcContentType){ if(size && !pcContentType){