Added support for proper range handling to HTTP-based fragmented protocols (Smooth, Live, Dynamic).

This commit is contained in:
Thulinma 2013-03-18 17:38:01 +01:00
parent d3ce22c783
commit cdcb71d8a8
4 changed files with 72 additions and 1 deletions

View file

@ -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{

View file

@ -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());

View file

@ -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++){

View file

@ -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());