mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-27 05:38:31 +08:00
简化hls cookie相关逻辑
This commit is contained in:
parent
d082955510
commit
52d831e990
@ -41,12 +41,27 @@ namespace mediakit {
|
|||||||
// 假如播放器在60秒内都未访问该cookie,那么将重新触发hls播放鉴权
|
// 假如播放器在60秒内都未访问该cookie,那么将重新触发hls播放鉴权
|
||||||
static int kHlsCookieSecond = 60;
|
static int kHlsCookieSecond = 60;
|
||||||
static const string kCookieName = "ZL_COOKIE";
|
static const string kCookieName = "ZL_COOKIE";
|
||||||
static const string kCookiePathKey = "kCookiePathKey";
|
|
||||||
static const string kAccessErrKey = "kAccessErrKey";
|
|
||||||
static const string kAccessHls = "kAccessHls";
|
|
||||||
static const string kHlsSuffix = "/hls.m3u8";
|
static const string kHlsSuffix = "/hls.m3u8";
|
||||||
static const string kHlsData = "kHlsData";
|
|
||||||
static const string kHlsHaveFindMediaSource = "kHlsHaveFindMediaSource";
|
class HttpCookieAttachment{
|
||||||
|
public:
|
||||||
|
HttpCookieAttachment() {};
|
||||||
|
~HttpCookieAttachment() {};
|
||||||
|
public:
|
||||||
|
//cookie生效作用域,本cookie只对该目录下的文件生效
|
||||||
|
string _path;
|
||||||
|
//上次鉴权失败信息,为空则上次鉴权成功
|
||||||
|
string _err_msg;
|
||||||
|
//本cookie是否为hls直播的
|
||||||
|
bool _is_hls = false;
|
||||||
|
//hls直播时的其他一些信息,主要用于播放器个数计数以及流量计数
|
||||||
|
HlsCookieData::Ptr _hls_data;
|
||||||
|
//如果是hls直播,那么判断该cookie是否使用过MediaSource::findAsync查找过
|
||||||
|
//如果程序未正常退出,会残余上次的hls文件,所以判断hls直播是否存在的关键不是文件存在与否
|
||||||
|
//而是应该判断HlsMediaSource是否已注册,但是这样会每次获取m3u8文件时都会用MediaSource::findAsync判断一次
|
||||||
|
//会导致程序性能低下,所以我们应该在cookie声明周期的第一次判断HlsMediaSource是否已经注册,后续通过文件存在与否判断
|
||||||
|
bool _have_find_media_source = false;
|
||||||
|
};
|
||||||
|
|
||||||
static const string &getContentType(const char *name) {
|
static const string &getContentType(const char *name) {
|
||||||
const char *dot;
|
const char *dot;
|
||||||
@ -256,14 +271,12 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
|||||||
if (cookie) {
|
if (cookie) {
|
||||||
//找到了cookie,对cookie上锁先
|
//找到了cookie,对cookie上锁先
|
||||||
auto lck = cookie->getLock();
|
auto lck = cookie->getLock();
|
||||||
auto accessErr = (*cookie)[kAccessErrKey].get<string>();
|
auto attachment = (*cookie)[kCookieName].get<HttpCookieAttachment>();
|
||||||
auto cookiePath = (*cookie)[kCookiePathKey].get<string>();
|
if (path.find(attachment._path) == 0) {
|
||||||
auto cookie_is_hls = (*cookie)[kAccessHls].get<bool>();
|
|
||||||
if (path.find(cookiePath) == 0) {
|
|
||||||
//上次cookie是限定本目录
|
//上次cookie是限定本目录
|
||||||
if (accessErr.empty()) {
|
if (attachment._err_msg.empty()) {
|
||||||
//上次鉴权成功
|
//上次鉴权成功
|
||||||
if(cookie_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;
|
||||||
@ -274,7 +287,7 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
|||||||
//上次鉴权失败,但是如果url参数发生变更,那么也重新鉴权下
|
//上次鉴权失败,但是如果url参数发生变更,那么也重新鉴权下
|
||||||
if (parser.Params().empty() || parser.Params() == cookie->getUid()) {
|
if (parser.Params().empty() || parser.Params() == cookie->getUid()) {
|
||||||
//url参数未变,或者本来就没有url参数,那么判断本次请求为重复请求,无访问权限
|
//url参数未变,或者本来就没有url参数,那么判断本次请求为重复请求,无访问权限
|
||||||
callback(accessErr, cookie_from_header ? nullptr : cookie);
|
callback(attachment._err_msg, cookie_from_header ? nullptr : cookie);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,18 +311,20 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
|||||||
cookie = HttpCookieManager::Instance().addCookie(kCookieName, uid, cookieLifeSecond);
|
cookie = HttpCookieManager::Instance().addCookie(kCookieName, uid, cookieLifeSecond);
|
||||||
//对cookie上锁
|
//对cookie上锁
|
||||||
auto lck = cookie->getLock();
|
auto lck = cookie->getLock();
|
||||||
|
HttpCookieAttachment attachment;
|
||||||
//记录用户能访问的路径
|
//记录用户能访问的路径
|
||||||
(*cookie)[kCookiePathKey].set<string>(cookie_path);
|
attachment._path = cookie_path;
|
||||||
//记录能否访问
|
//记录能否访问
|
||||||
(*cookie)[kAccessErrKey].set<string>(errMsg);
|
attachment._err_msg = errMsg;
|
||||||
//记录访问的是否为hls
|
//记录访问的是否为hls
|
||||||
(*cookie)[kAccessHls].set<bool>(is_hls);
|
attachment._is_hls = is_hls;
|
||||||
if(is_hls){
|
if(is_hls){
|
||||||
//hls相关信息
|
//hls相关信息
|
||||||
(*cookie)[kHlsData].set<HlsCookieData>(mediaInfo);
|
attachment._hls_data = std::make_shared<HlsCookieData>(mediaInfo);
|
||||||
//hls未查找MediaSource
|
//hls未查找MediaSource
|
||||||
(*cookie)[kHlsHaveFindMediaSource].set<bool>(false);
|
attachment._have_find_media_source = false;
|
||||||
}
|
}
|
||||||
|
(*cookie)[kCookieName].set<HttpCookieAttachment>(std::move(attachment));
|
||||||
callback(errMsg, cookie);
|
callback(errMsg, cookie);
|
||||||
}else{
|
}else{
|
||||||
callback(errMsg, nullptr);
|
callback(errMsg, nullptr);
|
||||||
@ -382,7 +397,7 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
|||||||
//文件鉴权失败
|
//文件鉴权失败
|
||||||
StrCaseMap headerOut;
|
StrCaseMap headerOut;
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kCookiePathKey].get<string>());
|
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));
|
||||||
return;
|
return;
|
||||||
@ -391,14 +406,14 @@ 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) {
|
||||||
httpHeader["Set-Cookie"] = cookie->getCookie((*cookie)[kCookiePathKey].get<string>());
|
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();
|
cookie->getLock();
|
||||||
auto is_hls = (*cookie)[kAccessHls].get<bool>();
|
auto is_hls = (*cookie)[kCookieName].get<HttpCookieAttachment>()._is_hls;
|
||||||
if (is_hls) {
|
if (is_hls) {
|
||||||
(*cookie)[kHlsData].get<HlsCookieData>().addByteUsage(body->remainSize());
|
(*cookie)[kCookieName].get<HttpCookieAttachment>()._hls_data->addByteUsage(body->remainSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cb(codeOut.data(), getContentType(strFile.data()), headerOut, body);
|
cb(codeOut.data(), getContentType(strFile.data()), headerOut, body);
|
||||||
@ -406,18 +421,16 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
|||||||
invoker.responseFile(parser.getValues(), httpHeader, strFile);
|
invoker.responseFile(parser.getValues(), httpHeader, strFile);
|
||||||
};
|
};
|
||||||
|
|
||||||
//如果程序未正常退出,会残余上次的hls文件,所以判断hls直播是否存在的关键不是文件存在与否
|
|
||||||
//而是应该判断HlsMediaSource是否已注册,但是这样会每次获取m3u8文件时都会用MediaSource::findAsync判断一次
|
|
||||||
//会导致程序性能低下,所以我们应该在cookie声明周期的第一次判断HlsMediaSource是否已经注册,后续通过文件存在与否判断
|
|
||||||
if (!is_hls) {
|
if (!is_hls) {
|
||||||
//不是hls,直接回复文件或404
|
//不是hls,直接回复文件或404
|
||||||
response_file(cookie, cb, strFile, parser);
|
response_file(cookie, cb, strFile, parser);
|
||||||
} else {
|
} else {
|
||||||
|
//是hls直播,判断是否存在
|
||||||
bool have_find_media_src = false;
|
bool have_find_media_src = false;
|
||||||
if(cookie){
|
if(cookie){
|
||||||
have_find_media_src = (*cookie)[kHlsHaveFindMediaSource].get<bool>();
|
have_find_media_src = (*cookie)[kCookieName].get<HttpCookieAttachment>()._have_find_media_source;
|
||||||
if(!have_find_media_src){
|
if(!have_find_media_src){
|
||||||
(*cookie)[kHlsHaveFindMediaSource].set<bool>(true);
|
(*cookie)[kCookieName].get<HttpCookieAttachment>()._have_find_media_source = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(have_find_media_src){
|
if(have_find_media_src){
|
||||||
@ -476,7 +489,7 @@ void HttpFileManager::onAccessPath(TcpSession &sender, Parser &parser, const Htt
|
|||||||
}
|
}
|
||||||
StrCaseMap headerOut;
|
StrCaseMap headerOut;
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kCookiePathKey].get<string>());
|
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kCookieName].get<HttpCookieAttachment>()._path);
|
||||||
}
|
}
|
||||||
cb(errMsg.empty() ? "200 OK" : "401 Unauthorized", "text/html", headerOut, std::make_shared<HttpStringBody>(strMenu));
|
cb(errMsg.empty() ? "200 OK" : "401 Unauthorized", "text/html", headerOut, std::make_shared<HttpStringBody>(strMenu));
|
||||||
});
|
});
|
||||||
|
@ -91,6 +91,7 @@ private:
|
|||||||
|
|
||||||
class HlsCookieData{
|
class HlsCookieData{
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<HlsCookieData> Ptr;
|
||||||
HlsCookieData(const MediaInfo &info);
|
HlsCookieData(const MediaInfo &info);
|
||||||
~HlsCookieData();
|
~HlsCookieData();
|
||||||
void addByteUsage(uint64_t bytes);
|
void addByteUsage(uint64_t bytes);
|
||||||
|
Loading…
Reference in New Issue
Block a user