Commit 042981c4 by xiongziliang

完善rtsp服务器错误提示

parent c8b192fa
...@@ -172,7 +172,7 @@ void MediaReader::startReadMP4() { ...@@ -172,7 +172,7 @@ void MediaReader::startReadMP4() {
return true; return true;
} }
bool MediaReader::close(MediaSource &sender,bool force){ bool MediaReader::close(MediaSource &sender,bool force){
if(!force && _mediaMuxer->readerCount() != 0 ){ if(!_mediaMuxer || (!force && _mediaMuxer->readerCount() != 0)){
return false; return false;
} }
_timer.reset(); _timer.reset();
......
...@@ -146,7 +146,7 @@ void PlayerProxy::rePlay(const string &strUrl,int iFailedCnt){ ...@@ -146,7 +146,7 @@ void PlayerProxy::rePlay(const string &strUrl,int iFailedCnt){
}, getPoller()); }, getPoller());
} }
bool PlayerProxy::close(MediaSource &sender,bool force) { bool PlayerProxy::close(MediaSource &sender,bool force) {
if(!force && _mediaMuxer->readerCount() != 0){ if(!_mediaMuxer || (!force && _mediaMuxer->readerCount() != 0)){
return false; return false;
} }
......
...@@ -149,7 +149,7 @@ void RtspSession::onWholeRtspPacket(Parser &parser) { ...@@ -149,7 +149,7 @@ void RtspSession::onWholeRtspPacket(Parser &parser) {
_mediaInfo.parse(parser.FullUrl()); _mediaInfo.parse(parser.FullUrl());
} }
typedef bool (RtspSession::*rtsp_request_handler)(const Parser &parser); typedef void (RtspSession::*rtsp_request_handler)(const Parser &parser);
static unordered_map<string, rtsp_request_handler> s_handler_map; static unordered_map<string, rtsp_request_handler> s_handler_map;
static onceToken token( []() { static onceToken token( []() {
s_handler_map.emplace("OPTIONS",&RtspSession::handleReq_Options); s_handler_map.emplace("OPTIONS",&RtspSession::handleReq_Options);
...@@ -167,14 +167,23 @@ void RtspSession::onWholeRtspPacket(Parser &parser) { ...@@ -167,14 +167,23 @@ void RtspSession::onWholeRtspPacket(Parser &parser) {
}, []() {}); }, []() {});
auto it = s_handler_map.find(strCmd); auto it = s_handler_map.find(strCmd);
if (it != s_handler_map.end()) { if (it == s_handler_map.end()) {
sendRtspResponse("403 Forbidden");
shutdown(SockException(Err_shutdown,StrPrinter << "403 Forbidden:" << strCmd));
return;
}
auto &fun = it->second; auto &fun = it->second;
if(!(this->*fun)(parser)){ try {
shutdown(SockException(Err_shutdown,"self close")); (this->*fun)(parser);
}catch (SockException &ex){
if(ex){
shutdown(ex);
} }
} else{ }catch (exception &ex){
shutdown(SockException(Err_shutdown,StrPrinter << "403 Forbidden:" << strCmd)); shutdown(SockException(Err_shutdown,ex.what()));
} }
parser.Clear();
} }
void RtspSession::onRtpPacket(const char *data, uint64_t len) { void RtspSession::onRtpPacket(const char *data, uint64_t len) {
...@@ -209,13 +218,12 @@ int64_t RtspSession::getContentLength(Parser &parser) { ...@@ -209,13 +218,12 @@ int64_t RtspSession::getContentLength(Parser &parser) {
} }
bool RtspSession::handleReq_Options(const Parser &parser) { void RtspSession::handleReq_Options(const Parser &parser) {
//支持这些命令 //支持这些命令
sendRtspResponse("200 OK",{"Public" , "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, ANNOUNCE, RECORD, SET_PARAMETER, GET_PARAMETER"}); sendRtspResponse("200 OK",{"Public" , "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, ANNOUNCE, RECORD, SET_PARAMETER, GET_PARAMETER"});
return true;
} }
bool RtspSession::handleReq_ANNOUNCE(const Parser &parser) { void RtspSession::handleReq_ANNOUNCE(const Parser &parser) {
auto src = dynamic_pointer_cast<RtmpMediaSource>(MediaSource::find(RTSP_SCHEMA, auto src = dynamic_pointer_cast<RtmpMediaSource>(MediaSource::find(RTSP_SCHEMA,
_mediaInfo._vhost, _mediaInfo._vhost,
_mediaInfo._app, _mediaInfo._app,
...@@ -223,12 +231,12 @@ bool RtspSession::handleReq_ANNOUNCE(const Parser &parser) { ...@@ -223,12 +231,12 @@ bool RtspSession::handleReq_ANNOUNCE(const Parser &parser) {
false)); false));
if(src){ if(src){
sendRtspResponse("406 Not Acceptable", {"Content-Type", "text/plain"}, "Already publishing."); sendRtspResponse("406 Not Acceptable", {"Content-Type", "text/plain"}, "Already publishing.");
WarnP(this) << "ANNOUNCE:" string err = StrPrinter << "ANNOUNCE:"
<< "Already publishing:" << "Already publishing:"
<< _mediaInfo._vhost << " " << _mediaInfo._vhost << " "
<< _mediaInfo._app << " " << _mediaInfo._app << " "
<< _mediaInfo._streamid << endl; << _mediaInfo._streamid << endl;
return false; throw SockException(Err_shutdown,err);
} }
_strSession = makeRandStr(12); _strSession = makeRandStr(12);
...@@ -239,13 +247,12 @@ bool RtspSession::handleReq_ANNOUNCE(const Parser &parser) { ...@@ -239,13 +247,12 @@ bool RtspSession::handleReq_ANNOUNCE(const Parser &parser) {
_pushSrc->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this())); _pushSrc->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this()));
_pushSrc->onGetSDP(_strSdp); _pushSrc->onGetSDP(_strSdp);
sendRtspResponse("200 OK"); sendRtspResponse("200 OK");
return true;
} }
bool RtspSession::handleReq_RECORD(const Parser &parser){ void RtspSession::handleReq_RECORD(const Parser &parser){
if (_aTrackInfo.empty() || parser["Session"] != _strSession) { if (_aTrackInfo.empty() || parser["Session"] != _strSession) {
send_SessionNotFound(); send_SessionNotFound();
return false; throw SockException(Err_shutdown,_aTrackInfo.empty() ? "can not find any availabe track when record" : "session not found when record");
} }
auto onRes = [this](const string &err){ auto onRes = [this](const string &err){
bool authSuccess = err.empty(); bool authSuccess = err.empty();
...@@ -297,10 +304,9 @@ bool RtspSession::handleReq_RECORD(const Parser &parser){ ...@@ -297,10 +304,9 @@ bool RtspSession::handleReq_RECORD(const Parser &parser){
//该事件无人监听,默认不鉴权 //该事件无人监听,默认不鉴权
onRes(""); onRes("");
} }
return true;
} }
bool RtspSession::handleReq_Describe(const Parser &parser) { void RtspSession::handleReq_Describe(const Parser &parser) {
_mediaInfo._schema = RTSP_SCHEMA; _mediaInfo._schema = RTSP_SCHEMA;
auto authorization = parser["Authorization"]; auto authorization = parser["Authorization"];
weak_ptr<RtspSession> weakSelf = dynamic_pointer_cast<RtspSession>(shared_from_this()); weak_ptr<RtspSession> weakSelf = dynamic_pointer_cast<RtspSession>(shared_from_this());
...@@ -337,13 +343,27 @@ bool RtspSession::handleReq_Describe(const Parser &parser) { ...@@ -337,13 +343,27 @@ bool RtspSession::handleReq_Describe(const Parser &parser) {
//该请求中的认证信息 //该请求中的认证信息
onGetRealm invoker = [weakSelf,authorization](const string &realm){ onGetRealm invoker = [weakSelf,authorization](const string &realm){
auto strongSelf = weakSelf.lock();
if(!strongSelf){
//本对象已经销毁
return;
}
//切换到自己的线程然后执行
strongSelf->async([weakSelf,realm,authorization](){
auto strongSelf = weakSelf.lock();
if(!strongSelf){
//本对象已经销毁
return;
}
if(realm.empty()){ if(realm.empty()){
//无需认证,回复sdp //无需认证,回复sdp
onAuthSuccess(weakSelf); strongSelf->onAuthSuccess();
return; return;
} }
//该流需要认证 //该流需要认证
onAuthUser(weakSelf,realm,authorization); strongSelf->onAuthUser(realm,authorization);
});
}; };
//广播是否需要认证事件 //广播是否需要认证事件
...@@ -355,101 +375,83 @@ bool RtspSession::handleReq_Describe(const Parser &parser) { ...@@ -355,101 +375,83 @@ bool RtspSession::handleReq_Describe(const Parser &parser) {
invoker(""); invoker("");
} }
}); });
return true;
} }
void RtspSession::onAuthSuccess(const weak_ptr<RtspSession> &weakSelf) { void RtspSession::onAuthSuccess() {
auto strongSelf = weakSelf.lock(); TraceP(this);
if(!strongSelf){ sendRtspResponse("200 OK",
//本对象已销毁 {"Content-Base",_strContentBase + "/",
return;
}
strongSelf->async([weakSelf](){
auto strongSelf = weakSelf.lock();
if(!strongSelf){
//本对象已销毁
return;
}
strongSelf->sendRtspResponse("200 OK",
{"Content-Base",strongSelf->_strContentBase + "/",
"x-Accept-Retransmit","our-retransmit", "x-Accept-Retransmit","our-retransmit",
"x-Accept-Dynamic-Rate","1" "x-Accept-Dynamic-Rate","1"
},strongSelf->_strSdp); },_strSdp);
});
} }
void RtspSession::onAuthFailed(const weak_ptr<RtspSession> &weakSelf,const string &realm) { void RtspSession::onAuthFailed(const string &realm,const string &why,bool close) {
auto strongSelf = weakSelf.lock();
if(!strongSelf){
//本对象已销毁
return;
}
strongSelf->async([weakSelf,realm]() {
auto strongSelf = weakSelf.lock();
if (!strongSelf) {
//本对象已销毁
return;
}
GET_CONFIG(bool,authBasic,Rtsp::kAuthBasic); GET_CONFIG(bool,authBasic,Rtsp::kAuthBasic);
if (!authBasic) { if (!authBasic) {
//我们需要客户端优先以md5方式认证 //我们需要客户端优先以md5方式认证
strongSelf->_strNonce = makeRandStr(32); _strNonce = makeRandStr(32);
strongSelf->sendRtspResponse("401 Unauthorized", sendRtspResponse("401 Unauthorized",
{"WWW-Authenticate", {"WWW-Authenticate",
StrPrinter << "Digest realm=\"" << realm << "\",nonce=\"" << strongSelf->_strNonce << "\"" }); StrPrinter << "Digest realm=\"" << realm << "\",nonce=\"" << _strNonce << "\"" });
}else { }else {
//当然我们也支持base64认证,但是我们不建议这样做 //当然我们也支持base64认证,但是我们不建议这样做
strongSelf->sendRtspResponse("401 Unauthorized", sendRtspResponse("401 Unauthorized",
{"WWW-Authenticate", {"WWW-Authenticate",
StrPrinter << "Basic realm=\"" << realm << "\"" }); StrPrinter << "Basic realm=\"" << realm << "\"" });
} }
}); if(close){
shutdown(SockException(Err_shutdown,StrPrinter << "401 Unauthorized:" << why));
}
} }
void RtspSession::onAuthBasic(const weak_ptr<RtspSession> &weakSelf,const string &realm,const string &strBase64){ void RtspSession::onAuthBasic(const string &realm,const string &strBase64){
//base64认证 //base64认证
char user_pwd_buf[512]; char user_pwd_buf[512];
av_base64_decode((uint8_t *)user_pwd_buf,strBase64.data(),strBase64.size()); av_base64_decode((uint8_t *)user_pwd_buf,strBase64.data(),strBase64.size());
auto user_pwd_vec = split(user_pwd_buf,":"); auto user_pwd_vec = split(user_pwd_buf,":");
if(user_pwd_vec.size() < 2){ if(user_pwd_vec.size() < 2){
//认证信息格式不合法,回复401 Unauthorized //认证信息格式不合法,回复401 Unauthorized
onAuthFailed(weakSelf,realm); onAuthFailed(realm,"can not find user and passwd when basic64 auth");
return; return;
} }
auto user = user_pwd_vec[0]; auto user = user_pwd_vec[0];
auto pwd = user_pwd_vec[1]; auto pwd = user_pwd_vec[1];
weak_ptr<RtspSession> weakSelf = dynamic_pointer_cast<RtspSession>(shared_from_this());
onAuth invoker = [pwd,realm,weakSelf](bool encrypted,const string &good_pwd){ onAuth invoker = [pwd,realm,weakSelf](bool encrypted,const string &good_pwd){
if(!encrypted && pwd == good_pwd){ auto strongSelf = weakSelf.lock();
//提供的是明文密码且匹配正确 if(!strongSelf){
onAuthSuccess(weakSelf); //本对象已经销毁
}else{ return;
//密码错误
onAuthFailed(weakSelf,realm);
} }
}; //切换到自己的线程执行
strongSelf->async([weakSelf,good_pwd,pwd,realm](){
auto strongSelf = weakSelf.lock(); auto strongSelf = weakSelf.lock();
if(!strongSelf){ if(!strongSelf){
//本对象已销毁 //本对象已经销毁
return;
}
//base64忽略encrypted参数,上层必须传入明文密码
if(pwd == good_pwd){
//提供的密码且匹配正确
strongSelf->onAuthSuccess();
return; return;
} }
//密码错误
strongSelf->onAuthFailed(realm,StrPrinter << "password mismatch when base64 auth:" << pwd << " != " << good_pwd);
});
};
//此时必须提供明文密码 //此时必须提供明文密码
if(!NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastOnRtspAuth,strongSelf->_mediaInfo,realm,user, true,invoker,*strongSelf)){ if(!NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastOnRtspAuth,_mediaInfo,realm,user, true,invoker,*this)){
//表明该流需要认证却没监听请求密码事件,这一般是大意的程序所为,警告之 //表明该流需要认证却没监听请求密码事件,这一般是大意的程序所为,警告之
WarnP(strongSelf.get()) << "请监听kBroadcastOnRtspAuth事件!"; WarnP(this) << "请监听kBroadcastOnRtspAuth事件!";
//但是我们还是忽略认证以便完成播放 //但是我们还是忽略认证以便完成播放
//我们输入的密码是明文 //我们输入的密码是明文
invoker(false,pwd); invoker(false,pwd);
} }
} }
void RtspSession::onAuthDigest(const weak_ptr<RtspSession> &weakSelf,const string &realm,const string &strMd5){ void RtspSession::onAuthDigest(const string &realm,const string &strMd5){
auto strongSelf = weakSelf.lock(); DebugP(this) << strMd5;
if(!strongSelf){
return;
}
DebugP(strongSelf.get()) << strMd5;
auto mapTmp = Parser::parseArgs(strMd5,",","="); auto mapTmp = Parser::parseArgs(strMd5,",","=");
decltype(mapTmp) map; decltype(mapTmp) map;
for(auto &pr : mapTmp){ for(auto &pr : mapTmp){
...@@ -457,15 +459,13 @@ void RtspSession::onAuthDigest(const weak_ptr<RtspSession> &weakSelf,const strin ...@@ -457,15 +459,13 @@ void RtspSession::onAuthDigest(const weak_ptr<RtspSession> &weakSelf,const strin
} }
//check realm //check realm
if(realm != map["realm"]){ if(realm != map["realm"]){
TraceP(strongSelf.get()) << "realm not mached:" << realm << "," << map["realm"]; onAuthFailed(realm,StrPrinter << "realm not mached:" << realm << " != " << map["realm"]);
onAuthFailed(weakSelf,realm);
return ; return ;
} }
//check nonce //check nonce
auto nonce = map["nonce"]; auto nonce = map["nonce"];
if(strongSelf->_strNonce != nonce){ if(_strNonce != nonce){
TraceP(strongSelf.get()) << "nonce not mached:" << nonce << "," << strongSelf->_strNonce; onAuthFailed(realm,StrPrinter << "nonce not mached:" << nonce << " != " << _strNonce);
onAuthFailed(weakSelf,realm);
return ; return ;
} }
//check username and uri //check username and uri
...@@ -473,20 +473,15 @@ void RtspSession::onAuthDigest(const weak_ptr<RtspSession> &weakSelf,const strin ...@@ -473,20 +473,15 @@ void RtspSession::onAuthDigest(const weak_ptr<RtspSession> &weakSelf,const strin
auto uri = map["uri"]; auto uri = map["uri"];
auto response = map["response"]; auto response = map["response"];
if(username.empty() || uri.empty() || response.empty()){ if(username.empty() || uri.empty() || response.empty()){
TraceP(strongSelf.get()) << "username/uri/response empty:" << username << "," << uri << "," << response; onAuthFailed(realm,StrPrinter << "username/uri/response empty:" << username << "," << uri << "," << response);
onAuthFailed(weakSelf,realm);
return ; return ;
} }
auto realInvoker = [weakSelf,realm,nonce,uri,username,response](bool ignoreAuth,bool encrypted,const string &good_pwd){ auto realInvoker = [this,realm,nonce,uri,username,response](bool ignoreAuth,bool encrypted,const string &good_pwd){
auto strongSelf = weakSelf.lock();
if(!strongSelf){
return;
}
if(ignoreAuth){ if(ignoreAuth){
//忽略认证 //忽略认证
onAuthSuccess(weakSelf); TraceP(this) << "auth ignored";
TraceP(strongSelf.get()) << "auth ignored"; onAuthSuccess();
return; return;
} }
/* /*
...@@ -506,45 +501,60 @@ void RtspSession::onAuthDigest(const weak_ptr<RtspSession> &weakSelf,const strin ...@@ -506,45 +501,60 @@ void RtspSession::onAuthDigest(const weak_ptr<RtspSession> &weakSelf,const strin
auto good_response = MD5( encrypted_pwd + ":" + nonce + ":" + MD5(string("DESCRIBE") + ":" + uri).hexdigest()).hexdigest(); auto good_response = MD5( encrypted_pwd + ":" + nonce + ":" + MD5(string("DESCRIBE") + ":" + uri).hexdigest()).hexdigest();
if(strcasecmp(good_response.data(),response.data()) == 0){ if(strcasecmp(good_response.data(),response.data()) == 0){
//认证成功!md5不区分大小写 //认证成功!md5不区分大小写
onAuthSuccess(weakSelf); onAuthSuccess();
TraceP(strongSelf.get()) << "onAuthSuccess";
}else{ }else{
//认证失败! //认证失败!
onAuthFailed(weakSelf,realm); onAuthFailed(realm, StrPrinter << "password mismatch when md5 auth:" << good_response << " != " << response );
TraceP(strongSelf.get()) << "onAuthFailed";
} }
}; };
onAuth invoker = [realInvoker](bool encrypted,const string &good_pwd){
weak_ptr<RtspSession> weakSelf = dynamic_pointer_cast<RtspSession>(shared_from_this());
onAuth invoker = [realInvoker,weakSelf](bool encrypted,const string &good_pwd){
auto strongSelf = weakSelf.lock();
if(!strongSelf){
return;
}
//切换到自己的线程确保realInvoker执行时,this指针有效
strongSelf->async([realInvoker,weakSelf,encrypted,good_pwd](){
auto strongSelf = weakSelf.lock();
if(!strongSelf){
return;
}
realInvoker(false,encrypted,good_pwd); realInvoker(false,encrypted,good_pwd);
});
}; };
//此时可以提供明文或md5加密的密码 //此时可以提供明文或md5加密的密码
if(!NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastOnRtspAuth,strongSelf->_mediaInfo,realm,username, false,invoker,*strongSelf)){ if(!NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastOnRtspAuth,_mediaInfo,realm,username, false,invoker,*this)){
//表明该流需要认证却没监听请求密码事件,这一般是大意的程序所为,警告之 //表明该流需要认证却没监听请求密码事件,这一般是大意的程序所为,警告之
WarnP(strongSelf.get()) << "请监听kBroadcastOnRtspAuth事件!"; WarnP(this) << "请监听kBroadcastOnRtspAuth事件!";
//但是我们还是忽略认证以便完成播放 //但是我们还是忽略认证以便完成播放
realInvoker(true,true,""); realInvoker(true,true,"");
} }
} }
void RtspSession::onAuthUser(const weak_ptr<RtspSession> &weakSelf,const string &realm,const string &authorization){ void RtspSession::onAuthUser(const string &realm,const string &authorization){
if(authorization.empty()){
onAuthFailed(realm,"", false);
return;
}
//请求中包含认证信息 //请求中包含认证信息
auto authType = FindField(authorization.data(),NULL," "); auto authType = FindField(authorization.data(),NULL," ");
auto authStr = FindField(authorization.data()," ",NULL); auto authStr = FindField(authorization.data()," ",NULL);
if(authType.empty() || authStr.empty()){ if(authType.empty() || authStr.empty()){
//认证信息格式不合法,回复401 Unauthorized //认证信息格式不合法,回复401 Unauthorized
onAuthFailed(weakSelf,realm); onAuthFailed(realm,"can not find auth type or auth string");
return; return;
} }
if(authType == "Basic"){ if(authType == "Basic"){
//base64认证,需要明文密码 //base64认证,需要明文密码
onAuthBasic(weakSelf,realm,authStr); onAuthBasic(realm,authStr);
}else if(authType == "Digest"){ }else if(authType == "Digest"){
//md5认证 //md5认证
onAuthDigest(weakSelf,realm,authStr); onAuthDigest(realm,authStr);
}else{ }else{
//其他认证方式?不支持! //其他认证方式?不支持!
onAuthFailed(weakSelf,realm); onAuthFailed(realm,StrPrinter << "unsupported auth type:" << authType);
} }
} }
inline void RtspSession::send_StreamNotFound() { inline void RtspSession::send_StreamNotFound() {
...@@ -557,7 +567,8 @@ inline void RtspSession::send_UnsupportedTransport() { ...@@ -557,7 +567,8 @@ inline void RtspSession::send_UnsupportedTransport() {
inline void RtspSession::send_SessionNotFound() { inline void RtspSession::send_SessionNotFound() {
sendRtspResponse("454 Session Not Found",{"Connection","Close"}); sendRtspResponse("454 Session Not Found",{"Connection","Close"});
} }
bool RtspSession::handleReq_Setup(const Parser &parser) {
void RtspSession::handleReq_Setup(const Parser &parser) {
//处理setup命令,该函数可能进入多次 //处理setup命令,该函数可能进入多次
auto controlSuffix = split(parser.Url(),"/").back();// parser.FullUrl().substr(_strContentBase.size()); auto controlSuffix = split(parser.Url(),"/").back();// parser.FullUrl().substr(_strContentBase.size());
if(controlSuffix.front() == '/'){ if(controlSuffix.front() == '/'){
...@@ -566,12 +577,12 @@ bool RtspSession::handleReq_Setup(const Parser &parser) { ...@@ -566,12 +577,12 @@ bool RtspSession::handleReq_Setup(const Parser &parser) {
int trackIdx = getTrackIndexByControlSuffix(controlSuffix); int trackIdx = getTrackIndexByControlSuffix(controlSuffix);
if (trackIdx == -1) { if (trackIdx == -1) {
//未找到相应track //未找到相应track
return false; throw SockException(Err_shutdown, StrPrinter << "can not find any track by control suffix:" << controlSuffix);
} }
SdpTrack::Ptr &trackRef = _aTrackInfo[trackIdx]; SdpTrack::Ptr &trackRef = _aTrackInfo[trackIdx];
if (trackRef->_inited) { if (trackRef->_inited) {
//已经初始化过该Track //已经初始化过该Track
return false; throw SockException(Err_shutdown, "can not setup one track twice");
} }
trackRef->_inited = true; //现在初始化 trackRef->_inited = true; //现在初始化
trackRef->_interleaved = trackRef->_type * 2; trackRef->_interleaved = trackRef->_type * 2;
...@@ -606,16 +617,14 @@ bool RtspSession::handleReq_Setup(const Parser &parser) { ...@@ -606,16 +617,14 @@ bool RtspSession::handleReq_Setup(const Parser &parser) {
auto pSockRtp = std::make_shared<Socket>(_sock->getPoller()); auto pSockRtp = std::make_shared<Socket>(_sock->getPoller());
if (!pSockRtp->bindUdpSock(0,get_local_ip().data())) { if (!pSockRtp->bindUdpSock(0,get_local_ip().data())) {
//分配端口失败 //分配端口失败
WarnP(this) << "分配rtp端口失败";
send_NotAcceptable(); send_NotAcceptable();
return false; throw SockException(Err_shutdown, "open rtp socket failed");
} }
auto pSockRtcp = std::make_shared<Socket>(_sock->getPoller()); auto pSockRtcp = std::make_shared<Socket>(_sock->getPoller());
if (!pSockRtcp->bindUdpSock(pSockRtp->get_local_port() + 1,get_local_ip().data())) { if (!pSockRtcp->bindUdpSock(pSockRtp->get_local_port() + 1,get_local_ip().data())) {
//分配端口失败 //分配端口失败
WarnP(this) << "分配rtcp端口失败";
send_NotAcceptable(); send_NotAcceptable();
return false; throw SockException(Err_shutdown, "open rtcp socket failed");
} }
_apRtpSock[trackIdx] = pSockRtp; _apRtpSock[trackIdx] = pSockRtp;
_apRtcpSock[trackIdx] = pSockRtcp; _apRtcpSock[trackIdx] = pSockRtcp;
...@@ -656,7 +665,7 @@ bool RtspSession::handleReq_Setup(const Parser &parser) { ...@@ -656,7 +665,7 @@ bool RtspSession::handleReq_Setup(const Parser &parser) {
_pBrdcaster = RtpBroadCaster::get(getPoller(),get_local_ip(),_mediaInfo._vhost, _mediaInfo._app, _mediaInfo._streamid); _pBrdcaster = RtpBroadCaster::get(getPoller(),get_local_ip(),_mediaInfo._vhost, _mediaInfo._app, _mediaInfo._streamid);
if (!_pBrdcaster) { if (!_pBrdcaster) {
send_NotAcceptable(); send_NotAcceptable();
return false; throw SockException(Err_shutdown, "can not get a available udp multicast socket");
} }
weak_ptr<RtspSession> weakSelf = dynamic_pointer_cast<RtspSession>(shared_from_this()); weak_ptr<RtspSession> weakSelf = dynamic_pointer_cast<RtspSession>(shared_from_this());
_pBrdcaster->setDetachCB(this, [weakSelf]() { _pBrdcaster->setDetachCB(this, [weakSelf]() {
...@@ -673,9 +682,8 @@ bool RtspSession::handleReq_Setup(const Parser &parser) { ...@@ -673,9 +682,8 @@ bool RtspSession::handleReq_Setup(const Parser &parser) {
auto pSockRtcp = UDPServer::Instance().getSock(get_local_ip().data(),2*trackIdx + 1,iSrvPort + 1); auto pSockRtcp = UDPServer::Instance().getSock(get_local_ip().data(),2*trackIdx + 1,iSrvPort + 1);
if (!pSockRtcp) { if (!pSockRtcp) {
//分配端口失败 //分配端口失败
WarnP(this) << "分配rtcp端口失败";
send_NotAcceptable(); send_NotAcceptable();
return false; throw SockException(Err_shutdown, "open shared rtcp socket failed");
} }
startListenPeerUdpData(trackIdx); startListenPeerUdpData(trackIdx);
GET_CONFIG(uint32_t,udpTTL,MultiCast::kUdpTTL); GET_CONFIG(uint32_t,udpTTL,MultiCast::kUdpTTL);
...@@ -693,13 +701,12 @@ bool RtspSession::handleReq_Setup(const Parser &parser) { ...@@ -693,13 +701,12 @@ bool RtspSession::handleReq_Setup(const Parser &parser) {
default: default:
break; break;
} }
return true;
} }
bool RtspSession::handleReq_Play(const Parser &parser) { void RtspSession::handleReq_Play(const Parser &parser) {
if (_aTrackInfo.empty() || parser["Session"] != _strSession) { if (_aTrackInfo.empty() || parser["Session"] != _strSession) {
send_SessionNotFound(); send_SessionNotFound();
return false; throw SockException(Err_shutdown,_aTrackInfo.empty() ? "can not find any availabe track when play" : "session not found when play");
} }
auto strRange = parser["Range"]; auto strRange = parser["Range"];
auto onRes = [this,strRange](const string &err){ auto onRes = [this,strRange](const string &err){
...@@ -812,27 +819,24 @@ bool RtspSession::handleReq_Play(const Parser &parser) { ...@@ -812,27 +819,24 @@ bool RtspSession::handleReq_Play(const Parser &parser) {
//后面是seek或恢复命令,不需要鉴权 //后面是seek或恢复命令,不需要鉴权
onRes(""); onRes("");
} }
return true;
} }
bool RtspSession::handleReq_Pause(const Parser &parser) { void RtspSession::handleReq_Pause(const Parser &parser) {
if (parser["Session"] != _strSession) { if (parser["Session"] != _strSession) {
send_SessionNotFound(); send_SessionNotFound();
return false; throw SockException(Err_shutdown,"session not found when pause");
} }
sendRtspResponse("200 OK"); sendRtspResponse("200 OK");
_enableSendRtp = false; _enableSendRtp = false;
return true;
} }
bool RtspSession::handleReq_Teardown(const Parser &parser) { void RtspSession::handleReq_Teardown(const Parser &parser) {
sendRtspResponse("200 OK"); sendRtspResponse("200 OK");
TraceP(this) << "播放器断开连接!"; throw SockException(Err_shutdown,"rtsp player send teardown request");
return true;
} }
bool RtspSession::handleReq_Get(const Parser &parser) { void RtspSession::handleReq_Get(const Parser &parser) {
_http_x_sessioncookie = parser["x-sessioncookie"]; _http_x_sessioncookie = parser["x-sessioncookie"];
sendRtspResponse("200 OK", sendRtspResponse("200 OK",
{"Connection","Close", {"Connection","Close",
...@@ -844,18 +848,15 @@ bool RtspSession::handleReq_Get(const Parser &parser) { ...@@ -844,18 +848,15 @@ bool RtspSession::handleReq_Get(const Parser &parser) {
//注册http getter,以便http poster绑定 //注册http getter,以便http poster绑定
lock_guard<recursive_mutex> lock(g_mtxGetter); lock_guard<recursive_mutex> lock(g_mtxGetter);
g_mapGetter[_http_x_sessioncookie] = dynamic_pointer_cast<RtspSession>(shared_from_this()); g_mapGetter[_http_x_sessioncookie] = dynamic_pointer_cast<RtspSession>(shared_from_this());
return true;
} }
bool RtspSession::handleReq_Post(const Parser &parser) { void RtspSession::handleReq_Post(const Parser &parser) {
lock_guard<recursive_mutex> lock(g_mtxGetter); lock_guard<recursive_mutex> lock(g_mtxGetter);
string sessioncookie = parser["x-sessioncookie"]; string sessioncookie = parser["x-sessioncookie"];
//Poster 找到 Getter //Poster 找到 Getter
auto it = g_mapGetter.find(sessioncookie); auto it = g_mapGetter.find(sessioncookie);
if (it == g_mapGetter.end()) { if (it == g_mapGetter.end()) {
WarnP(this) << "Http Poster未找到Http Getter"; throw SockException(Err_shutdown,"can not find http getter by x-sessioncookie");
return false;
} }
//Poster 找到Getter的SOCK //Poster 找到Getter的SOCK
...@@ -885,13 +886,11 @@ bool RtspSession::handleReq_Post(const Parser &parser) { ...@@ -885,13 +886,11 @@ bool RtspSession::handleReq_Post(const Parser &parser) {
//http poster后面的粘包 //http poster后面的粘包
_onRecv(std::make_shared<BufferString>(parser.Content())); _onRecv(std::make_shared<BufferString>(parser.Content()));
} }
return true;
} }
bool RtspSession::handleReq_SET_PARAMETER(const Parser &parser) { void RtspSession::handleReq_SET_PARAMETER(const Parser &parser) {
//TraceP(this) <<endl; //TraceP(this) <<endl;
sendRtspResponse("200 OK"); sendRtspResponse("200 OK");
return true;
} }
inline void RtspSession::send_NotAcceptable() { inline void RtspSession::send_NotAcceptable() {
......
...@@ -120,17 +120,17 @@ protected: ...@@ -120,17 +120,17 @@ protected:
*/ */
virtual void onRtcpPacket(int iTrackidx, SdpTrack::Ptr &track, unsigned char *pucData, unsigned int uiLen); virtual void onRtcpPacket(int iTrackidx, SdpTrack::Ptr &track, unsigned char *pucData, unsigned int uiLen);
private: private:
bool handleReq_Options(const Parser &parser); //处理options方法 void handleReq_Options(const Parser &parser); //处理options方法
bool handleReq_Describe(const Parser &parser); //处理describe方法 void handleReq_Describe(const Parser &parser); //处理describe方法
bool handleReq_ANNOUNCE(const Parser &parser); //处理options方法 void handleReq_ANNOUNCE(const Parser &parser); //处理options方法
bool handleReq_RECORD(const Parser &parser); //处理options方法 void handleReq_RECORD(const Parser &parser); //处理options方法
bool handleReq_Setup(const Parser &parser); //处理setup方法 void handleReq_Setup(const Parser &parser); //处理setup方法
bool handleReq_Play(const Parser &parser); //处理play方法 void handleReq_Play(const Parser &parser); //处理play方法
bool handleReq_Pause(const Parser &parser); //处理pause方法 void handleReq_Pause(const Parser &parser); //处理pause方法
bool handleReq_Teardown(const Parser &parser); //处理teardown方法 void handleReq_Teardown(const Parser &parser); //处理teardown方法
bool handleReq_Get(const Parser &parser); //处理Get方法 void handleReq_Get(const Parser &parser); //处理Get方法
bool handleReq_Post(const Parser &parser); //处理Post方法 void handleReq_Post(const Parser &parser); //处理Post方法
bool handleReq_SET_PARAMETER(const Parser &parser); //处理SET_PARAMETER方法 void handleReq_SET_PARAMETER(const Parser &parser); //处理SET_PARAMETER方法
void inline send_StreamNotFound(); //rtsp资源未找到 void inline send_StreamNotFound(); //rtsp资源未找到
void inline send_UnsupportedTransport(); //不支持的传输模式 void inline send_UnsupportedTransport(); //不支持的传输模式
...@@ -145,11 +145,11 @@ private: ...@@ -145,11 +145,11 @@ private:
inline void startListenPeerUdpData(int iTrackIdx); inline void startListenPeerUdpData(int iTrackIdx);
//认证相关 //认证相关
static void onAuthSuccess(const weak_ptr<RtspSession> &weakSelf); void onAuthSuccess();
static void onAuthFailed(const weak_ptr<RtspSession> &weakSelf,const string &realm); void onAuthFailed(const string &realm,const string &why,bool close = true);
static void onAuthUser(const weak_ptr<RtspSession> &weakSelf,const string &realm,const string &authorization); void onAuthUser(const string &realm,const string &authorization);
static void onAuthBasic(const weak_ptr<RtspSession> &weakSelf,const string &realm,const string &strBase64); void onAuthBasic(const string &realm,const string &strBase64);
static void onAuthDigest(const weak_ptr<RtspSession> &weakSelf,const string &realm,const string &strMd5); void onAuthDigest(const string &realm,const string &strMd5);
inline void sendRtpPacket(const RtpPacket::Ptr &pkt); inline void sendRtpPacket(const RtpPacket::Ptr &pkt);
bool sendRtspResponse(const string &res_code,const std::initializer_list<string> &header, const string &sdp = "" , const char *protocol = "RTSP/1.0"); bool sendRtspResponse(const string &res_code,const std::initializer_list<string> &header, const string &sdp = "" , const char *protocol = "RTSP/1.0");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论