Added support for proper range handling to HTTP-based fragmented protocols (Smooth, Live, Dynamic).
This commit is contained in:
		
							parent
							
								
									d3ce22c783
								
							
						
					
					
						commit
						cdcb71d8a8
					
				
					 4 changed files with 72 additions and 1 deletions
				
			
		| 
						 | 
					@ -269,6 +269,7 @@ namespace Connector_HTTP {
 | 
				
			||||||
    connconn[uid]->conn->SendNow(request);
 | 
					    connconn[uid]->conn->SendNow(request);
 | 
				
			||||||
    connconn[uid]->lastuse = 0;
 | 
					    connconn[uid]->lastuse = 0;
 | 
				
			||||||
    unsigned int timeout = 0;
 | 
					    unsigned int timeout = 0;
 | 
				
			||||||
 | 
					    unsigned int retries = 0;
 | 
				
			||||||
    //wait for a response
 | 
					    //wait for a response
 | 
				
			||||||
    while (connconn.count(uid) && connconn[uid]->conn->connected() && conn->connected()){
 | 
					    while (connconn.count(uid) && connconn[uid]->conn->connected() && conn->connected()){
 | 
				
			||||||
      conn->spool();
 | 
					      conn->spool();
 | 
				
			||||||
| 
						 | 
					@ -285,6 +286,20 @@ namespace Connector_HTTP {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        //check if the whole response was received
 | 
					        //check if the whole response was received
 | 
				
			||||||
        if (H.Read(connconn[uid]->conn->Received().get())){
 | 
					        if (H.Read(connconn[uid]->conn->Received().get())){
 | 
				
			||||||
 | 
					          //208 means the fragment is too new, retry in 2000ms
 | 
				
			||||||
 | 
					          if (H.url == "208"){
 | 
				
			||||||
 | 
					            retries++;
 | 
				
			||||||
 | 
					            if (retries >= 5){
 | 
				
			||||||
 | 
					              std::cout << "[5 retry-laters, cancelled]" << std::endl;
 | 
				
			||||||
 | 
					              connconn[uid]->conn->close();
 | 
				
			||||||
 | 
					              return Handle_Timeout(H, conn);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            connconn[uid]->lastuse = 0;
 | 
				
			||||||
 | 
					            timeout = 0;
 | 
				
			||||||
 | 
					            Util::sleep(2000);
 | 
				
			||||||
 | 
					            connconn[uid]->conn->SendNow(request);
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          break; //continue down below this while loop
 | 
					          break; //continue down below this while loop
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }else{
 | 
					      }else{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -233,6 +233,25 @@ namespace Connector_HTTP {
 | 
				
			||||||
#if DEBUG >= 5
 | 
					#if DEBUG >= 5
 | 
				
			||||||
            printf("Quality: %s, Seg %d Frag %d\n", Quality.c_str(), Segment, ReqFragment);
 | 
					            printf("Quality: %s, Seg %d Frag %d\n", Quality.c_str(), Segment, ReqFragment);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					            if (Strm.metadata.isMember("live")){
 | 
				
			||||||
 | 
					              int seekable = Strm.canSeekFrame(ReqFragment);
 | 
				
			||||||
 | 
					              if (seekable < 0){
 | 
				
			||||||
 | 
					                HTTP_S.Clean();
 | 
				
			||||||
 | 
					                HTTP_S.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n");
 | 
				
			||||||
 | 
					                conn.SendNow(HTTP_S.BuildResponse("412", "Fragment out of range"));
 | 
				
			||||||
 | 
					                HTTP_R.Clean(); //clean for any possible next requests
 | 
				
			||||||
 | 
					                std::cout << "Fragment @ F" << ReqFragment << " too old (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              if (seekable > 0){
 | 
				
			||||||
 | 
					                HTTP_S.Clean();
 | 
				
			||||||
 | 
					                HTTP_S.SetBody("Proxy, re-request this in a second or two.\n");
 | 
				
			||||||
 | 
					                conn.SendNow(HTTP_S.BuildResponse("208", "Ask again later"));
 | 
				
			||||||
 | 
					                HTTP_R.Clean(); //clean for any possible next requests
 | 
				
			||||||
 | 
					                std::cout << "Fragment @ F" << ReqFragment << " not available yet (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            std::stringstream sstream;
 | 
					            std::stringstream sstream;
 | 
				
			||||||
            sstream << "f " << ReqFragment << "\no \n";
 | 
					            sstream << "f " << ReqFragment << "\no \n";
 | 
				
			||||||
            ss.SendNow(sstream.str().c_str());
 | 
					            ss.SendNow(sstream.str().c_str());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -167,7 +167,25 @@ namespace Connector_HTTP {
 | 
				
			||||||
            Segment = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find("_", temp) - temp).c_str());
 | 
					            Segment = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find("_", temp) - temp).c_str());
 | 
				
			||||||
            temp = HTTP_R.url.find("_", temp) + 1;
 | 
					            temp = HTTP_R.url.find("_", temp) + 1;
 | 
				
			||||||
            int frameCount = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find(".ts", temp) - temp).c_str());
 | 
					            int frameCount = atoi(HTTP_R.url.substr(temp, HTTP_R.url.find(".ts", temp) - temp).c_str());
 | 
				
			||||||
 | 
					            if (Strm.metadata.isMember("live")){
 | 
				
			||||||
 | 
					              int seekable = Strm.canSeekFrame(Segment);
 | 
				
			||||||
 | 
					              if (seekable < 0){
 | 
				
			||||||
 | 
					                HTTP_S.Clean();
 | 
				
			||||||
 | 
					                HTTP_S.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n");
 | 
				
			||||||
 | 
					                conn.SendNow(HTTP_S.BuildResponse("412", "Fragment out of range"));
 | 
				
			||||||
 | 
					                HTTP_R.Clean(); //clean for any possible next requests
 | 
				
			||||||
 | 
					                std::cout << "Fragment @ F" << Segment << " too old (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              if (seekable > 0){
 | 
				
			||||||
 | 
					                HTTP_S.Clean();
 | 
				
			||||||
 | 
					                HTTP_S.SetBody("Proxy, re-request this in a second or two.\n");
 | 
				
			||||||
 | 
					                conn.SendNow(HTTP_S.BuildResponse("208", "Ask again later"));
 | 
				
			||||||
 | 
					                HTTP_R.Clean(); //clean for any possible next requests
 | 
				
			||||||
 | 
					                std::cout << "Fragment @ F" << Segment << " not available yet (F" << Strm.metadata["keynum"][0u].asInt() << " - " << Strm.metadata["keynum"][Strm.metadata["keynum"].size() - 1].asInt() << ")" << std::endl;
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            std::stringstream sstream;
 | 
					            std::stringstream sstream;
 | 
				
			||||||
            sstream << "f " << Segment << "\n";
 | 
					            sstream << "f " << Segment << "\n";
 | 
				
			||||||
            for (int i = 0; i < frameCount; i++){
 | 
					            for (int i = 0; i < frameCount; i++){
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -166,6 +166,25 @@ namespace Connector_HTTP {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            tempStr = tempStr.substr(tempStr.find("(") + 1);
 | 
					            tempStr = tempStr.substr(tempStr.find("(") + 1);
 | 
				
			||||||
            ReqFragment = atoll(tempStr.substr(0, tempStr.find(")")).c_str());
 | 
					            ReqFragment = atoll(tempStr.substr(0, tempStr.find(")")).c_str());
 | 
				
			||||||
 | 
					            if (Strm.metadata.isMember("live")){
 | 
				
			||||||
 | 
					              int seekable = Strm.canSeekms(ReqFragment / 10000);
 | 
				
			||||||
 | 
					              if (seekable < 0){
 | 
				
			||||||
 | 
					                HTTP_S.Clean();
 | 
				
			||||||
 | 
					                HTTP_S.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n");
 | 
				
			||||||
 | 
					                conn.SendNow(HTTP_S.BuildResponse("412", "Fragment out of range"));
 | 
				
			||||||
 | 
					                HTTP_R.Clean(); //clean for any possible next requests
 | 
				
			||||||
 | 
					                std::cout << "Fragment @ " << ReqFragment / 10000 << "ms too old (" << Strm.metadata["keytime"][0u].asInt() << " - " << Strm.metadata["keytime"][Strm.metadata["keytime"].size() - 1].asInt() << " ms)" << std::endl;
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              if (seekable > 0){
 | 
				
			||||||
 | 
					                HTTP_S.Clean();
 | 
				
			||||||
 | 
					                HTTP_S.SetBody("Proxy, re-request this in a second or two.\n");
 | 
				
			||||||
 | 
					                conn.SendNow(HTTP_S.BuildResponse("208", "Ask again later"));
 | 
				
			||||||
 | 
					                HTTP_R.Clean(); //clean for any possible next requests
 | 
				
			||||||
 | 
					                std::cout << "Fragment @ " << ReqFragment / 10000 << "ms not available yet (" << Strm.metadata["keytime"][0u].asInt() << " - " << Strm.metadata["keytime"][Strm.metadata["keytime"].size() - 1].asInt() << " ms)" << std::endl;
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            std::stringstream sstream;
 | 
					            std::stringstream sstream;
 | 
				
			||||||
            sstream << "s " << (ReqFragment / 10000) << "\no \n";
 | 
					            sstream << "s " << (ReqFragment / 10000) << "\no \n";
 | 
				
			||||||
            ss.SendNow(sstream.str().c_str());
 | 
					            ss.SendNow(sstream.str().c_str());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue