SendResponseMessage() публичный Метод

public SendResponseMessage ( ) : bool
Результат bool
        private bool SendAuthenticationChallenge(RtspProtocol from, Variant realm)
        {
            //10. Ok, the user doesn't know that this needs authentication. We
            //will respond back with a nice 401. Generate the line first
            string wwwAuthenticate = HTTPAuthHelper.GetWWWAuthenticateHeader(
                    realm["method"],
                    realm["name"]);

            //12. Save the nonce for later validation when new requests are coming in again
            from.CustomParameters["wwwAuthenticate"] = wwwAuthenticate;

            //13. send the response
            from.PushResponseFirstLine(RTSP_VERSION_1_0, 401, "Unauthorized");
            from.PushResponseHeader(HTTP_HEADERS_WWWAUTHENTICATE, wwwAuthenticate);
            return from.SendResponseMessage();
        }
        private bool HandleRTSPRequestAnnounce(RtspProtocol pFrom, Variant requestHeaders, string requestContent)
        {
            //1. Make sure we ONLY handle application/sdp
            if ((string)requestHeaders[RTSP_HEADERS,RTSP_HEADERS_CONTENT_TYPE]!= RTSP_HEADERS_ACCEPT_APPLICATIONSDP)
            {
                FATAL("Invalid ANNOUNCE request:\n{0}", (requestHeaders.ToString()));
                return false;
            }

            //2. Get the SDP
            var sdp = pFrom.InboundSDP;

            //3. Parse the SDP
            if (!SDP.ParseSDP(sdp, requestContent))
            {
                FATAL("Unable to parse the SDP");
                return false;
            }

            //4. Get the first video track
            var videoTrack = sdp.GetVideoTrack(0,requestHeaders[RTSP_FIRST_LINE,RTSP_URL]);
                    
            var audioTrack = sdp.GetAudioTrack(0,requestHeaders[RTSP_FIRST_LINE,RTSP_URL]);
                    

            //5. Store the tracks inside the session for later use
            if (audioTrack != VariantType.Null)
            {
                pFrom.CustomParameters["pendingTracks",audioTrack["globalTrackIndex"]] = audioTrack;
            }
            if (videoTrack != VariantType.Null)
            {
                pFrom.CustomParameters["pendingTracks",videoTrack["globalTrackIndex"]] = videoTrack;
            }

            //6. Mark this connection as inbound connection
            pFrom.CustomParameters["isInbound"] = true;

            //7. Save the streamName
            string streamName = sdp.GetStreamName();
            if (streamName == "")
            {
                streamName = $"rtsp_stream_{pFrom.Id}";
            }
            pFrom.CustomParameters["sdpStreamName"] = streamName;
            streamName = new Uri(requestHeaders[RTSP_FIRST_LINE, RTSP_URL],UriKind.Absolute).Segments.Last();
            //8. Save the bandwidth hint
            pFrom.CustomParameters["sdpBandwidthHint"] = sdp.GetTotalBandwidth();

            //9. Get the inbound connectivity
            InboundConnectivity pInboundConnectivity = pFrom.GetInboundConnectivity(
                    streamName,
                    sdp.GetTotalBandwidth(),Application.Configuration[CONF_APPLICATION_RTCPDETECTIONINTERVAL]);
            if (pInboundConnectivity == null)
            {
                FATAL("Unable to create inbound connectivity");
                return false;
            }

            //8. Send back the response
            pFrom.PushResponseFirstLine(RTSP_VERSION_1_0, 200, "OK");
            return pFrom.SendResponseMessage();
        }
        private bool HandleRTSPRequestPlay(RtspProtocol pFrom, Variant requestHeaders, string requestContent)
        {
            //1. Get the outbound connectivity
            bool forceTcp = pFrom.CustomParameters["forceTcp"];
            var pOutboundConnectivity = GetOutboundConnectivity(pFrom, true);
            if (pOutboundConnectivity == null)
            {
                FATAL("Unable to get the outbound connectivity");
                return false;
            }

            if (forceTcp)
            {
                //3. Get the audio/video client ports
                byte videoDataChannelNumber = 0xff;
                byte videoRtcpChannelNumber = 0xff;
                byte audioDataChannelNumber = 0xff;
                byte audioRtcpChannelNumber = 0xff;
                if (pFrom.CustomParameters["audioDataChannelNumber"]!=null)
                {
                    audioDataChannelNumber = pFrom.CustomParameters["audioDataChannelNumber"];
                    audioRtcpChannelNumber = pFrom.CustomParameters["audioRtcpChannelNumber"];
                }
                if (pFrom.CustomParameters["videoDataChannelNumber"] != null)
                {
                    videoDataChannelNumber = pFrom.CustomParameters["videoDataChannelNumber"];
                    videoRtcpChannelNumber = pFrom.CustomParameters["videoRtcpChannelNumber"];
                }

                //4.register the video
                if (videoDataChannelNumber != 0xff)
                {
                    if (!pOutboundConnectivity.RegisterTCPVideoClient(pFrom.Id,
                            videoDataChannelNumber, videoRtcpChannelNumber))
                    {
                        FATAL("Unable to register video stream");
                        return false;
                    }
                }

                //5. Register the audio
                if (audioDataChannelNumber != 0xff)
                {
                    if (!pOutboundConnectivity.RegisterTCPAudioClient(pFrom.Id,
                            audioDataChannelNumber, audioRtcpChannelNumber))
                    {
                        FATAL("Unable to register audio stream");
                        return false;
                    }
                }
            }
            else
            {
                //3. Get the audio/video client ports
                ushort videoDataPortNumber = 0;
                ushort videoRtcpPortNumber = 0;
                ushort audioDataPortNumber = 0;
                ushort audioRtcpPortNumber = 0;
                if (pFrom.CustomParameters["audioDataPortNumber"] != null)
                {
                    audioDataPortNumber = pFrom.CustomParameters["audioDataPortNumber"];
                    audioRtcpPortNumber = pFrom.CustomParameters["audioRtcpPortNumber"];
                }
                if (pFrom.CustomParameters["videoDataPortNumber"] != null)
                {
                    videoDataPortNumber = pFrom.CustomParameters["videoDataPortNumber"];
                    videoRtcpPortNumber = pFrom.CustomParameters["videoRtcpPortNumber"];
                }

                //4.register the video
                if (videoDataPortNumber != 0)
                {
                    var videoDataAddress = ((TCPCarrier)pFrom.IOHandler).FarInfo;
                    videoDataAddress.Port = videoDataPortNumber;
                    var videoRtcpAddress = ((TCPCarrier)pFrom.IOHandler).FarInfo;
                    videoRtcpAddress.Port = videoRtcpPortNumber;
                    if (!pOutboundConnectivity.RegisterUDPVideoClient(pFrom.Id,
                            videoDataAddress, videoRtcpAddress))
                    {
                        FATAL("Unable to register video stream");
                        return false;
                    }
                }

                //5. Register the audio
                if (audioDataPortNumber != 0)
                {
                    var audioDataAddress = ((TCPCarrier)pFrom.IOHandler).FarInfo;
                    audioDataAddress.Port = audioDataPortNumber;
                    var audioRtcpAddress = ((TCPCarrier)pFrom.IOHandler).FarInfo;
                    audioRtcpAddress.Port = audioRtcpPortNumber;
                    if (!pOutboundConnectivity.RegisterUDPAudioClient(pFrom.Id,audioDataAddress, audioRtcpAddress))
                    {
                        FATAL("Unable to register audio stream");
                        return false;
                    }
                }
            }

            //6. prepare the response
            pFrom.PushResponseFirstLine(RTSP_VERSION_1_0, 200, "OK");
            //7. Done
            return pFrom.SendResponseMessage();
        }
        public bool HandleRTSPRequest(RtspProtocol from,Variant requestHeaders,string requestContent)
        {
            string method = requestHeaders[RTSP_FIRST_LINE, RTSP_METHOD];
            //1. we need a CSeq
            if (requestHeaders[RTSP_HEADERS, RTSP_HEADERS_CSEQ] == null)
            {
                FATAL("Request doesn't have {0}:\n{1}", RTSP_HEADERS_CSEQ, requestHeaders);
                return false;
            }
            //2. Validate session id
            string wantedSessionId = from.SessionId;
            if (!string.IsNullOrEmpty(wantedSessionId))
            {
                var requestSessionId = "";
                if (requestHeaders[RTSP_HEADERS, RTSP_HEADERS_SESSION] == null)
                {
                    FATAL("No session id");
                    return false;
                }
                requestSessionId = requestHeaders[RTSP_HEADERS, RTSP_HEADERS_SESSION];
                var parts = requestSessionId.Split(';');
                if (parts.Length >= 1)
                {
                    requestSessionId = parts[0];
                }
                if (requestSessionId != wantedSessionId)
                {
                    FATAL("Invalid session ID. Wanted: `{0}`; Got: `{1}`",
                            (wantedSessionId),
                            (requestSessionId));
                    return false;
                }
            }
            //4. Prepare a fresh new response. Add the sequence number
            from.ClearResponseMessage();
            from.PushResponseHeader(RTSP_HEADERS_CSEQ, requestHeaders[RTSP_HEADERS, RTSP_HEADERS_CSEQ]);
            //5. Do we have authentication? We will authenticate everything except "OPTIONS"
            if ( !string.IsNullOrEmpty(_usersFile) && NeedAuthentication(from,requestHeaders,requestContent))
            {
                //6. Re-parse authentication file if necessary
                if (!ParseUsersFile())
                {
                    FATAL("Unable to parse authentication file");
                    return false;
                }
                //7. Get the real name to use it further in authentication process
                string realmName = GetAuthenticationRealm(from, requestHeaders,
                        requestContent);
                //8. Do we have that realm?
                if (_realms[realmName]==null)
                {
                    FATAL("Realm `{0}` not found", (realmName));
                    return false;
                }
                Variant realm = _realms[realmName];
                //9. Is the user even trying to authenticate?
                if (requestHeaders[RTSP_HEADERS, RTSP_HEADERS_AUTHORIZATION] == null)
                {
                    return SendAuthenticationChallenge(from, realm);
                }
                else
                {
                    //14. The client sent us some response. Validate it now
                    //Did we ever sent him an authorization challange?
                    if (from.CustomParameters["wwwAuthenticate"] ==null)
                    {
                        FATAL("Client tried to authenticate and the server didn't required that");
                        return false;
                    }

                    //15. Get the server challenge
                    string wwwAuthenticate = from.CustomParameters["wwwAuthenticate"];

                    //16. Get the client response
                    string authorization = requestHeaders[RTSP_HEADERS, RTSP_HEADERS_AUTHORIZATION];

                    //17. Try to authenticate
                    if (!HTTPAuthHelper.ValidateAuthRequest(wwwAuthenticate,
                            authorization,
                            method,
                            (string)requestHeaders[RTSP_FIRST_LINE,RTSP_URL],
                            realm))
                    {
                        WARN("Authorization failed: challenge: {0}; response: {1}",
                                wwwAuthenticate, authorization);
                        return SendAuthenticationChallenge(from, realm);
                    }

                    //18. Success. User authenticated
                    //INFO("User authenticated: %s", (authorization));
                }
            }
            switch (method)
            {
                case RTSP_METHOD_OPTIONS:
                    from.PushResponseFirstLine(RTSP_VERSION_1_0, 200, "OK");
                    from.PushResponseHeader(RTSP_HEADERS_PUBLIC, "DESCRIBE, OPTIONS, PAUSE, PLAY, SETUP, TEARDOWN, ANNOUNCE, RECORD");
                    return from.SendResponseMessage();
                case RTSP_METHOD_DESCRIBE:
                    //1. get the stream name
                    Uri uri = new Uri(requestHeaders[RTSP_FIRST_LINE,RTSP_URL]);
                    
                    string streamName = (uri.Segments.LastOrDefault(x=>!x.EndsWith("/"))??"")+uri.Query;
                    if (streamName == "")
                    {
                        FATAL("Invalid stream name");
                        return false;
                    }

                    //2. Get the inbound stream capabilities
                    IInNetStream pInStream = GetInboundStream(streamName);

                    //3. Prepare the body of the response
                    string outboundContent = ComputeSDP(from, streamName, "", "0.0.0.0");
                    if (outboundContent == "")
                    {
                        FATAL("Unable to compute SDP");
                        return false;
                    }

                    //4. Save the stream id for later usage
                    from.CustomParameters["streamId"] = pInStream.UniqueId;

                    //5. Mark this connection as outbound connection
                    from.CustomParameters["isInbound"] = false;

                    //6. prepare the response
                    from.PushResponseFirstLine(RTSP_VERSION_1_0, 200, "OK");
                    from.PushResponseHeader(RTSP_HEADERS_CONTENT_TYPE, RTSP_HEADERS_ACCEPT_APPLICATIONSDP);
                    from.PushResponseContent(outboundContent, false);

                    //7. Done
                    return from.SendResponseMessage();
                case RTSP_METHOD_SETUP:
                    if (from.CustomParameters["isInbound"] != VariantType.Boolean)
                    {
                        FATAL("Invalid state");
                        return false;
                    }

                    return @from.CustomParameters["isInbound"] ? HandleRTSPRequestSetupInbound(@from, requestHeaders, requestContent) : HandleRTSPRequestSetupOutbound(@from, requestHeaders, requestContent);
                case RTSP_METHOD_PLAY:
                    return HandleRTSPRequestPlay(from, requestHeaders, requestContent);
                case RTSP_METHOD_TEARDOWN:
                    from.EnqueueForDelete();
                    return true;
                case RTSP_METHOD_ANNOUNCE:
                    return HandleRTSPRequestAnnounce(from, requestHeaders, requestContent);
                case RTSP_METHOD_RECORD:
                    //1. Make sure we have everything and we are in the proper state
                    if ((from.CustomParameters["isInbound"] != VariantType.Boolean)
                            || ((bool)from.CustomParameters["isInbound"] != true))
                    {
                        FATAL("Invalid state");
                        return false;
                    }

                    if (from.CustomParameters["pendingTracks"] != VariantType.Map)
                    {
                        FATAL("Invalid state");
                        return false;
                    }

                    //3. Get the inbound connectivity
                    InboundConnectivity pConnectivity = from.InboundConnectivity;
                    if (pConnectivity == null)
                    {
                        FATAL("Unable to get inbound connectivity");
                        return false;
                    }
                    if (!pConnectivity.Initialize())
                    {
                        FATAL("Unable to initialize inbound connectivity");
                        return false;
                    }

                    //4. Send back the response
                    from.PushResponseFirstLine(RTSP_VERSION_1_0, 200, "OK");
                    return from.SendResponseMessage();
                case RTSP_METHOD_PAUSE:
                    from.PushResponseFirstLine(RTSP_VERSION_1_0, 200, "OK");
                    return from.SendResponseMessage();
                default:
                    return false;
            }
        }