HLS/HTTP fixes:
- Optimize URIReader class to not close connections if not needed - reConnector now works for non-GET requests with GET params - Chunk sending mode correctly kept for HLS - Removed lots of H.Clean() from HLS that weren't needed - Improved HTTP output class request handling logic - Removed firstRun from HTTP output class; no longer needed
This commit is contained in:
parent
5774ce3b9e
commit
194b6e1388
5 changed files with 13 additions and 27 deletions
|
@ -148,7 +148,7 @@ std::string &HTTP::Parser::BuildRequest(){
|
|||
/// \todo Include POST variable handling for vars?
|
||||
std::map<std::string, std::string>::iterator it;
|
||||
if (protocol.size() < 5 || protocol[4] != '/'){protocol = "HTTP/1.0";}
|
||||
if (method == "GET" && vars.size() && url.find('?') == std::string::npos){
|
||||
if (method != "POST" && vars.size() && url.find('?') == std::string::npos){
|
||||
builder = method + " " + Encodings::URL::encode(url, "/:=@[]") + allVars() + " " + protocol + "\r\n";
|
||||
}else{
|
||||
builder = method + " " + Encodings::URL::encode(url, "/:=@[]") + " " + protocol + "\r\n";
|
||||
|
@ -277,9 +277,10 @@ void HTTP::Parser::SendResponse(std::string code, std::string message, Socket::C
|
|||
void HTTP::Parser::StartResponse(std::string code, std::string message, const HTTP::Parser &request,
|
||||
Socket::Connection &conn, bool bufferAllChunks){
|
||||
std::string prot = request.protocol;
|
||||
sendingChunks =
|
||||
bool willSendChunks =
|
||||
(!bufferAllChunks && request.protocol == "HTTP/1.1" && request.GetHeader("Connection") != "close");
|
||||
CleanPreserveHeaders();
|
||||
sendingChunks = willSendChunks;
|
||||
protocol = prot;
|
||||
if (sendingChunks){
|
||||
SetHeader("Transfer-Encoding", "chunked");
|
||||
|
|
|
@ -45,13 +45,13 @@ namespace HTTP{
|
|||
void URIReader::dataCallback(const char *ptr, size_t size){allData.append(ptr, size);}
|
||||
|
||||
bool URIReader::open(const HTTP::URL &uri){
|
||||
close();
|
||||
myURI = uri;
|
||||
curPos = 0;
|
||||
allData.truncate(0);
|
||||
bufPos = 0;
|
||||
|
||||
if (!myURI.protocol.size() || myURI.protocol == "file"){
|
||||
close();
|
||||
if (!myURI.path.size() || myURI.path == "-"){
|
||||
downer.getSocket().open(-1, fileno(stdin));
|
||||
stateType = HTTP::Stream;
|
||||
|
|
|
@ -230,13 +230,11 @@ namespace Mist{
|
|||
std::string sessId = H.GetVar("sessId");
|
||||
|
||||
if (H.url == "/crossdomain.xml"){
|
||||
H.Clean();
|
||||
H.SetHeader("Content-Type", "text/xml");
|
||||
H.SetHeader("Server", APPIDENT);
|
||||
H.setCORSHeaders();
|
||||
if (method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
H.SetBody("<?xml version=\"1.0\"?><!DOCTYPE cross-domain-policy SYSTEM "
|
||||
|
@ -244,13 +242,11 @@ namespace Mist{
|
|||
"cross-domain-policy.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" "
|
||||
"/><site-control permitted-cross-domain-policies=\"all\"/></cross-domain-policy>");
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean(); // clean for any possible next requests
|
||||
return;
|
||||
}// crossdomain.xml
|
||||
|
||||
if (H.method == "OPTIONS"){
|
||||
bool isTS = (HTTP::URL(H.url).getExt().substr(0, 3) != "m3u");
|
||||
H.Clean();
|
||||
H.setCORSHeaders();
|
||||
if (isTS){
|
||||
H.SetHeader("Content-Type", "video/mp2t");
|
||||
|
@ -266,7 +262,6 @@ namespace Mist{
|
|||
}
|
||||
H.SetBody("");
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -294,11 +289,9 @@ namespace Mist{
|
|||
if (sscanf(tmpStr.c_str(), "/%zu_%zu/%" PRIu64 "_%" PRIu64 ".ts", &vidTrack, &audTrack, &from, &until) != 4){
|
||||
if (sscanf(tmpStr.c_str(), "/%zu/%" PRIu64 "_%" PRIu64 ".ts", &vidTrack, &from, &until) != 3){
|
||||
MEDIUM_MSG("Could not parse URL: %s", H.getUrl().c_str());
|
||||
H.Clean();
|
||||
H.setCORSHeaders();
|
||||
H.SetBody("The HLS URL wasn't understood - what did you want, exactly?\n");
|
||||
myConn.SendNow(H.BuildResponse("404", "URL mismatch"));
|
||||
H.Clean(); // clean for any possible next requests
|
||||
return;
|
||||
}
|
||||
userSelect.clear();
|
||||
|
@ -314,12 +307,10 @@ namespace Mist{
|
|||
}
|
||||
|
||||
if (M.getLive() && from < M.getFirstms(vidTrack)){
|
||||
H.Clean();
|
||||
H.setCORSHeaders();
|
||||
H.SetBody("The requested fragment is no longer kept in memory on the server and cannot be "
|
||||
"served.\n");
|
||||
myConn.SendNow(H.BuildResponse("404", "Fragment out of range"));
|
||||
H.Clean(); // clean for any possible next requests
|
||||
WARN_MSG("Fragment @ %" PRIu64 " too old", from);
|
||||
return;
|
||||
}
|
||||
|
@ -335,7 +326,6 @@ namespace Mist{
|
|||
}
|
||||
if (method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -353,17 +343,14 @@ namespace Mist{
|
|||
}else{
|
||||
initialize();
|
||||
std::string request = H.url.substr(H.url.find("/", 5) + 1);
|
||||
H.Clean();
|
||||
H.setCORSHeaders();
|
||||
H.SetHeader("Content-Type", "application/vnd.apple.mpegurl");
|
||||
if (!M.getValidTracks().size()){
|
||||
H.SendResponse("404", "Not online or found", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
if (method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
std::string manifest;
|
||||
|
@ -373,7 +360,6 @@ namespace Mist{
|
|||
size_t idx = atoi(request.substr(0, request.find("/")).c_str());
|
||||
if (!M.getValidTracks().count(idx)){
|
||||
H.SendResponse("404", "No corresponding track found", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -389,7 +375,6 @@ namespace Mist{
|
|||
if (thisPacket.getTime() >= until){
|
||||
stop();
|
||||
wantRequest = true;
|
||||
parseData = false;
|
||||
|
||||
// Ensure alignment of contCounters, to prevent discontinuities.
|
||||
for (std::map<size_t, uint16_t>::iterator it = contCounters.begin(); it != contCounters.end(); it++){
|
||||
|
@ -407,6 +392,7 @@ namespace Mist{
|
|||
|
||||
// Signal end of data
|
||||
H.Chunkify("", 0, myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
// Invoke the generic TS output sendNext handler
|
||||
|
|
|
@ -14,7 +14,6 @@ namespace Mist{
|
|||
idleInterval = 0;
|
||||
idleLast = 0;
|
||||
if (config->getString("ip").size()){myConn.setHost(config->getString("ip"));}
|
||||
firstRun = true;
|
||||
if (config->getString("prequest").size()){
|
||||
myConn.Received().prepend(config->getString("prequest"));
|
||||
}
|
||||
|
@ -197,14 +196,11 @@ namespace Mist{
|
|||
if (!isBlocking && !parseData){Util::sleep(100);}
|
||||
return;
|
||||
}
|
||||
// If we can't read anything more and we're non-blocking, sleep some.
|
||||
if (!firstRun && !myConn.spool()){
|
||||
if (!isBlocking && !parseData){Util::sleep(100);}
|
||||
return;
|
||||
}
|
||||
firstRun = false;
|
||||
|
||||
//Attempt to read a HTTP request, regardless of data being available
|
||||
bool sawRequest = false;
|
||||
while (H.Read(myConn)){
|
||||
sawRequest = true;
|
||||
std::string handler = getHandler();
|
||||
if (handler != capa["name"].asStringRef() || H.GetVar("stream") != streamName){
|
||||
INFO_MSG("Received request: %s => %s (%s)", H.getUrl().c_str(), handler.c_str(), H.GetVar("stream").c_str());
|
||||
|
@ -307,8 +303,12 @@ namespace Mist{
|
|||
if (!myConn){return;}
|
||||
onHTTP();
|
||||
idleLast = Util::bootMS();
|
||||
if (!H.bufferChunks){H.Clean();}
|
||||
// Prevent the clean as well as the loop when we're in the middle of handling a request now
|
||||
if (!wantRequest){return;}
|
||||
H.Clean();
|
||||
}
|
||||
// If we can't read anything more and we're non-blocking, sleep some.
|
||||
if (!sawRequest && !myConn.spool() && !isBlocking && !parseData){Util::sleep(100);}
|
||||
}
|
||||
|
||||
/// Default HTTP handler.
|
||||
|
|
|
@ -27,7 +27,6 @@ namespace Mist{
|
|||
bool parseRange(std::string header, uint64_t &byteStart, uint64_t &byteEnd);
|
||||
|
||||
protected:
|
||||
bool firstRun;
|
||||
bool responded;
|
||||
HTTP::Parser H;
|
||||
HTTP::Websocket *webSock;
|
||||
|
|
Loading…
Add table
Reference in a new issue