From 0bff2ad176ceaf0680db9fd6a7f99d0da7fcc3d6 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Tue, 29 Oct 2019 09:16:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=B2=BE=E7=AE=80Http?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Http/HttpSession.cpp | 91 +++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/src/Http/HttpSession.cpp b/src/Http/HttpSession.cpp index d58825d5..10d6b08d 100644 --- a/src/Http/HttpSession.cpp +++ b/src/Http/HttpSession.cpp @@ -138,32 +138,8 @@ HttpResponseInvokerImp::HttpResponseInvokerImp(const HttpResponseInvokerImp::Htt void HttpResponseInvokerImp::responseFile(const StrCaseMap &requestHeader, const StrCaseMap &responseHeader, const string &filePath) const { - try { - struct stat tFileStat; - if (filePath.empty() || 0 != stat(filePath.data(), &tFileStat)) { - //文件不存在 - throw std::runtime_error("file not exited"); - } - - auto &strRange = const_cast(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(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); - } - + StrCaseMap &httpHeader = const_cast(responseHeader); + do { std::shared_ptr fp(fopen(filePath.data(), "rb"), [](FILE *fp) { if (fp) { fclose(fp); @@ -171,16 +147,43 @@ void HttpResponseInvokerImp::responseFile(const StrCaseMap &requestHeader, }); if (!fp) { //打开文件失败 - throw std::runtime_error(StrPrinter << "open file not failed:" << get_uv_errmsg(false)); + break; + } + + auto &strRange = const_cast(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(fp, iRangeStart, iRangeEnd - iRangeStart + 1); (*this)(pcHttpResult, httpHeader, fileBody); + return; + }while(false); - }catch (std::exception &ex){ - (*this)("404 Not Found", responseHeader, ex.what()); - } + GET_CONFIG(string,notFound,Http::kNotFound); + 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(){ @@ -378,7 +381,7 @@ bool HttpSession::checkLiveFlvStream(const function &cb){ if(!cb) { //找到rtmp源,发送http头,负载后续发送 - sendResponse("200 OK", false, get_mime_type(".flv"),KeyValue(),nullptr,false); + sendResponse("200 OK", false, "video/x-flv",KeyValue(),nullptr,false); }else{ cb(); } @@ -583,11 +586,16 @@ void HttpSession::Handle_Req_GET(int64_t &content_len) { return; } - //先看看该http事件是否被拦截 if(emitHttpEvent(false)){ + //拦截http api事件 return; } + if(checkLiveFlvStream()){ + //拦截http-flv播放器 + return; + } + //事件未被拦截,则认为是http下载请求 auto fullUrl = string(HTTP_SCHEMA) + "://" + _parser["Host"] + _parser.FullUrl(); _mediaInfo.parse(fullUrl); @@ -633,22 +641,9 @@ void HttpSession::Handle_Req_GET(int64_t &content_len) { } }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; //判断是否有权限访问该文件 - 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()){ KeyValue headerOut; if(cookie){ @@ -813,8 +808,8 @@ void HttpSession::sendResponse(const char *pcStatus, } if(set_content_len && size >= 0){ - //文件长度为定值或者,且不是http-flv设置Content-Length - headerOut.emplace("Content-Length", StrPrinter << size <