mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-23 03:10:04 +08:00
http文件鉴权支持自定义错误提示
This commit is contained in:
parent
cfbdda0698
commit
c7cc082d95
@ -673,34 +673,23 @@ void installWebApi() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
API_REGIST(hook,on_http_access,{
|
API_REGIST(hook,on_http_access,{
|
||||||
#if 0
|
|
||||||
//能访问根目录以及根目录下所有文件10分钟
|
|
||||||
val["path"] = "/";
|
|
||||||
val["second"] = 10 * 60;
|
|
||||||
#else
|
|
||||||
//在这里根据allArgs["params"](url参数)来判断该http客户端是否有权限访问该文件
|
//在这里根据allArgs["params"](url参数)来判断该http客户端是否有权限访问该文件
|
||||||
if(!checkAccess(allArgs["params"])){
|
if(!checkAccess(allArgs["params"])){
|
||||||
//无访问权限
|
//无访问权限
|
||||||
|
val["err"] = "无访问权限";
|
||||||
|
//仅限制访问当前目录
|
||||||
val["path"] = "";
|
val["path"] = "";
|
||||||
//标记该客户端无权限1分钟,1分钟之内它凭此cookie访问将都无权限
|
//标记该客户端无权限1分钟
|
||||||
//如果客户端不支持cookie,那么可以根据url参数来追踪用户,请参考kBroadcastTrackHttpClient事件
|
|
||||||
//如果服务器未处理kBroadcastTrackHttpClient事件,那么ZLMediaKit会根据ip和端口追踪用户
|
|
||||||
val["second"] = 60;
|
val["second"] = 60;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//只能访问本文件,且只授权10分钟,访问其他文件都要另外授权
|
//可以访问
|
||||||
if(allArgs["is_dir"].as<bool>()){
|
val["err"] = "";
|
||||||
//访问的是目录,该授权cookie只对该目录有效
|
//只能访问当前目录
|
||||||
val["path"] = (string)allArgs["path"];
|
val["path"] = "";
|
||||||
}else{
|
//该http客户端用户被授予10分钟的访问权限,该权限仅限访问当前目录
|
||||||
//访问的是文件,那么我们授予客户端访问所在目录的权限
|
|
||||||
string dir = allArgs["path"].substr(0,allArgs["path"].rfind("/") + 1);
|
|
||||||
val["path"] = dir;
|
|
||||||
}
|
|
||||||
//该http客户端用户被授予10分钟的访问权限,该权限仅限访问特定目录
|
|
||||||
val["second"] = 10 * 60;
|
val["second"] = 10 * 60;
|
||||||
#endif
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -399,13 +399,13 @@ void installWebHook(){
|
|||||||
NoticeCenter::Instance().addListener(nullptr,Broadcast::kBroadcastHttpAccess,[](BroadcastHttpAccessArgs){
|
NoticeCenter::Instance().addListener(nullptr,Broadcast::kBroadcastHttpAccess,[](BroadcastHttpAccessArgs){
|
||||||
if(sender.get_peer_ip() == "127.0.0.1" && args._param_strs == hook_adminparams){
|
if(sender.get_peer_ip() == "127.0.0.1" && args._param_strs == hook_adminparams){
|
||||||
//如果是本机或超级管理员访问,那么不做访问鉴权;权限有效期1个小时
|
//如果是本机或超级管理员访问,那么不做访问鉴权;权限有效期1个小时
|
||||||
invoker("/",60 * 60);
|
invoker("","",60 * 60);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!hook_enable || hook_http_access.empty()){
|
if(!hook_enable || hook_http_access.empty()){
|
||||||
//未开启http文件访问鉴权,那么允许访问,但是每次访问都要鉴权;
|
//未开启http文件访问鉴权,那么允许访问,但是每次访问都要鉴权;
|
||||||
//因为后续随时都可能开启鉴权(重载配置文件后可能重新开启鉴权)
|
//因为后续随时都可能开启鉴权(重载配置文件后可能重新开启鉴权)
|
||||||
invoker("/",0);
|
invoker("","",0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,15 +423,13 @@ void installWebHook(){
|
|||||||
do_http_hook(hook_http_access,body, [invoker](const Value &obj,const string &err){
|
do_http_hook(hook_http_access,body, [invoker](const Value &obj,const string &err){
|
||||||
if(!err.empty()){
|
if(!err.empty()){
|
||||||
//如果接口访问失败,那么仅限本次没有访问http服务器的权限
|
//如果接口访问失败,那么仅限本次没有访问http服务器的权限
|
||||||
invoker("",0);
|
invoker(err,"",0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//path参数是该客户端能访问的顶端目录,该目录下的所有文件它都能访问
|
//err参数代表不能访问的原因,空则代表可以访问
|
||||||
//second参数规定该cookie超时时间,超过这个时间后,用户需要重新鉴权
|
//path参数是该客户端能访问或被禁止的顶端目录,如果path为空字符串,则表述为当前目录
|
||||||
//如果path为空字符串,则为禁止访问任何目录
|
//second参数规定该cookie超时时间,如果second为0,本次鉴权结果不缓存
|
||||||
//如果second为0,本次鉴权结果不缓存
|
invoker(obj["err"].asString(),obj["path"].asString(),obj["second"].asInt());
|
||||||
//如果被禁止访问文件,在cookie有效期内,假定再次访问的url参数变了,那么也能立即触发重新鉴权操作
|
|
||||||
invoker(obj["path"].asString(),obj["second"].asInt());
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,10 @@ bool HttpServerCookie::isExpired() {
|
|||||||
return _ticker.elapsedTime() > _max_elapsed * 1000;
|
return _ticker.elapsedTime() > _max_elapsed * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<lock_guard<mutex> > HttpServerCookie::getLock(){
|
||||||
|
return std::make_shared<lock_guard<mutex> >(_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
string HttpServerCookie::cookieExpireTime() const{
|
string HttpServerCookie::cookieExpireTime() const{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
time_t tt = time(NULL) + _max_elapsed;
|
time_t tt = time(NULL) + _max_elapsed;
|
||||||
@ -105,7 +109,7 @@ void HttpCookieManager::onManager() {
|
|||||||
for (auto it_cookie = it_name->second.begin() ; it_cookie != it_name->second.end() ; ){
|
for (auto it_cookie = it_name->second.begin() ; it_cookie != it_name->second.end() ; ){
|
||||||
if(it_cookie->second->isExpired()){
|
if(it_cookie->second->isExpired()){
|
||||||
//cookie过期,移除记录
|
//cookie过期,移除记录
|
||||||
WarnL << it_cookie->second->getUid() << " cookie过期";
|
DebugL << it_cookie->second->getUid() << " cookie过期:" << it_cookie->second->getCookie();
|
||||||
it_cookie = it_name->second.erase(it_cookie);
|
it_cookie = it_name->second.erase(it_cookie);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -114,7 +118,7 @@ void HttpCookieManager::onManager() {
|
|||||||
|
|
||||||
if(it_name->second.empty()){
|
if(it_name->second.empty()){
|
||||||
//该类型下没有任何cooki记录,移除之
|
//该类型下没有任何cooki记录,移除之
|
||||||
WarnL << "该path下没有任何cooki记录:" << it_name->first;
|
DebugL << "该path下没有任何cooki记录:" << it_name->first;
|
||||||
it_name = _map_cookie.erase(it_name);
|
it_name = _map_cookie.erase(it_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -152,6 +156,7 @@ HttpServerCookie::Ptr HttpCookieManager::getCookie(const string &cookie_name,con
|
|||||||
}
|
}
|
||||||
if(it_cookie->second->isExpired()){
|
if(it_cookie->second->isExpired()){
|
||||||
//cookie过期
|
//cookie过期
|
||||||
|
DebugL << "cookie过期:" << it_cookie->second->getCookie();
|
||||||
it_name->second.erase(it_cookie);
|
it_name->second.erase(it_cookie);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,12 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool isExpired();
|
bool isExpired();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取区域锁
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::shared_ptr<lock_guard<mutex> > getLock();
|
||||||
private:
|
private:
|
||||||
string cookieExpireTime() const ;
|
string cookieExpireTime() const ;
|
||||||
private:
|
private:
|
||||||
@ -110,6 +116,7 @@ private:
|
|||||||
string _cookie_uuid;
|
string _cookie_uuid;
|
||||||
uint64_t _max_elapsed;
|
uint64_t _max_elapsed;
|
||||||
Ticker _ticker;
|
Ticker _ticker;
|
||||||
|
mutex _mtx;
|
||||||
std::weak_ptr<HttpCookieManager> _manager;
|
std::weak_ptr<HttpCookieManager> _manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -49,11 +49,10 @@ using namespace toolkit;
|
|||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
static int kSockFlags = SOCKET_DEFAULE_FLAGS | FLAG_MORE;
|
static int kSockFlags = SOCKET_DEFAULE_FLAGS | FLAG_MORE;
|
||||||
|
static int kHlsCookieSecond = 10 * 60;
|
||||||
static const string kCookieName = "ZL_COOKIE";
|
static const string kCookieName = "ZL_COOKIE";
|
||||||
static const string kAccessPathKey = "kAccessPathKey";
|
static const string kCookiePathKey = "kCookiePathKey";
|
||||||
static const string kAccessDirUnauthorized = "你没有权限访问该目录";
|
static const string kAccessErrKey = "kAccessErrKey";
|
||||||
static const string kAccessFileUnauthorized = "你没有权限访问该文件";
|
|
||||||
|
|
||||||
|
|
||||||
string dateStr() {
|
string dateStr() {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
@ -346,13 +345,8 @@ static inline bool checkHls(BroadcastHttpAccessArgs){
|
|||||||
}
|
}
|
||||||
//访问的hls.m3u8结尾,我们转换成kBroadcastMediaPlayed事件
|
//访问的hls.m3u8结尾,我们转换成kBroadcastMediaPlayed事件
|
||||||
Broadcast::AuthInvoker mediaAuthInvoker = [invoker,path](const string &err){
|
Broadcast::AuthInvoker mediaAuthInvoker = [invoker,path](const string &err){
|
||||||
if(err.empty() ){
|
//cookie有效期为kHlsCookieSecond
|
||||||
//鉴权通过,允许播放一个小时
|
invoker(err,"",kHlsCookieSecond);
|
||||||
invoker(path.substr(0,path.rfind("/") + 1),60 * 60);
|
|
||||||
}else{
|
|
||||||
//鉴权失败,10秒内不允许播放hls
|
|
||||||
invoker("",10);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
auto args_copy = args;
|
auto args_copy = args;
|
||||||
@ -360,13 +354,13 @@ static inline bool checkHls(BroadcastHttpAccessArgs){
|
|||||||
return NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPlayed,args_copy,mediaAuthInvoker,sender);
|
return NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPlayed,args_copy,mediaAuthInvoker,sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void HttpSession::canAccessPath(const string &path_in,bool is_dir,const function<void(bool canAccess,const HttpServerCookie::Ptr &cookie)> &callback_in){
|
inline void HttpSession::canAccessPath(const string &path_in,bool is_dir,const function<void(const string &errMsg,const HttpServerCookie::Ptr &cookie)> &callback_in){
|
||||||
auto path = path_in;
|
auto path = path_in;
|
||||||
replace(const_cast<string &>(path),"//","/");
|
replace(const_cast<string &>(path),"//","/");
|
||||||
|
|
||||||
auto callback = [callback_in,this](bool canAccess,const HttpServerCookie::Ptr &cookie){
|
auto callback = [callback_in,this](const string &errMsg,const HttpServerCookie::Ptr &cookie){
|
||||||
try {
|
try {
|
||||||
callback_in(canAccess,cookie);
|
callback_in(errMsg,cookie);
|
||||||
}catch (SockException &ex){
|
}catch (SockException &ex){
|
||||||
if(ex){
|
if(ex){
|
||||||
shutdown(ex);
|
shutdown(ex);
|
||||||
@ -386,48 +380,63 @@ inline void HttpSession::canAccessPath(const string &path_in,bool is_dir,const f
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(cookie){
|
if(cookie){
|
||||||
//找到了cookie
|
//找到了cookie,对cookie上锁先
|
||||||
auto accessPath = (*cookie)[kAccessPathKey];
|
auto lck = cookie->getLock();
|
||||||
if (!accessPath.empty() && path.find(accessPath) == 0) {
|
auto accessErr = (*cookie)[kAccessErrKey];
|
||||||
//用户是有权限访问该目录
|
if (accessErr.empty() && path.find((*cookie)[kCookiePathKey]) == 0) {
|
||||||
callback(true, nullptr);
|
//用户有权限访问该目录
|
||||||
|
callback("", nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//用户无权限访问,我们看看用户的url参数变了没有
|
//用户无权限访问,我们看看用户的url参数变了没有
|
||||||
//如果url参数变了,那么重新鉴权
|
if (_parser.Params().empty() || _parser.Params() == cookie->getUid()) {
|
||||||
if (cookie->getUid() == _parser.Params()) {
|
|
||||||
//url参数未变,那么判断无权限访问
|
//url参数未变,那么判断无权限访问
|
||||||
callback(false, nullptr);
|
callback(accessErr.empty() ? "无权限访问该目录" : accessErr, nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//如果url参数变了,那么旧cookie失效,我们重新鉴权
|
||||||
|
HttpCookieManager::Instance().delCookie(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
//该用户从来未获取过cookie,这个时候我们广播是否允许该用户访问该http目录
|
//该用户从来未获取过cookie,这个时候我们广播是否允许该用户访问该http目录
|
||||||
weak_ptr<HttpSession> weakSelf = dynamic_pointer_cast<HttpSession>(shared_from_this());
|
weak_ptr<HttpSession> weakSelf = dynamic_pointer_cast<HttpSession>(shared_from_this());
|
||||||
HttpAccessPathInvoker accessPathInvoker = [weakSelf, callback, uid , path] (const string &accessPath, int cookieLifeSecond) {
|
HttpAccessPathInvoker accessPathInvoker = [weakSelf,callback,uid,path,is_dir] (const string &errMsg,const string &cookie_path_in, int cookieLifeSecond) {
|
||||||
|
string cookie_path = cookie_path_in;
|
||||||
|
if(cookie_path.empty()){
|
||||||
|
//如果未设置鉴权目录,那么我们采用当前目录
|
||||||
|
if(is_dir){
|
||||||
|
cookie_path = path;
|
||||||
|
}else{
|
||||||
|
cookie_path = path.substr(0,path.rfind("/") + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpServerCookie::Ptr cookie ;
|
||||||
|
if(cookieLifeSecond) {
|
||||||
|
//本次鉴权设置了有效期,我们把鉴权结果缓存在cookie中
|
||||||
|
cookie = HttpCookieManager::Instance().addCookie(kCookieName, uid, cookieLifeSecond);
|
||||||
|
//对cookie上锁
|
||||||
|
auto lck = cookie->getLock();
|
||||||
|
//记录用户能访问的路径
|
||||||
|
(*cookie)[kCookiePathKey] = cookie_path;
|
||||||
|
//记录能否访问
|
||||||
|
(*cookie)[kAccessErrKey] = errMsg;
|
||||||
|
}
|
||||||
|
|
||||||
auto strongSelf = weakSelf.lock();
|
auto strongSelf = weakSelf.lock();
|
||||||
if (!strongSelf) {
|
if (!strongSelf) {
|
||||||
//自己已经销毁
|
//自己已经销毁
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strongSelf->async([weakSelf, callback, accessPath, cookieLifeSecond, uid , path]() {
|
strongSelf->async([weakSelf,callback,cookie,errMsg]() {
|
||||||
//切换到自己线程
|
//切换到自己线程
|
||||||
auto strongSelf = weakSelf.lock();
|
auto strongSelf = weakSelf.lock();
|
||||||
if (!strongSelf) {
|
if (!strongSelf) {
|
||||||
//自己已经销毁
|
//自己已经销毁
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(cookieLifeSecond){
|
callback(errMsg, cookie);
|
||||||
//我们给用户生成追踪cookie
|
|
||||||
auto cookie = HttpCookieManager::Instance().addCookie(kCookieName,uid,cookieLifeSecond);
|
|
||||||
//记录用户能访问的路径
|
|
||||||
(*cookie)[kAccessPathKey] = accessPath;
|
|
||||||
//判断该用户是否有权限访问该目录,并且设置客户端cookie
|
|
||||||
callback(!accessPath.empty() && path.find(accessPath) == 0, cookie);
|
|
||||||
}else{
|
|
||||||
//仅限本次访问文件
|
|
||||||
callback(!accessPath.empty() && path.find(accessPath) == 0, nullptr);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -439,7 +448,7 @@ inline void HttpSession::canAccessPath(const string &path_in,bool is_dir,const f
|
|||||||
bool flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastHttpAccess,_parser,_mediaInfo,path,is_dir,accessPathInvoker,*this);
|
bool flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastHttpAccess,_parser,_mediaInfo,path,is_dir,accessPathInvoker,*this);
|
||||||
if(!flag){
|
if(!flag){
|
||||||
//此事件无人监听,我们默认都有权限访问
|
//此事件无人监听,我们默认都有权限访问
|
||||||
callback(true, nullptr);
|
callback("", nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -497,15 +506,16 @@ inline void HttpSession::Handle_Req_GET(int64_t &content_len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//判断是否有权限访问该目录
|
//判断是否有权限访问该目录
|
||||||
canAccessPath(_parser.Url(),true,[this,bClose,strFile,strMeun](bool canAccess,const HttpServerCookie::Ptr &cookie){
|
auto path = _parser.Url();
|
||||||
if(!canAccess){
|
canAccessPath(_parser.Url(),true,[this,bClose,strFile,strMeun,path](const string &errMsg,const HttpServerCookie::Ptr &cookie){
|
||||||
const_cast<string &>(strMeun) = kAccessDirUnauthorized;
|
if(!errMsg.empty()){
|
||||||
|
const_cast<string &>(strMeun) = errMsg;
|
||||||
}
|
}
|
||||||
auto headerOut = makeHttpHeader(bClose,strMeun.size());
|
auto headerOut = makeHttpHeader(bClose,strMeun.size());
|
||||||
if(cookie){
|
if(cookie){
|
||||||
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kAccessPathKey]);
|
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kCookiePathKey]);
|
||||||
}
|
}
|
||||||
sendResponse(canAccess ? "200 OK" : "401 Unauthorized" , headerOut, strMeun);
|
sendResponse(errMsg.empty() ? "200 OK" : "401 Unauthorized" , headerOut, strMeun);
|
||||||
throw SockException(bClose ? Err_shutdown : Err_success,"close connection after access folder");
|
throw SockException(bClose ? Err_shutdown : Err_success,"close connection after access folder");
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -534,7 +544,16 @@ inline void HttpSession::Handle_Req_GET(int64_t &content_len) {
|
|||||||
|
|
||||||
auto parser = _parser;
|
auto parser = _parser;
|
||||||
//判断是否有权限访问该文件
|
//判断是否有权限访问该文件
|
||||||
canAccessPath(_parser.Url(),false,[this,parser,tFileStat,pFilePtr,bClose,strFile](bool canAccess,const HttpServerCookie::Ptr &cookie){
|
canAccessPath(_parser.Url(),false,[this,parser,tFileStat,pFilePtr,bClose,strFile](const string &errMsg,const HttpServerCookie::Ptr &cookie){
|
||||||
|
if(!errMsg.empty()){
|
||||||
|
auto headerOut = makeHttpHeader(bClose,errMsg.size());
|
||||||
|
if(cookie){
|
||||||
|
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kCookiePathKey]);
|
||||||
|
}
|
||||||
|
sendResponse("401 Unauthorized" , headerOut, errMsg);
|
||||||
|
throw SockException(bClose ? Err_shutdown : Err_success,"close connection after access file failed");
|
||||||
|
}
|
||||||
|
|
||||||
//判断是不是分节下载
|
//判断是不是分节下载
|
||||||
auto &strRange = parser["Range"];
|
auto &strRange = parser["Range"];
|
||||||
int64_t iRangeStart = 0, iRangeEnd = 0;
|
int64_t iRangeStart = 0, iRangeEnd = 0;
|
||||||
@ -552,8 +571,7 @@ inline void HttpSession::Handle_Req_GET(int64_t &content_len) {
|
|||||||
pcHttpResult = "206 Partial Content";
|
pcHttpResult = "206 Partial Content";
|
||||||
fseek(pFilePtr.get(), iRangeStart, SEEK_SET);
|
fseek(pFilePtr.get(), iRangeStart, SEEK_SET);
|
||||||
}
|
}
|
||||||
auto httpHeader = canAccess ? makeHttpHeader(bClose, iRangeEnd - iRangeStart + 1, get_mime_type(strFile.data()))
|
auto httpHeader = makeHttpHeader(bClose, iRangeEnd - iRangeStart + 1, get_mime_type(strFile.data()));
|
||||||
: makeHttpHeader(bClose, kAccessFileUnauthorized.size());
|
|
||||||
if (strRange.size() != 0) {
|
if (strRange.size() != 0) {
|
||||||
//分节下载返回Content-Range头
|
//分节下载返回Content-Range头
|
||||||
httpHeader.emplace("Content-Range",StrPrinter<<"bytes " << iRangeStart << "-" << iRangeEnd << "/" << tFileStat.st_size<< endl);
|
httpHeader.emplace("Content-Range",StrPrinter<<"bytes " << iRangeStart << "-" << iRangeEnd << "/" << tFileStat.st_size<< endl);
|
||||||
@ -564,12 +582,10 @@ inline void HttpSession::Handle_Req_GET(int64_t &content_len) {
|
|||||||
httpHeader["Access-Control-Allow-Credentials"] = "true";
|
httpHeader["Access-Control-Allow-Credentials"] = "true";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cookie){
|
|
||||||
httpHeader["Set-Cookie"] = cookie->getCookie((*cookie)[kAccessPathKey]);
|
|
||||||
}
|
|
||||||
//先回复HTTP头部分
|
//先回复HTTP头部分
|
||||||
sendResponse(canAccess ? pcHttpResult : "401 Unauthorized" , httpHeader,canAccess ? "" : kAccessFileUnauthorized);
|
sendResponse(pcHttpResult,httpHeader,"");
|
||||||
if (!canAccess || iRangeEnd - iRangeStart < 0) {
|
|
||||||
|
if (iRangeEnd - iRangeStart < 0) {
|
||||||
//文件是空的!
|
//文件是空的!
|
||||||
throw SockException(bClose ? Err_shutdown : Err_success,"close connection after access file");
|
throw SockException(bClose ? Err_shutdown : Err_success,"close connection after access file");
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,12 @@ public:
|
|||||||
const KeyValue &headerOut,
|
const KeyValue &headerOut,
|
||||||
const string &contentOut)> HttpResponseInvoker;
|
const string &contentOut)> HttpResponseInvoker;
|
||||||
|
|
||||||
typedef std::function<void(const string &accessPath, int cookieLifeSecond)> HttpAccessPathInvoker;
|
/**
|
||||||
|
* @param errMsg 如果为空,则代表鉴权通过,否则为错误提示
|
||||||
|
* @param accessPath 运行或禁止访问的根目录
|
||||||
|
* @param cookieLifeSecond 鉴权cookie有效期
|
||||||
|
**/
|
||||||
|
typedef std::function<void(const string &errMsg,const string &accessPath, int cookieLifeSecond)> HttpAccessPathInvoker;
|
||||||
|
|
||||||
HttpSession(const Socket::Ptr &pSock);
|
HttpSession(const Socket::Ptr &pSock);
|
||||||
virtual ~HttpSession();
|
virtual ~HttpSession();
|
||||||
@ -125,7 +130,7 @@ private:
|
|||||||
* @param is_dir path是否为目录
|
* @param is_dir path是否为目录
|
||||||
* @param callback 有权限或无权限的回调
|
* @param callback 有权限或无权限的回调
|
||||||
*/
|
*/
|
||||||
inline void canAccessPath(const string &path,bool is_dir,const function<void(bool canAccess,const HttpServerCookie::Ptr &cookie)> &callback);
|
inline void canAccessPath(const string &path,bool is_dir,const function<void(const string &errMsg,const HttpServerCookie::Ptr &cookie)> &callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户唯一识别id
|
* 获取用户唯一识别id
|
||||||
|
Loading…
Reference in New Issue
Block a user