CORS Headers
This commit is contained in:
parent
3c48a6c03c
commit
a39350f83e
11 changed files with 171 additions and 17 deletions
|
@ -35,9 +35,13 @@ void HTTP::Parser::CleanPreserveHeaders() {
|
|||
/// Sets the neccesary headers to allow Cross Origin Resource Sharing with all domains.
|
||||
void HTTP::Parser::setCORSHeaders(){
|
||||
SetHeader("Access-Control-Allow-Origin", "*");
|
||||
SetHeader("Access-Control-Allow-Methods", "GET, POST");
|
||||
SetHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With");
|
||||
SetHeader("Access-Control-Allow-Credentials", "true");
|
||||
SetHeader("Access-Control-Expose-Headers", "*");
|
||||
SetHeader("Access-Control-Max-Age", "600");
|
||||
SetHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, HEAD");
|
||||
SetHeader("Access-Control-Allow-Headers", "*");
|
||||
SetHeader("Access-Control-Request-Method", "GET");
|
||||
SetHeader("Access-Control-Request-Headers", "*");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -178,15 +178,22 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void OutHDS::onHTTP(){
|
||||
std::string method = H.method;
|
||||
|
||||
if (H.url.find(".abst") != std::string::npos){
|
||||
initialize();
|
||||
std::string streamID = H.url.substr(streamName.size() + 10);
|
||||
streamID = streamID.substr(0, streamID.find(".abst"));
|
||||
H.Clean();
|
||||
H.SetBody(dynamicBootstrap(atoll(streamID.c_str())));
|
||||
H.SetHeader("Content-Type", "binary/octet");
|
||||
H.SetHeader("Cache-Control", "no-cache");
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
H.SetBody(dynamicBootstrap(atoll(streamID.c_str())));
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean(); //clean for any possible next requests
|
||||
return;
|
||||
|
@ -207,6 +214,7 @@ namespace Mist {
|
|||
unsigned int mslen = 0;
|
||||
if (fragNum < (unsigned int)myMeta.tracks[tid].missedFrags){
|
||||
H.Clean();
|
||||
H.setCORSHeaders();
|
||||
H.SetBody("The requested fragment is no longer kept in memory on the server and cannot be served.\n");
|
||||
H.SendResponse("412", "Fragment out of range", myConn);
|
||||
H.Clean(); //clean for any possible next requests
|
||||
|
@ -238,6 +246,12 @@ namespace Mist {
|
|||
|
||||
H.Clean();
|
||||
H.SetHeader("Content-Type", "video/mp4");
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
H.StartResponse(H, myConn);
|
||||
//send the bootstrap
|
||||
std::string bootstrap = dynamicBootstrap(tid);
|
||||
|
@ -266,6 +280,12 @@ namespace Mist {
|
|||
H.Clean();
|
||||
H.SetHeader("Content-Type", "text/xml");
|
||||
H.SetHeader("Cache-Control", "no-cache");
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
H.SetBody(dynamicIndex());
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
}
|
||||
|
|
|
@ -134,28 +134,25 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void OutHLS::onHTTP(){
|
||||
std::string method = H.method;
|
||||
|
||||
|
||||
if (H.url == "/crossdomain.xml"){
|
||||
H.Clean();
|
||||
H.SetHeader("Content-Type", "text/xml");
|
||||
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||
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 \"http://www.adobe.com/xml/dtds/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"){
|
||||
H.Clean();
|
||||
H.SetHeader("Content-Type", "application/octet-stream");
|
||||
H.SetHeader("Cache-Control", "no-cache");
|
||||
H.setCORSHeaders();
|
||||
H.SetBody("");
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
if (H.url.find("hls") == std::string::npos){
|
||||
myConn.close();
|
||||
return;
|
||||
|
@ -178,6 +175,7 @@ namespace Mist {
|
|||
if (sscanf(tmpStr.c_str(), "/%u/%llu_%llu.ts", &vidTrack, &from, &until) != 3){
|
||||
DEBUG_MSG(DLVL_MEDIUM, "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
|
||||
|
@ -210,6 +208,7 @@ namespace Mist {
|
|||
}while (myConn && seekable > 0);
|
||||
if (seekable < 0){
|
||||
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("412", "Fragment out of range"));
|
||||
H.Clean(); //clean for any possible next requests
|
||||
|
@ -222,8 +221,14 @@ namespace Mist {
|
|||
ts_from = from;
|
||||
lastVid = from * 90;
|
||||
|
||||
H.Clean();
|
||||
H.SetHeader("Content-Type", "video/mp2t");
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
H.StartResponse(H, myConn, VLCworkaround);
|
||||
|
||||
unsigned int fragCounter = myMeta.tracks[vidTrack].missedFrags;
|
||||
|
@ -251,6 +256,11 @@ namespace Mist {
|
|||
}
|
||||
H.SetHeader("Cache-Control", "no-cache");
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
std::string manifest;
|
||||
if (request.find("/") == std::string::npos){
|
||||
manifest = liveIndex();
|
||||
|
|
|
@ -438,12 +438,11 @@ namespace Mist {
|
|||
|
||||
|
||||
void OutHSS::onHTTP() {
|
||||
if (H.method == "OPTIONS"){
|
||||
if ((H.method == "OPTIONS" || H.method == "HEAD") && H.url.find("Manifest") == std::string::npos){
|
||||
H.Clean();
|
||||
H.SetHeader("Content-Type", "application/octet-stream");
|
||||
H.SetHeader("Cache-Control", "no-cache");
|
||||
H.setCORSHeaders();
|
||||
H.SetBody("");
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
|
@ -455,6 +454,10 @@ namespace Mist {
|
|||
H.SetHeader("Content-Type", "text/xml");
|
||||
H.SetHeader("Cache-Control", "no-cache");
|
||||
H.setCORSHeaders();
|
||||
if(H.method == "OPTIONS" || H.method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
return;
|
||||
}
|
||||
std::string manifest = smoothIndex();
|
||||
H.SetBody(manifest);
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
|
|
|
@ -152,13 +152,21 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void OutHTTP::onHTTP(){
|
||||
std::string method = H.method;
|
||||
|
||||
if (H.url == "/crossdomain.xml"){
|
||||
H.Clean();
|
||||
H.SetHeader("Content-Type", "text/xml");
|
||||
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||
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 \"http://www.adobe.com/xml/dtds/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();
|
||||
return;
|
||||
} //crossdomain.xml
|
||||
|
||||
|
@ -167,8 +175,14 @@ namespace Mist {
|
|||
H.SetHeader("Content-Type", "text/xml");
|
||||
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
H.SetBody("<?xml version=\"1.0\" encoding=\"utf-8\"?><access-policy><cross-domain-access><policy><allow-from http-methods=\"*\" http-request-headers=\"*\"><domain uri=\"*\"/></allow-from><grant-to><resource path=\"/\" include-subpaths=\"true\"/></grant-to></policy></cross-domain-access></access-policy>");
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
} //clientaccesspolicy.xml
|
||||
|
||||
|
@ -196,8 +210,15 @@ namespace Mist {
|
|||
H.SetHeader("Content-Type", "image/x-icon");
|
||||
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||
H.SetHeader("Content-Length", icon_len);
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
myConn.SendNow((const char*)icon_data, icon_len);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -207,6 +228,11 @@ namespace Mist {
|
|||
H.SetHeader("Content-Type", "text/html");
|
||||
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
H.SetBody("<!DOCTYPE html><html><head><title>Stream "+streamName+"</title><style>BODY{color:white;background:black;}</style></head><body><script src=\"embed_"+streamName+".js\"></script></body></html>");
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
return;
|
||||
|
@ -259,8 +285,14 @@ namespace Mist {
|
|||
H.SetHeader("Content-Type", "application/smil");
|
||||
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
H.SetBody("<smil>\n <head>\n <meta base='rtmp://" + host + ":" + port + url_rel + "' />\n </head>\n <body>\n <switch>\n"+trackSources+" </switch>\n </body>\n</smil>");
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -280,6 +312,11 @@ namespace Mist {
|
|||
}else{
|
||||
H.SetHeader("Content-Type", "application/json");
|
||||
}
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
response = "// Generating info code for stream " + streamName + "\n\nif (!mistvideo){var mistvideo = {};}\n";
|
||||
JSON::Value json_resp;
|
||||
IPC::semaphore configLock("!mistConfLock", O_CREAT | O_RDWR, ACCESSPERMS, 1);
|
||||
|
@ -409,6 +446,7 @@ namespace Mist {
|
|||
}
|
||||
H.SetBody(response);
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
} //embed code generator
|
||||
}
|
||||
|
|
|
@ -30,8 +30,11 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void OutJSON::sendHeader(){
|
||||
std::string method = H.method;
|
||||
H.Clean();
|
||||
H.SetHeader("Content-Type", "text/javascript");
|
||||
H.protocol = "HTTP/1.0";
|
||||
H.setCORSHeaders();
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
sentHeader = true;
|
||||
}
|
||||
|
@ -46,6 +49,18 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void OutJSON::onHTTP(){
|
||||
std::string method = H.method;
|
||||
|
||||
H.Clean();
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SetHeader("Content-Type", "text/javascript");
|
||||
H.protocol = "HTTP/1.0";
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
first = true;
|
||||
jsonp = "";
|
||||
if (H.GetVar("callback") != ""){jsonp = H.GetVar("callback");}
|
||||
|
|
|
@ -37,9 +37,12 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void OutProgressiveFLV::sendHeader(){
|
||||
|
||||
|
||||
H.Clean();
|
||||
H.SetHeader("Content-Type", "video/x-flv");
|
||||
H.protocol = "HTTP/1.0";
|
||||
H.setCORSHeaders();
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
myConn.SendNow(FLV::Header, 13);
|
||||
tag.DTSCMetaInit(myMeta, selectedTracks);
|
||||
|
@ -56,6 +59,18 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void OutProgressiveFLV::onHTTP(){
|
||||
std::string method = H.method;
|
||||
|
||||
H.Clean();
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SetHeader("Content-Type", "video/x-flv");
|
||||
H.protocol = "HTTP/1.0";
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
parseData = true;
|
||||
wantRequest = false;
|
||||
}
|
||||
|
|
|
@ -24,13 +24,32 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void OutProgressiveMP3::sendHeader(){
|
||||
std::string method = H.method;
|
||||
H.Clean();
|
||||
H.SetHeader("Content-Type", "audio/mpeg");
|
||||
H.protocol = "HTTP/1.0";
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
return;
|
||||
}
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
sentHeader = true;
|
||||
}
|
||||
|
||||
void OutProgressiveMP3::onHTTP(){
|
||||
std::string method = H.method;
|
||||
|
||||
H.Clean();
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SetHeader("Content-Type", "audio/mpeg");
|
||||
H.protocol = "HTTP/1.0";
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
parseData = true;
|
||||
wantRequest = false;
|
||||
}
|
||||
|
|
|
@ -439,8 +439,16 @@ namespace Mist {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void OutProgressiveMP4::onHTTP(){
|
||||
if(H.method == "OPTIONS" || H.method == "HEAD"){
|
||||
H.Clean();
|
||||
H.setCORSHeaders();
|
||||
H.SetHeader("Content-Type", "video/MP4");
|
||||
H.SetHeader("Accept-Ranges", "bytes, parsec");
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
return;
|
||||
}
|
||||
|
||||
initialize();
|
||||
parseData = true;
|
||||
wantRequest = false;
|
||||
|
|
|
@ -127,6 +127,7 @@ namespace Mist {
|
|||
HTTP_S.SetHeader("Content-Type", "video/ogg");
|
||||
HTTP_S.protocol = "HTTP/1.0";
|
||||
myConn.SendNow(HTTP_S.BuildResponse("200", "OK")); //no SetBody = unknown length - this is intentional, we will stream the entire file
|
||||
|
||||
|
||||
std::map<int, std::deque<std::string> > initData;
|
||||
|
||||
|
@ -175,6 +176,16 @@ namespace Mist {
|
|||
void OutProgressiveOGG::onRequest(){
|
||||
if (HTTP_R.Read(myConn)){
|
||||
DEBUG_MSG(DLVL_DEVEL, "Received request %s", HTTP_R.getUrl().c_str());
|
||||
|
||||
if (HTTP_R.method == "OPTIONS" || HTTP_R.method == "HEAD"){
|
||||
HTTP_S.Clean();
|
||||
HTTP_S.SetHeader("Content-Type", "video/ogg");
|
||||
HTTP_S.protocol = "HTTP/1.0";
|
||||
HTTP_S.SendResponse("200", "OK", myConn);
|
||||
HTTP_S.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
if (HTTP_R.GetVar("audio") != ""){
|
||||
selectedTracks.insert(JSON::Value(HTTP_R.GetVar("audio")).asInt());
|
||||
}
|
||||
|
|
|
@ -52,6 +52,17 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void OutProgressiveSRT::onHTTP(){
|
||||
std::string method = H.method;
|
||||
|
||||
H.Clean();
|
||||
H.setCORSHeaders();
|
||||
if(method == "OPTIONS" || method == "HEAD"){
|
||||
H.SetHeader("Content-Type", "text/plain");
|
||||
H.protocol = "HTTP/1.0";
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
lastNum = 0;
|
||||
webVTT = (H.url.find(".webvtt") != std::string::npos);
|
||||
if (H.GetVar("track") != ""){
|
||||
|
|
Loading…
Add table
Reference in a new issue