Better onFail handling, better HTTP failure handling

This commit is contained in:
Thulinma 2018-11-13 16:34:30 +01:00
parent 9a2544cc9b
commit 251dc5f171
9 changed files with 30 additions and 49 deletions

View file

@ -130,8 +130,12 @@ namespace Mist{
/// Called when stream initialization has failed.
/// The standard implementation will set isInitialized to false and close the client connection,
/// thus causing the process to exit cleanly.
void Output::onFail(){
MEDIUM_MSG("onFail");
void Output::onFail(const std::string & msg, bool critical){
if (critical){
FAIL_MSG("onFail '%s': %s", streamName.c_str(), msg.c_str());
}else{
MEDIUM_MSG("onFail '%s': %s", streamName.c_str(), msg.c_str());
}
isInitialized = false;
wantRequest = true;
parseData= false;
@ -153,7 +157,7 @@ namespace Mist{
reconnect();
//if the connection failed, fail
if (streamName.size() < 1){
onFail();
onFail("Could not connect to stream", true);
return;
}
sought = false;
@ -216,14 +220,12 @@ namespace Mist{
if (config->hasOption("noinput") && config->getBool("noinput")){
Util::sanitizeName(streamName);
if (!Util::streamAlive(streamName)){
FAIL_MSG("Stream %s not already active - aborting initialization", streamName.c_str());
onFail();
onFail("Stream not active already, aborting");
return;
}
}else{
if (!Util::startInput(streamName, "", true, isPushing())){
FAIL_MSG("Opening stream %s failed - aborting initialization", streamName.c_str());
onFail();
onFail("Stream open failed", true);
return;
}
}
@ -236,16 +238,14 @@ namespace Mist{
nProxy.userClient = IPC::sharedClient(userPageName, PLAY_EX_SIZE, true);
}
if (!nProxy.userClient.isAlive()){
FAIL_MSG("Could not register as client for %s", streamName.c_str());
onFail();
onFail("Could not register as client", true);
return;
}
char pageId[NAME_BUFFER_SIZE];
snprintf(pageId, NAME_BUFFER_SIZE, SHM_STREAM_INDEX, streamName.c_str());
nProxy.metaPages[0].init(pageId, DEFAULT_STRM_PAGE_SIZE);
if (!nProxy.metaPages[0].mapped){
FAIL_MSG("Could not connect to data for %s", streamName.c_str());
onFail();
onFail("Could not connect to stream data", true);
return;
}
isInitialized = true;
@ -1173,12 +1173,7 @@ namespace Mist{
snprintf(userPageName, NAME_BUFFER_SIZE, SHM_USERS, streamName.c_str());
nProxy.userClient = IPC::sharedClient(userPageName, PLAY_EX_SIZE, true);
if (!nProxy.userClient.getData()){
WARN_MSG("Player connection failure - aborting output");
if (!onFinish()){
myConn.close();
}else{
disconnect();
}
onFail("Player connection failure - aborting output", true);
return;
}
}
@ -1186,21 +1181,11 @@ namespace Mist{
if (isPushing() && !pushIsOngoing){
waitForStreamPushReady();
if (!nProxy.userClient.isAlive()){
WARN_MSG("Failed to wait for buffer, aborting incoming push");
if (!onFinish()){
myConn.close();
}else{
disconnect();
}
onFail("Failed to wait for buffer, aborting incoming push", true);
return;
}
}else{
INFO_MSG("Received disconnect request from input");
if (!onFinish()){
myConn.close();
}else{
disconnect();
}
onFail("Received disconnect request from input");
return;
}
}

View file

@ -73,7 +73,7 @@ namespace Mist {
void disconnect();
virtual void initialize();
virtual void sendHeader();
virtual void onFail();
virtual void onFail(const std::string & msg, bool critical = false);
virtual void requestHandler();
static Util::Config * config;
void playbackSleep(uint64_t millis);

View file

@ -197,7 +197,7 @@ namespace Mist {
}
if (H.url.find("hls") == std::string::npos){
onFail();
onFail("HLS handler active, but this is not a HLS URL. Eh... What...?");
return;
}
@ -213,11 +213,7 @@ namespace Mist {
}
initialize();
if (!keepGoing()){
onFail();
return;
}
if (!keepGoing()){return;}
if (H.url.find(".m3u") == std::string::npos){
std::string tmpStr = H.getUrl().substr(5 + streamName.size());

View file

@ -39,13 +39,14 @@ namespace Mist {
config = cfg;
}
void HTTPOutput::onFail(){
void HTTPOutput::onFail(const std::string & msg, bool critical){
INFO_MSG("Failing '%s': %s: %s", streamName.c_str(), H.url.c_str(), msg.c_str());
if (!webSock){
H.Clean(); //make sure no parts of old requests are left in any buffers
H.SetBody("Stream not found. Sorry, we tried.");
H.SendResponse("404", "Stream not found", myConn);
H.SetBody("Could not retrieve stream: "+msg);
H.SendResponse("404", "Error opening stream", myConn);
}
Output::onFail();
Output::onFail(msg, critical);
}
bool isMatch(const std::string & url, const std::string & m, std::string & streamname){

View file

@ -12,7 +12,7 @@ namespace Mist {
virtual ~HTTPOutput();
static void init(Util::Config * cfg);
void onRequest();
virtual void onFail();
virtual void onFail(const std::string & msg, bool critical = false);
virtual void onHTTP(){};
virtual void onIdle(){};
virtual void onWebsocketFrame(){};

View file

@ -60,7 +60,7 @@ namespace Mist {
return !(config->getString("ip").size());
}
void OutHTTP::onFail(){
void OutHTTP::onFail(const std::string & msg, bool critical){
std::string method = H.method;
// send logo icon
if (H.url.length() > 4 && H.url.substr(H.url.length() - 4, 4) == ".ico"){
@ -75,6 +75,7 @@ namespace Mist {
if (websocketHandler()){return;}
JSON::Value json_resp;
json_resp["error"] = "Could not retrieve stream. Sorry.";
json_resp["error_guru"] = msg;
if (H.url.size() >= 5 && H.url.substr(0, 5) == "/json"){
H.Clean();
H.SetBody(json_resp.toString());
@ -92,9 +93,7 @@ namespace Mist {
H.Clean();
return;
}
INFO_MSG("Failing: %s", H.url.c_str());
HTTPOutput::onFail();
Output::onFail();
HTTPOutput::onFail(msg, critical);
}
void OutHTTP::init(Util::Config * cfg){

View file

@ -8,7 +8,7 @@ namespace Mist {
~OutHTTP();
static void init(Util::Config * cfg);
static bool listenMode();
virtual void onFail();
virtual void onFail(const std::string & msg, bool critical = false);
///preHTTP is disabled in the internal HTTP output, since most don't need the stream alive to work
virtual void preHTTP(){};
void HTMLResponse();

View file

@ -81,10 +81,10 @@ namespace Mist {
sentHeader = true;
}
void OutJSON::onFail(){
void OutJSON::onFail(const std::string & msg, bool critical){
//Only run failure handle if we're not being persistent
if (!keepReselecting){
HTTPOutput::onFail();
HTTPOutput::onFail(msg, critical);
}else{
onFinish();
}

View file

@ -12,7 +12,7 @@ namespace Mist {
virtual void onWebsocketConnect();
virtual void preWebsocketConnect();
bool onFinish();
void onFail();
void onFail(const std::string & msg, bool critical = false);
void sendNext();
void sendHeader();
bool doesWebsockets(){return true;}