优化HLS直播相关代码
This commit is contained in:
parent
380a0204b1
commit
07ef417250
|
|
@ -219,8 +219,9 @@ static MediaSource::Ptr find_l(const string &schema, const string &vhost_in, con
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ret && create_new){
|
if(!ret && create_new && schema != HLS_SCHEMA){
|
||||||
//未查找媒体源,则创建一个
|
//未查找媒体源,则读取mp4创建一个
|
||||||
|
//播放hls不触发mp4点播(因为HLS也可以用于录像,不是纯粹的直播)
|
||||||
ret = MediaSource::createFromMP4(schema, vhost, app, id);
|
ret = MediaSource::createFromMP4(schema, vhost, app, id);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ static int kHlsCookieSecond = 60;
|
||||||
static const string kCookieName = "ZL_COOKIE";
|
static const string kCookieName = "ZL_COOKIE";
|
||||||
static const string kHlsSuffix = "/hls.m3u8";
|
static const string kHlsSuffix = "/hls.m3u8";
|
||||||
|
|
||||||
class HttpCookieAttachment{
|
class HttpCookieAttachment {
|
||||||
public:
|
public:
|
||||||
HttpCookieAttachment() {};
|
HttpCookieAttachment() {};
|
||||||
~HttpCookieAttachment() {};
|
~HttpCookieAttachment() {};
|
||||||
|
|
@ -160,7 +160,7 @@ const string &HttpFileManager::getContentType(const char *name) {
|
||||||
dot = strrchr(name, '.');
|
dot = strrchr(name, '.');
|
||||||
static StrCaseMap mapType;
|
static StrCaseMap mapType;
|
||||||
static onceToken token([&]() {
|
static onceToken token([&]() {
|
||||||
for (unsigned int i = 0; i < sizeof (s_mime_src) / sizeof (s_mime_src[0]); ++i) {
|
for (unsigned int i = 0; i < sizeof(s_mime_src) / sizeof(s_mime_src[0]); ++i) {
|
||||||
mapType.emplace(s_mime_src[i][0], s_mime_src[i][1]);
|
mapType.emplace(s_mime_src[i][0], s_mime_src[i][1]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -183,8 +183,8 @@ static string searchIndexFile(const string &dir){
|
||||||
}
|
}
|
||||||
set<string> setFile;
|
set<string> setFile;
|
||||||
while ((pDirent = readdir(pDir)) != NULL) {
|
while ((pDirent = readdir(pDir)) != NULL) {
|
||||||
static set<const char *,StrCaseCompare> indexSet = {"index.html","index.htm","index"};
|
static set<const char *, StrCaseCompare> indexSet = {"index.html", "index.htm", "index"};
|
||||||
if(indexSet.find(pDirent->d_name) != indexSet.end()){
|
if (indexSet.find(pDirent->d_name) != indexSet.end()) {
|
||||||
string ret = pDirent->d_name;
|
string ret = pDirent->d_name;
|
||||||
closedir(pDir);
|
closedir(pDir);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -196,16 +196,16 @@ static string searchIndexFile(const string &dir){
|
||||||
|
|
||||||
static bool makeFolderMenu(const string &httpPath, const string &strFullPath, string &strRet) {
|
static bool makeFolderMenu(const string &httpPath, const string &strFullPath, string &strRet) {
|
||||||
GET_CONFIG(bool, dirMenu, Http::kDirMenu);
|
GET_CONFIG(bool, dirMenu, Http::kDirMenu);
|
||||||
if(!dirMenu){
|
if (!dirMenu) {
|
||||||
//不允许浏览文件夹
|
//不允许浏览文件夹
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
string strPathPrefix(strFullPath);
|
string strPathPrefix(strFullPath);
|
||||||
string last_dir_name;
|
string last_dir_name;
|
||||||
if(strPathPrefix.back() == '/'){
|
if (strPathPrefix.back() == '/') {
|
||||||
strPathPrefix.pop_back();
|
strPathPrefix.pop_back();
|
||||||
}else{
|
} else {
|
||||||
last_dir_name = split(strPathPrefix,"/").back();
|
last_dir_name = split(strPathPrefix, "/").back();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!File::is_dir(strPathPrefix.data())) {
|
if (!File::is_dir(strPathPrefix.data())) {
|
||||||
|
|
@ -249,24 +249,24 @@ static bool makeFolderMenu(const string &httpPath, const string &strFullPath, st
|
||||||
if (File::is_special_dir(pDirent->d_name)) {
|
if (File::is_special_dir(pDirent->d_name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(pDirent->d_name[0] == '.'){
|
if (pDirent->d_name[0] == '.') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
setFile.emplace(pDirent->d_name);
|
setFile.emplace(pDirent->d_name);
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(auto &strFile :setFile ){
|
for (auto &strFile :setFile) {
|
||||||
string strAbsolutePath = strPathPrefix + "/" + strFile;
|
string strAbsolutePath = strPathPrefix + "/" + strFile;
|
||||||
bool isDir = File::is_dir(strAbsolutePath.data());
|
bool isDir = File::is_dir(strAbsolutePath.data());
|
||||||
ss << "<li><span>" << i++ << "</span>\t";
|
ss << "<li><span>" << i++ << "</span>\t";
|
||||||
ss << "<a href=\"";
|
ss << "<a href=\"";
|
||||||
if(!last_dir_name.empty()){
|
if (!last_dir_name.empty()) {
|
||||||
ss << last_dir_name << "/" << strFile;
|
ss << last_dir_name << "/" << strFile;
|
||||||
}else{
|
} else {
|
||||||
ss << strFile;
|
ss << strFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isDir){
|
if (isDir) {
|
||||||
ss << "/";
|
ss << "/";
|
||||||
}
|
}
|
||||||
ss << "\">";
|
ss << "\">";
|
||||||
|
|
@ -307,14 +307,14 @@ static bool end_of(const string &str, const string &substr){
|
||||||
//拦截hls的播放请求
|
//拦截hls的播放请求
|
||||||
static bool emitHlsPlayed(const Parser &parser, const MediaInfo &mediaInfo, const HttpSession::HttpAccessPathInvoker &invoker,TcpSession &sender){
|
static bool emitHlsPlayed(const Parser &parser, const MediaInfo &mediaInfo, const HttpSession::HttpAccessPathInvoker &invoker,TcpSession &sender){
|
||||||
//访问的hls.m3u8结尾,我们转换成kBroadcastMediaPlayed事件
|
//访问的hls.m3u8结尾,我们转换成kBroadcastMediaPlayed事件
|
||||||
Broadcast::AuthInvoker mediaAuthInvoker = [invoker](const string &err){
|
Broadcast::AuthInvoker auth_invoker = [invoker](const string &err) {
|
||||||
//cookie有效期为kHlsCookieSecond
|
//cookie有效期为kHlsCookieSecond
|
||||||
invoker(err,"",kHlsCookieSecond);
|
invoker(err, "", kHlsCookieSecond);
|
||||||
};
|
};
|
||||||
bool flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPlayed,mediaInfo,mediaAuthInvoker,static_cast<SockInfo &>(sender));
|
bool flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPlayed, mediaInfo, auth_invoker, static_cast<SockInfo &>(sender));
|
||||||
if(!flag){
|
if (!flag) {
|
||||||
//未开启鉴权,那么允许播放
|
//未开启鉴权,那么允许播放
|
||||||
mediaAuthInvoker("");
|
auth_invoker("");
|
||||||
}
|
}
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
@ -325,23 +325,23 @@ public:
|
||||||
SockInfoImp() = default;
|
SockInfoImp() = default;
|
||||||
~SockInfoImp() override = default;
|
~SockInfoImp() override = default;
|
||||||
|
|
||||||
string get_local_ip() override{
|
string get_local_ip() override {
|
||||||
return _local_ip;
|
return _local_ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t get_local_port() override{
|
uint16_t get_local_port() override {
|
||||||
return _local_port;
|
return _local_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
string get_peer_ip() override{
|
string get_peer_ip() override {
|
||||||
return _peer_ip;
|
return _peer_ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t get_peer_port() override{
|
uint16_t get_peer_port() override {
|
||||||
return _peer_port;
|
return _peer_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
string getIdentifier() const override{
|
string getIdentifier() const override {
|
||||||
return _identifier;
|
return _identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -384,7 +384,7 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
||||||
//上次cookie是限定本目录
|
//上次cookie是限定本目录
|
||||||
if (attachment._err_msg.empty()) {
|
if (attachment._err_msg.empty()) {
|
||||||
//上次鉴权成功
|
//上次鉴权成功
|
||||||
if(attachment._is_hls){
|
if (attachment._is_hls) {
|
||||||
//如果播放的是hls,那么刷新hls的cookie(获取ts文件也会刷新)
|
//如果播放的是hls,那么刷新hls的cookie(获取ts文件也会刷新)
|
||||||
cookie->updateTime();
|
cookie->updateTime();
|
||||||
cookie_from_header = false;
|
cookie_from_header = false;
|
||||||
|
|
@ -434,7 +434,7 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
||||||
attachment._err_msg = errMsg;
|
attachment._err_msg = errMsg;
|
||||||
//记录访问的是否为hls
|
//记录访问的是否为hls
|
||||||
attachment._is_hls = is_hls;
|
attachment._is_hls = is_hls;
|
||||||
if(is_hls){
|
if (is_hls) {
|
||||||
//hls相关信息
|
//hls相关信息
|
||||||
attachment._hls_data = std::make_shared<HlsCookieData>(mediaInfo, info);
|
attachment._hls_data = std::make_shared<HlsCookieData>(mediaInfo, info);
|
||||||
//hls未查找MediaSource
|
//hls未查找MediaSource
|
||||||
|
|
@ -442,7 +442,7 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
||||||
}
|
}
|
||||||
(*cookie)[kCookieName].set<HttpCookieAttachment>(std::move(attachment));
|
(*cookie)[kCookieName].set<HttpCookieAttachment>(std::move(attachment));
|
||||||
callback(errMsg, cookie);
|
callback(errMsg, cookie);
|
||||||
}else{
|
} else {
|
||||||
callback(errMsg, nullptr);
|
callback(errMsg, nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -465,15 +465,15 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
||||||
* 发送404 Not Found
|
* 发送404 Not Found
|
||||||
*/
|
*/
|
||||||
static void sendNotFound(const HttpFileManager::invoker &cb) {
|
static void sendNotFound(const HttpFileManager::invoker &cb) {
|
||||||
GET_CONFIG(string,notFound,Http::kNotFound);
|
GET_CONFIG(string, notFound, Http::kNotFound);
|
||||||
cb("404 Not Found","text/html",StrCaseMap(),std::make_shared<HttpStringBody>(notFound));
|
cb("404 Not Found", "text/html", StrCaseMap(), std::make_shared<HttpStringBody>(notFound));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拼接文件路径
|
* 拼接文件路径
|
||||||
*/
|
*/
|
||||||
static string pathCat(const string &a, const string &b){
|
static string pathCat(const string &a, const string &b){
|
||||||
if(a.back() == '/'){
|
if (a.back() == '/') {
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
return a + '/' + b;
|
return a + '/' + b;
|
||||||
|
|
@ -496,7 +496,7 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_hls){
|
if (is_hls) {
|
||||||
//hls,那么移除掉后缀获取真实的stream_id并且修改协议为HLS
|
//hls,那么移除掉后缀获取真实的stream_id并且修改协议为HLS
|
||||||
const_cast<string &>(mediaInfo._schema) = HLS_SCHEMA;
|
const_cast<string &>(mediaInfo._schema) = HLS_SCHEMA;
|
||||||
replace(const_cast<string &>(mediaInfo._streamid), kHlsSuffix, "");
|
replace(const_cast<string &>(mediaInfo._streamid), kHlsSuffix, "");
|
||||||
|
|
@ -506,7 +506,7 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
||||||
//判断是否有权限访问该文件
|
//判断是否有权限访问该文件
|
||||||
canAccessPath(sender, parser, mediaInfo, false, [cb, strFile, parser, is_hls, mediaInfo, weakSession , file_exist](const string &errMsg, const HttpServerCookie::Ptr &cookie) {
|
canAccessPath(sender, parser, mediaInfo, false, [cb, strFile, parser, is_hls, mediaInfo, weakSession , file_exist](const string &errMsg, const HttpServerCookie::Ptr &cookie) {
|
||||||
auto strongSession = weakSession.lock();
|
auto strongSession = weakSession.lock();
|
||||||
if(!strongSession){
|
if (!strongSession) {
|
||||||
//http客户端已经断开,不需要回复
|
//http客户端已经断开,不需要回复
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -514,6 +514,7 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
||||||
//文件鉴权失败
|
//文件鉴权失败
|
||||||
StrCaseMap headerOut;
|
StrCaseMap headerOut;
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
|
auto lck = cookie->getLock();
|
||||||
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kCookieName].get<HttpCookieAttachment>()._path);
|
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kCookieName].get<HttpCookieAttachment>()._path);
|
||||||
}
|
}
|
||||||
cb("401 Unauthorized", "text/html", headerOut, std::make_shared<HttpStringBody>(errMsg));
|
cb("401 Unauthorized", "text/html", headerOut, std::make_shared<HttpStringBody>(errMsg));
|
||||||
|
|
@ -523,11 +524,12 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
||||||
auto response_file = [file_exist](const HttpServerCookie::Ptr &cookie, const HttpFileManager::invoker &cb, const string &strFile, const Parser &parser) {
|
auto response_file = [file_exist](const HttpServerCookie::Ptr &cookie, const HttpFileManager::invoker &cb, const string &strFile, const Parser &parser) {
|
||||||
StrCaseMap httpHeader;
|
StrCaseMap httpHeader;
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
|
auto lck = cookie->getLock();
|
||||||
httpHeader["Set-Cookie"] = cookie->getCookie((*cookie)[kCookieName].get<HttpCookieAttachment>()._path);
|
httpHeader["Set-Cookie"] = cookie->getCookie((*cookie)[kCookieName].get<HttpCookieAttachment>()._path);
|
||||||
}
|
}
|
||||||
HttpSession::HttpResponseInvoker invoker = [&](const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body) {
|
HttpSession::HttpResponseInvoker invoker = [&](const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body) {
|
||||||
if (cookie && file_exist) {
|
if (cookie && file_exist) {
|
||||||
cookie->getLock();
|
auto lck = cookie->getLock();
|
||||||
auto is_hls = (*cookie)[kCookieName].get<HttpCookieAttachment>()._is_hls;
|
auto is_hls = (*cookie)[kCookieName].get<HttpCookieAttachment>()._is_hls;
|
||||||
if (is_hls) {
|
if (is_hls) {
|
||||||
(*cookie)[kCookieName].get<HttpCookieAttachment>()._hls_data->addByteUsage(body->remainSize());
|
(*cookie)[kCookieName].get<HttpCookieAttachment>()._hls_data->addByteUsage(body->remainSize());
|
||||||
|
|
@ -541,24 +543,28 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
||||||
if (!is_hls) {
|
if (!is_hls) {
|
||||||
//不是hls,直接回复文件或404
|
//不是hls,直接回复文件或404
|
||||||
response_file(cookie, cb, strFile, parser);
|
response_file(cookie, cb, strFile, parser);
|
||||||
} else {
|
return;
|
||||||
//是hls直播,判断是否存在
|
}
|
||||||
|
|
||||||
|
//是hls直播,判断HLS直播流是否已经注册
|
||||||
bool have_find_media_src = false;
|
bool have_find_media_src = false;
|
||||||
if(cookie){
|
if (cookie) {
|
||||||
|
auto lck = cookie->getLock();
|
||||||
have_find_media_src = (*cookie)[kCookieName].get<HttpCookieAttachment>()._have_find_media_source;
|
have_find_media_src = (*cookie)[kCookieName].get<HttpCookieAttachment>()._have_find_media_source;
|
||||||
if(!have_find_media_src){
|
if (!have_find_media_src) {
|
||||||
(*cookie)[kCookieName].get<HttpCookieAttachment>()._have_find_media_source = true;
|
(*cookie)[kCookieName].get<HttpCookieAttachment>()._have_find_media_source = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(have_find_media_src){
|
if (have_find_media_src) {
|
||||||
//之前该cookie已经通过MediaSource::findAsync查找过了,所以现在只以文件系统查找结果为准
|
//之前该cookie已经通过MediaSource::findAsync查找过了,所以现在只以文件系统查找结果为准
|
||||||
response_file(cookie, cb, strFile, parser);
|
response_file(cookie, cb, strFile, parser);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//hls文件不存在,我们等待其生成并延后回复
|
//hls文件不存在,我们等待其生成并延后回复
|
||||||
MediaSource::findAsync(mediaInfo, strongSession, [response_file, cookie, cb, strFile, parser](const MediaSource::Ptr &src) {
|
MediaSource::findAsync(mediaInfo, strongSession, [response_file, cookie, cb, strFile, parser](const MediaSource::Ptr &src) {
|
||||||
if(cookie){
|
if (cookie) {
|
||||||
//尝试添加HlsMediaSource的观看人数
|
auto lck = cookie->getLock();
|
||||||
|
//尝试添加HlsMediaSource的观看人数(HLS是按需生成的,这样可以触发HLS文件的生成)
|
||||||
(*cookie)[kCookieName].get<HttpCookieAttachment>()._hls_data->addByteUsage(0);
|
(*cookie)[kCookieName].get<HttpCookieAttachment>()._hls_data->addByteUsage(0);
|
||||||
}
|
}
|
||||||
if (src && File::is_file(strFile.data())) {
|
if (src && File::is_file(strFile.data())) {
|
||||||
|
|
@ -568,17 +574,16 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
||||||
}
|
}
|
||||||
auto hls = dynamic_pointer_cast<HlsMediaSource>(src);
|
auto hls = dynamic_pointer_cast<HlsMediaSource>(src);
|
||||||
if (!hls) {
|
if (!hls) {
|
||||||
//流不存在,那么直接返回文件
|
//流不存在,那么直接返回文件(相当于纯粹的HLS文件服务器,但是会挂起播放器15秒左右(用于等待HLS流的注册))
|
||||||
response_file(cookie, cb, strFile, parser);
|
response_file(cookie, cb, strFile, parser);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//流存在,但是m3u8文件不存在,那么等待生成m3u8文件
|
//流存在,但是m3u8文件不存在,那么等待生成m3u8文件(HLS源注册后,并不会立即生成HLS文件,有人观看才会按需生成HLS文件)
|
||||||
hls->waitForFile([response_file, cookie, cb, strFile, parser]() {
|
hls->waitForFile([response_file, cookie, cb, strFile, parser]() {
|
||||||
response_file(cookie, cb, strFile, parser);
|
response_file(cookie, cb, strFile, parser);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -639,13 +644,13 @@ void HttpFileManager::onAccessPath(TcpSession &sender, Parser &parser, const Htt
|
||||||
////////////////////////////////////HttpResponseInvokerImp//////////////////////////////////////
|
////////////////////////////////////HttpResponseInvokerImp//////////////////////////////////////
|
||||||
|
|
||||||
void HttpResponseInvokerImp::operator()(const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body) const{
|
void HttpResponseInvokerImp::operator()(const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body) const{
|
||||||
if(_lambad){
|
if (_lambad) {
|
||||||
_lambad(codeOut,headerOut,body);
|
_lambad(codeOut, headerOut, body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpResponseInvokerImp::operator()(const string &codeOut, const StrCaseMap &headerOut, const string &body) const{
|
void HttpResponseInvokerImp::operator()(const string &codeOut, const StrCaseMap &headerOut, const string &body) const{
|
||||||
this->operator()(codeOut,headerOut,std::make_shared<HttpStringBody>(body));
|
this->operator()(codeOut, headerOut, std::make_shared<HttpStringBody>(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponseInvokerImp::HttpResponseInvokerImp(const HttpResponseInvokerImp::HttpResponseInvokerLambda0 &lambda){
|
HttpResponseInvokerImp::HttpResponseInvokerImp(const HttpResponseInvokerImp::HttpResponseInvokerLambda0 &lambda){
|
||||||
|
|
@ -653,23 +658,23 @@ HttpResponseInvokerImp::HttpResponseInvokerImp(const HttpResponseInvokerImp::Htt
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponseInvokerImp::HttpResponseInvokerImp(const HttpResponseInvokerImp::HttpResponseInvokerLambda1 &lambda){
|
HttpResponseInvokerImp::HttpResponseInvokerImp(const HttpResponseInvokerImp::HttpResponseInvokerLambda1 &lambda){
|
||||||
if(!lambda){
|
if (!lambda) {
|
||||||
_lambad = nullptr;
|
_lambad = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_lambad = [lambda](const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body){
|
_lambad = [lambda](const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body) {
|
||||||
string str;
|
string str;
|
||||||
if(body && body->remainSize()){
|
if (body && body->remainSize()) {
|
||||||
str = body->readData(body->remainSize())->toString();
|
str = body->readData(body->remainSize())->toString();
|
||||||
}
|
}
|
||||||
lambda(codeOut,headerOut,str);
|
lambda(codeOut, headerOut, str);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
StrCaseMap &httpHeader = const_cast<StrCaseMap&>(responseHeader);
|
StrCaseMap &httpHeader = const_cast<StrCaseMap &>(responseHeader);
|
||||||
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);
|
||||||
|
|
@ -678,8 +683,8 @@ void HttpResponseInvokerImp::responseFile(const StrCaseMap &requestHeader,
|
||||||
|
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
//打开文件失败
|
//打开文件失败
|
||||||
GET_CONFIG(string,notFound,Http::kNotFound);
|
GET_CONFIG(string, notFound, Http::kNotFound);
|
||||||
GET_CONFIG(string,charSet,Http::kCharSet);
|
GET_CONFIG(string, charSet, Http::kCharSet);
|
||||||
|
|
||||||
auto strContentType = StrPrinter << "text/html; charset=" << charSet << endl;
|
auto strContentType = StrPrinter << "text/html; charset=" << charSet << endl;
|
||||||
httpHeader["Content-Type"] = strContentType;
|
httpHeader["Content-Type"] = strContentType;
|
||||||
|
|
@ -689,7 +694,7 @@ void HttpResponseInvokerImp::responseFile(const StrCaseMap &requestHeader,
|
||||||
|
|
||||||
auto &strRange = const_cast<StrCaseMap &>(requestHeader)["Range"];
|
auto &strRange = const_cast<StrCaseMap &>(requestHeader)["Range"];
|
||||||
int64_t iRangeStart = 0;
|
int64_t iRangeStart = 0;
|
||||||
int64_t iRangeEnd = 0 ;
|
int64_t iRangeEnd = 0;
|
||||||
int64_t fileSize = HttpMultiFormBody::fileSize(fp.get());
|
int64_t fileSize = HttpMultiFormBody::fileSize(fp.get());
|
||||||
|
|
||||||
const char *pcHttpResult = NULL;
|
const char *pcHttpResult = NULL;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue