/// <summary> /// Handles one message. /// </summary> /// <param name="message">The message.</param> private void HandleOneMessage(RtspMessage message) { Contract.Requires(message != null); RtspListener destination = null; if (message is RtspRequest) { destination = HandleRequest(ref message); _logger.Debug("Dispatch message from {0} to {1}", message.SourcePort != null ? message.SourcePort.RemoteAdress : "UNKNOWN", destination != null ? destination.RemoteAdress : "UNKNOWN"); // HandleRequest can change message type. if (message is RtspRequest) { var context = new OriginContext(); context.OriginCSeq = message.CSeq; context.OriginSourcePort = message.SourcePort; (message as RtspRequest).ContextData = context; } } else if (message is RtspResponse) { RtspResponse response = message as RtspResponse; if (response.OriginalRequest != null) { var context = response.OriginalRequest.ContextData as OriginContext; if (context != null) { destination = context.OriginSourcePort; response.CSeq = context.OriginCSeq; _logger.Debug("Dispatch response back to {0}", destination.RemoteAdress); } } HandleResponse(response); } if (destination != null) { bool isGood = destination.SendMessage(message); if (!isGood) { destination.Stop(); _serverListener.Remove(destination.RemoteAdress); // send back a message because we can't forward. if (message is RtspRequest && message.SourcePort != null) { RtspRequest request = message as RtspRequest; RtspResponse theDirectResponse = request.CreateResponse(); _logger.Warn("Error during forward : {0}. So sending back a direct error response", message.Command); theDirectResponse.ReturnCode = 500; request.SourcePort.SendMessage(theDirectResponse); } } } }
public void Disconnect() { _client.Stop(); _keepaliveTimer = null; _videoDataChannel = 0; _decoder = null; _h264Payload = new H264Payload(); }
private async void HandleRequest(RtspRequest request) { RtspListener listener = null; if (_listeners.TryGetValue(request.RemoteEndpoint.ToString(), out listener)) { await Task.Run(() => { try { int receivedCseq = request.CSeq; request.Context = new RequestContext(listener); var response = _dispatcher.Dispatch(request); if (response != null) { if (response.HasBody) { response.Headers[RtspHeaders.Names.CONTENT_LENGTH] = response.Body.Length.ToString(); } response.Headers[RtspHeaders.Names.CSEQ] = receivedCseq.ToString(); listener.SendResponse(response); // Remove listener on teardown. // VLC will terminate the connection and the listener will stop itself properly. // Some clients will send Teardown but keep the connection open, in this type scenario we'll close it. if (request.Method == RtspRequest.RtspMethod.TEARDOWN) { listener.Stop(); _listeners.Remove(listener.Endpoint.ToString()); } } } catch (Exception e) { LOG.Error(e, $"Caught exception while procesing RTSP request from {request.URI}"); listener.SendResponse(RtspResponse.CreateBuilder() .Status(RtspResponse.Status.InternalServerError) .Build()); } }); } else { LOG.Error($"Unable to process request because no active connection was found for {request.URI}"); } }
public void ReceiveOptionsMessage() { string message = string.Empty; message += "OPTIONS * RTSP/1.0\n"; message += "CSeq: 1\n"; message += "Require: implicit-play\n"; message += "Proxy-Require: gzipped-messages\n"; message += "\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler <RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf <RtspRequest>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspRequest theRequest = theMessage as RtspRequest; Assert.AreEqual(RtspRequest.RequestType.OPTIONS, theRequest.RequestTyped); Assert.AreEqual(3, theRequest.Headers.Count); Assert.AreEqual(1, theRequest.CSeq); Assert.Contains("Require", theRequest.Headers.Keys); Assert.Contains("Proxy-Require", theRequest.Headers.Keys); Assert.AreEqual(null, theRequest.RtspUri); Assert.AreEqual(0, _receivedData.Count); }
public void ReceiveResponseMessage() { string message = string.Empty; message += "RTSP/1.0 551 Option not supported\n"; message += "CSeq: 302\n"; message += "Unsupported: funky-feature\n"; message += "\r\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler <RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf <RtspResponse>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspResponse theResponse = theMessage as RtspResponse; Assert.AreEqual(551, theResponse.ReturnCode); Assert.AreEqual("Option not supported", theResponse.ReturnMessage); Assert.AreEqual(2, theResponse.Headers.Count); Assert.AreEqual(302, theResponse.CSeq); Assert.AreEqual(0, _receivedData.Count); }
public void ReceivePlayMessage() { string message = string.Empty; message += "PLAY rtsp://audio.example.com/audio RTSP/1.0\r\n"; message += "CSeq: 835\r\n"; message += "\r\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler <RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf <RtspRequest>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspRequest theRequest = theMessage as RtspRequest; Assert.AreEqual(RtspRequest.RequestType.PLAY, theRequest.RequestTyped); Assert.AreEqual(1, theRequest.Headers.Count); Assert.AreEqual(835, theRequest.CSeq); Assert.AreEqual("rtsp://audio.example.com/audio", theRequest.RtspUri.ToString()); Assert.AreEqual(0, _receivedData.Count); }
public void ReceiveData() { Random rnd = new Random(); byte[] data = new byte[0x0234]; rnd.NextBytes(data); byte[] buffer = new byte[data.Length + 4]; buffer[0] = 0x24; // $ buffer[1] = 11; buffer[2] = 0x02; buffer[3] = 0x34; Buffer.BlockCopy(data, 0, buffer, 4, data.Length); MemoryStream stream = new MemoryStream(buffer); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler <RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(500); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(0, _receivedMessage.Count); Assert.AreEqual(1, _receivedData.Count); Assert.IsInstanceOf <RtspData>(_receivedData[0]); RtspData dataMessage = _receivedData[0] as RtspData; Assert.AreEqual(11, dataMessage.Channel); Assert.AreSame(testedListener, dataMessage.SourcePort); Assert.AreEqual(data, dataMessage.Data); }
public void ReceiveData() { Random rnd = new Random(); byte[] data = new byte[0x0234]; rnd.NextBytes(data); byte[] buffer = new byte[data.Length + 4]; buffer[0] = 0x24; // $ buffer[1] = 11; buffer[2] = 0x02; buffer[3] = 0x34; Buffer.BlockCopy(data, 0, buffer, 4, data.Length); MemoryStream stream = new MemoryStream(buffer); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(500); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(0, _receivedMessage.Count); Assert.AreEqual(1, _receivedData.Count); Assert.IsInstanceOf<RtspData>(_receivedData[0]); RtspData dataMessage = _receivedData[0] as RtspData; Assert.AreEqual(11, dataMessage.Channel); Assert.AreSame(testedListener, dataMessage.SourcePort); Assert.AreEqual(data, dataMessage.Data); }
public void ReceiveNoMessage() { string message = string.Empty; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler <RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler <RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); Assert.AreEqual(0, _receivedMessage.Count); Assert.AreEqual(0, _receivedData.Count); }
public void ReceiveResponseMessage() { string message = string.Empty; message += "RTSP/1.0 551 Option not supported\n"; message += "CSeq: 302\n"; message += "Unsupported: funky-feature\n"; message += "\r\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf<RtspResponse>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspResponse theResponse = theMessage as RtspResponse; Assert.AreEqual(551, theResponse.ReturnCode); Assert.AreEqual("Option not supported", theResponse.ReturnMessage); Assert.AreEqual(2, theResponse.Headers.Count); Assert.AreEqual(302, theResponse.CSeq); Assert.AreEqual(0, _receivedData.Count); }
public void ReceivePlayMessage() { string message = string.Empty; message += "PLAY rtsp://audio.example.com/audio RTSP/1.0\r\n"; message += "CSeq: 835\r\n"; message += "\r\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf<RtspRequest>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspRequest theRequest = theMessage as RtspRequest; Assert.AreEqual(RtspRequest.RequestType.PLAY, theRequest.RequestTyped); Assert.AreEqual(1, theRequest.Headers.Count); Assert.AreEqual(835, theRequest.CSeq); Assert.AreEqual("rtsp://audio.example.com/audio", theRequest.RtspUri.ToString()); Assert.AreEqual(0, _receivedData.Count); }
public void ReceiveOptionsMessage() { string message = string.Empty; message += "OPTIONS * RTSP/1.0\n"; message += "CSeq: 1\n"; message += "Require: implicit-play\n"; message += "Proxy-Require: gzipped-messages\n"; message += "\n"; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); //Check the message recevied Assert.AreEqual(1, _receivedMessage.Count); RtspChunk theMessage = _receivedMessage[0]; Assert.IsInstanceOf<RtspRequest>(theMessage); Assert.AreEqual(0, theMessage.Data.Length); Assert.AreSame(testedListener, theMessage.SourcePort); RtspRequest theRequest = theMessage as RtspRequest; Assert.AreEqual(RtspRequest.RequestType.OPTIONS, theRequest.RequestTyped); Assert.AreEqual(3, theRequest.Headers.Count); Assert.AreEqual(1, theRequest.CSeq); Assert.Contains("Require", theRequest.Headers.Keys); Assert.Contains("Proxy-Require", theRequest.Headers.Keys); Assert.AreEqual(null, theRequest.RtspUri); Assert.AreEqual(0, _receivedData.Count); }
public void ReceiveNoMessage() { string message = string.Empty; MemoryStream stream = new MemoryStream(ASCIIEncoding.UTF8.GetBytes(message)); _mockTransport.GetStream().Returns(stream); // Setup test object. RtspListener testedListener = new RtspListener(_mockTransport); testedListener.MessageReceived += new EventHandler<RtspChunkEventArgs>(MessageReceived); testedListener.DataReceived += new EventHandler<RtspChunkEventArgs>(DataReceived); // Run testedListener.Start(); System.Threading.Thread.Sleep(100); testedListener.Stop(); // Check the transport was closed. _mockTransport.Received().Close(); Assert.AreEqual(0, _receivedMessage.Count); Assert.AreEqual(0, _receivedData.Count); }