Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Copyright (c) 2010,
- * Gavriloaie Eugen-Andrei ([email protected])
- *
- * This file is part of crtmpserver.
- * crtmpserver is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * crtmpserver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with crtmpserver. If not, see <http://www.gnu.org/licenses/>.
- */
- #ifdef HAS_PROTOCOL_RTMP
- #include "rtmpappprotocolhandler.h"
- #include "protocols/rtmp/basertmpprotocol.h"
- #include "protocols/rtmp/messagefactories/messagefactories.h"
- #include "application/baseclientapplication.h"
- #include "streaming/baseinnetstream.h"
- #include "streaming/streamstypes.h"
- using namespace app_flvplayback;
- RTMPAppProtocolHandler::RTMPAppProtocolHandler(Variant &configuration)
- : BaseRTMPAppProtocolHandler(configuration) {
- }
- RTMPAppProtocolHandler::~RTMPAppProtocolHandler() {
- }
- bool RTMPAppProtocolHandler::ProcessInvokeGeneric(BaseRTMPProtocol *pFrom,
- Variant &request) {
- string functionName = M_INVOKE_FUNCTION(request);
- if (functionName == "getAvailableFlvs") {
- return ProcessGetAvailableFlvs(pFrom, request);
- } else if (functionName == "insertMetadata") {
- return ProcessInsertMetadata(pFrom, request);
- } else {
- return BaseRTMPAppProtocolHandler::ProcessInvokeGeneric(pFrom, request);
- }
- }
- // adding functions for filter validations
- bool RTMPAppProtocolHandler::ProcessInvokeConnect(BaseRTMPProtocol *pFrom, Variant &request) {
- //1. Get the request params
- if (M_INVOKE_PARAMS(request).MapSize() < 1) {
- FATAL("Invalid request");
- return false;
- }
- Variant connectParameters = M_INVOKE_PARAM(request, 0);
- if (_authMethod != "") {
- //we have adobe auth enabled
- string flashVer = connectParameters[RM_INVOKE_PARAMS_CONNECT_FLASHVER];
- if (!_configuration[CONF_APPLICATION_AUTH][CONF_APPLICATION_AUTH_ENCODER_AGENTS].HasKey(flashVer)) {
- //this connection will not be authenticated, so we will try to validate the URI's
- //if (!ValidateRequest(request)) {
- //For URI Token-Key Auth added by Madhawa Jayanath
- if (!ValidateRequest(pFrom, request)) {
- FATAL("Invalid connect request");
- return false;
- }
- }
- } else {
- //we don't have adobe auth enabled at all. We will try to validate the URI's
- //if (!ValidateRequest(request)) {
- //For URI Token-Key Auth added by Madhawa Jayanath
- if (!ValidateRequest(pFrom, request)) {
- FATAL("Invalid connect request");
- return false;
- }
- }
- return BaseRTMPAppProtocolHandler::ProcessInvokeConnect(pFrom, request);
- }
- //bool RTMPAppProtocolHandler::ValidateRequest(Variant &request) {
- //For URI Token-Key Auth added by Madhawa Jayanath
- bool RTMPAppProtocolHandler::ValidateRequest(BaseRTMPProtocol *pFrom, Variant &request) {
- //TODO: Validate the various URI's inside the request here
- //0. Dump the request on console, just to see its structure
- FINEST("Initial request:\n%s", STR(request.ToString()));
- //1. Get the connect params from the connect invoke
- Variant connectParams = M_INVOKE_PARAM(request, 0);
- //For URI Token-Key Auth added by Madhawa Jayanath
- Variant mySecondparam=M_INVOKE_PARAM(request,1);
- if (_configuration["sharedKey"] != "") {
- string sharedkey = _configuration["sharedKey"];
- IOHandler *pHandler=pFrom->GetIOHandler();
- if(pHandler==NULL)
- return false;
- if(pHandler->GetType()!= IOHT_TCP_CARRIER)
- return false;
- string peerAddress=((TCPCarrier *)pHandler)->GetFarEndpointAddressIp();
- uint16_t peerPort=((TCPCarrier *)pHandler)->GetFarEndpointPort();
- string md5Code = md5(peerAddress+sharedkey, true);
- if(mySecondparam !=V_STRING) {
- FATAL("Invalid connect request");
- return false;
- }
- string myTokenKey=(string)mySecondparam;
- if(myTokenKey !=md5Code) {
- FATAL("Invalid Token-Key");
- return false;
- }
- INFO("Requested URL Token-Key is \'%s\'", STR((string) myTokenKey));
- INFO("IP + Shared Key is \'%s\'", STR((string) peerAddress+sharedkey));
- INFO("Calculated URL Token-Key is \'%s\'", STR((string) md5Code));
- INFO("Peer IP is \'%s\'", STR((string) peerAddress));
- INFO("Peer Port is \'%i\'", peerPort);
- }
- //2. This should be a key-value map
- if (connectParams != V_MAP) {
- FATAL("Incorrect invoke params:\n%s", STR(request.ToString()));
- return false;
- }
- //3. Let's extract few values. Make sure we extract them using non-case-sensitive keys
- Variant tcUrl = connectParams.GetValue(RM_INVOKE_PARAMS_CONNECT_TCURL, false);
- //If you are sure about case-sensitive settings, you can extract it directly like this
- Variant swfUrl = connectParams[RM_INVOKE_PARAMS_CONNECT_SWFURL];
- //Variant tcUrl = connectParams[RM_INVOKE_PARAMS_CONNECT_TCURL];
- Variant pageUrl = connectParams[RM_INVOKE_PARAMS_CONNECT_PAGEURL];
- //4. Do some validation on them.
- if (pageUrl != V_STRING) {
- FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_PAGEURL": %s", STR(request.ToString()));
- return false;
- }
- if (tcUrl != V_STRING) {
- FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_TCURL":\n%s", STR(request.ToString()));
- return false;
- }
- string rawURI;
- URI uri;
- if (!URI::FromString(pageUrl, true, uri)) {
- FATAL("Unable to parse the uri %s", STR(rawURI));
- return false;
- }
- // as proto we are going to validate rtmp/rtmpe
- // added if/elseif/else and INFO like Andriy suggested
- if (((string) tcUrl) != "rtmp://media.bfy.ro/livestream") {
- INFO("Connect schema is \'%s\'", STR((string) tcUrl));
- } else if (((string) tcUrl) != "rtmpe://media.bfy.ro/livestream") {
- INFO("Connect schema is \'%s\'", STR((string) tcUrl));
- }
- else {
- FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_TCURL": %s", STR(request.ToString()));
- return false;
- }
- // we use our static flowplayer which is always on the same address
- // added if/elseif/else and INFO like Andriy suggested
- if (((string) swfUrl) != "http://www.a-queens.ro/flowplayer/flowplayer-3.2.5.swf") {
- INFO("Flash player address is \'%s\'", STR((string) swfUrl));
- } else if (((string) swfUrl) != "http://www.a-queens.ro/player.swf") {
- INFO("Flash player address is \'%s\'", STR((string) swfUrl));
- }
- else {
- FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_SWFURL": %s", STR(request.ToString()));
- return false;
- }
- // ip which resolve our calling webpage(s)/website(s)
- // added if/elseif/else and INFO like Andriy suggested
- if (((string) uri.ip) == "86.122.125.158") {
- INFO("Stream calling webpage is \'%s\'", STR((string) pageUrl));
- INFO("stream Calling webpage IP is \'%s\'", STR((string) uri.ip));
- }
- else {
- FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_PAGEURL": %s", STR(request.ToString()));
- return false;
- }
- return true;
- //NYIR;
- }
- bool RTMPAppProtocolHandler::ProcessGetAvailableFlvs(BaseRTMPProtocol *pFrom, Variant &request) {
- Variant parameters;
- parameters.PushToArray(Variant());
- parameters.PushToArray(Variant());
- vector<string> files;
- if (!ListFolder(_configuration[CONF_APPLICATION_MEDIAFOLDER], files)) {
- FATAL("Unable to list folder %s",
- STR(_configuration[CONF_APPLICATION_MEDIAFOLDER]));
- return false;
- }
- string file, name, extension;
- FOR_VECTOR_ITERATOR(string, files, i) {
- file = VECTOR_VAL(i);
- splitFileName(file, name, extension);
- extension = lowercase(extension);
- if (extension != MEDIA_TYPE_FLV
- && extension != MEDIA_TYPE_MP3
- && extension != MEDIA_TYPE_MP4
- && extension != MEDIA_TYPE_M4A
- && extension != MEDIA_TYPE_M4V
- && extension != MEDIA_TYPE_MOV
- && extension != MEDIA_TYPE_F4V
- && extension != MEDIA_TYPE_TS
- && extension != MEDIA_TYPE_MKV)
- continue;
- string flashName = "";
- if (extension == MEDIA_TYPE_FLV) {
- flashName = name;
- } else if (extension == MEDIA_TYPE_MP3) {
- flashName = extension + ":" + name;
- } else {
- if (extension == MEDIA_TYPE_MP4
- || extension == MEDIA_TYPE_M4A
- || extension == MEDIA_TYPE_M4V
- || extension == MEDIA_TYPE_MOV
- || extension == MEDIA_TYPE_F4V) {
- flashName = MEDIA_TYPE_MP4":" + name + "." + extension;
- } else {
- flashName = extension + ":" + name + "." + extension;
- }
- }
- // FINEST("Parsing `%s`", STR(flashName));
- // Variant v = GetMetaData(flashName, true);
- // if (v != V_NULL)
- parameters[(uint32_t) 1].PushToArray(flashName);
- }
- map<uint32_t, BaseStream *> allInboundStreams =
- GetApplication()->GetStreamsManager()->FindByType(ST_IN_NET, true);
- FOR_MAP(allInboundStreams, uint32_t, BaseStream *, i) {
- parameters[(uint32_t) 1].PushToArray(MAP_VAL(i)->GetName());
- }
- Variant message = GenericMessageFactory::GetInvoke(3, 0, 0, false, 0,
- "SetAvailableFlvs", parameters);
- return SendRTMPMessage(pFrom, message);
- }
- bool RTMPAppProtocolHandler::ProcessInsertMetadata(BaseRTMPProtocol *pFrom, Variant &request) {
- //STREAMING REFACTORING
- // //FINEST("request:\n%s", STR(request.ToString()));
- //
- // //1. Get the stream name
- // if ((VariantType) M_INVOKE_PARAM(request, 1) != V_STRING)
- // return true;
- // string streamName = M_INVOKE_PARAM(request, 1);
- //
- // //2. Get the stream
- // vector<BaseOutboundStream *> streams = FindOSByName(streamName);
- // BaseInboundStream *pInboundStream = NULL;
- //
- // FOR_VECTOR(streams, i) {
- // if (streams[i]->GetProtocol()->GetId() == pFrom->GetId()) {
- // pInboundStream = streams[i]->GetInboundStream();
- // break;
- // }
- // }
- // if (pInboundStream == NULL) {
- // FINEST("This stream is not yet bound");
- // return true;
- // }
- // if (pInboundStream->IsEnqueueForDelete()) {
- // FINEST("This stream will be deleted soon");
- // return true;
- // }
- //
- // //3. Prepare the FlexStreamSend message
- // Variant params;
- // params.PushToArray(M_INVOKE_PARAM(request, 2));
- // return pInboundStream->SendStreamMessage("onMetaData", params);
- NYIR;
- }
- #endif /* HAS_PROTOCOL_RTMP */
Advertisement
Add Comment
Please, Sign In to add comment