CORS Headers

This commit is contained in:
Erik Zandvliet 2016-01-26 14:31:09 +01:00
parent 3c48a6c03c
commit a39350f83e
11 changed files with 171 additions and 17 deletions

View file

@ -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", "*");
}

View file

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

View file

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

View file

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

View file

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

View file

@ -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");}

View file

@ -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;
}

View file

@ -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;
}

View file

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

View file

@ -128,6 +128,7 @@ namespace Mist {
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;
OGG::oggSegment newSegment;
@ -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());
}

View file

@ -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") != ""){