예제 #1
0
 public ConcatenatedStream(params Stream[] underlier)
 {
     StreamList = underlier;
     _pos       = 0L;
     _Icurrent  = 0;
     _len       = StreamList.Sum(v => v.Length - v.Position);
 }
예제 #2
0
        public void TestParse_16bPayloadLength_Masked()
        {
            // 0xC2 = 1100 0010
            //        FRRR opco
            //        ISSS de
            //        NVVV
            //         123
            var buffer = new byte[]
            {
                0xC2, 128 + 126,
                0x08, 0,   // 16b length in Big-Endian = 0x0800 = 2048
                5, 6, 7, 8 // 32b mask
            };
            var payload = new DummyDataStream(2048);
            var header  = new ByteArray(buffer);
            var parser  = new WebSocketMessage.Parser();

            parser.ParseHeader(header);
            var binMsg = new StreamList();

            binMsg.Add(header);
            binMsg.Add(payload);
            var msg = parser.Close(binMsg);

            Assert.True(msg.FIN);
            Assert.True(msg.RSV1);
            Assert.False(msg.RSV2);
            Assert.False(msg.RSV3);
            Assert.Equal(WebSocketMessage.OpcodeType.Binary, msg.Opcode);
            Assert.Equal(2048, msg.PayloadLength);
            Assert.True(msg.MASK);
            Assert.Equal(4, msg.MaskingKey.Length);
            Assert.Equal(6, msg.MaskingKey[1]);
        }
예제 #3
0
        public void TestParse_64bPayloadLength_NoMask()
        {
            // 0xC1 = 1100 0001
            //        FRRR opco
            //        ISSS de
            //        NVVV
            //         123
            var buffer = new byte[]
            {
                0xC1, 127,
                0, 0, 0, 0, 0, 1, 0, 0, // 64b length in Big-Endian = 0x10000 = 65 536
            };
            var payload = new DummyDataStream(2048);
            var header  = new ByteArray(buffer);
            var parser  = new WebSocketMessage.Parser();

            parser.ParseHeader(header);
            var binMsg = new StreamList();

            binMsg.Add(header);
            binMsg.Add(payload);
            Assert.Throws(typeof(ArgumentOutOfRangeException), () => parser.Close(binMsg));
            binMsg.Add(new DummyDataStream(65536 - 2048));
            var msg = parser.Close(binMsg);

            Assert.True(msg.FIN);
            Assert.True(msg.RSV1);
            Assert.False(msg.RSV2);
            Assert.False(msg.RSV3);
            Assert.Equal(WebSocketMessage.OpcodeType.Text, msg.Opcode);
            Assert.Equal(65536, msg.PayloadLength);
            Assert.False(msg.MASK);
        }
예제 #4
0
        public void TestParse_7bPayloadLength_NoMask()
        {
            // 0xC2 = 1100 0010
            //        FRRR opco
            //        ISSS de
            //        NVVV
            //         123
            var buffer  = new byte[] { 0xC2, 10 };
            var payload = new DummyDataStream(10);
            var header  = new ByteArray(buffer);
            var parser  = new WebSocketMessage.Parser();

            parser.ParseHeader(header);
            var binMsg = new StreamList();

            binMsg.Add(header);
            binMsg.Add(payload);
            var msg = parser.Close(binMsg);

            Assert.True(msg.FIN);
            Assert.True(msg.RSV1);
            Assert.False(msg.RSV2);
            Assert.False(msg.RSV3);
            Assert.Equal(WebSocketMessage.OpcodeType.Binary, msg.Opcode);
            Assert.Equal(10, msg.PayloadLength);
            Assert.False(msg.MASK);
        }
예제 #5
0
        public void TestReceiveFour_Full()
        {
            // 0xC2 = 1100 0010
            //        FRRR opco
            //        ISSS de
            //        NVVV
            //         123
            var buffer    = new byte[] { 0xC2, 10 };
            var payload   = new DummyDataStream(10);
            var header    = new ByteArray(buffer);
            var websocket = new BaseWebSocket(logger);
            int called    = 0;

            websocket.MessageParsed += delegate(object sender, WebSocketMessage msg)
            {
                ++called;
                Assert.True(msg.FIN);
                Assert.True(msg.RSV1);
                Assert.False(msg.RSV2);
                Assert.False(msg.RSV3);
                Assert.Equal(WebSocketMessage.OpcodeType.Binary, msg.Opcode);
                Assert.Equal(10, msg.PayloadLength);
                Assert.False(msg.MASK);
            };

            var binMsg = new StreamList();

            binMsg.Add(header);
            binMsg.Add(payload);
            binMsg.Add(binMsg);
            binMsg.Add(binMsg);
            websocket.Receive(binMsg);
            Assert.Equal(4, called);
        }
예제 #6
0
 private HttpData(IDataStream headerData, IReadOnlyDictionary <string, string> headers, IReadOnlyList <string> headerKeys, bool isRequest, string version, int code, string reasonPhrase, HttpRequestMethod method, string requestTarget, IDataStream bodyData = null, IDataStream messageData = null)
 {
     HeaderData = headerData;
     BodyData   = bodyData ?? EmptyData.Instance;
     if (messageData == null)
     {
         var list = new StreamList();
         list.Add(HeaderData);
         list.Add(BodyData);
         list.Freeze();
         MessageData = list;
     }
     else
     {
         MessageData = messageData;
     }
     Headers       = headers;
     HeaderKeys    = headerKeys;
     IsRequest     = isRequest;
     Version       = version;
     Code          = code;
     ReasonPhrase  = reasonPhrase;
     Method        = method;
     RequestTarget = requestTarget;
 }
예제 #7
0
        protected override void ThreadFunc()
        {
            try
            {
                // Step 1 : create a stream with header information
                // Step 2 : create a stream from the file
                // Step 3 : create a StreamList
                // Step 4 : create a HTTPResponse object
                // Step 5 : call the Receive function of the response object

                using (System.IO.Stream fs = HTTPManager.IOService.CreateFileStream(this.CurrentRequest.CurrentUri.LocalPath, FileStreamModes.OpenRead))
                    using (StreamList stream = new StreamList(new BufferPoolMemoryStream(), fs))
                    {
                        // This will write to the MemoryStream
                        stream.Write("HTTP/1.1 200 Ok\r\n");
                        stream.Write("Content-Type: application/octet-stream\r\n");
                        stream.Write("Content-Length: " + fs.Length.ToString() + "\r\n");
                        stream.Write("\r\n");

                        stream.Seek(0, System.IO.SeekOrigin.Begin);

                        base.CurrentRequest.Response = new HTTPResponse(base.CurrentRequest, stream, base.CurrentRequest.UseStreaming, false);

                        if (!CurrentRequest.Response.Receive())
                        {
                            CurrentRequest.Response = null;
                        }
                    }
            }
            catch (Exception e)
            {
                CurrentRequest.Response = null;

                if (!CurrentRequest.IsCancellationRequested)
                {
                    CurrentRequest.Exception = e;
                    CurrentRequest.State     = HTTPRequestStates.Error;
                }
            }
            finally
            {
                if (this.CurrentRequest.IsCancellationRequested)
                {
                    this.CurrentRequest.Response = null;
                    this.CurrentRequest.State    = this.CurrentRequest.IsTimedOut ? HTTPRequestStates.TimedOut : HTTPRequestStates.Aborted;
                }
                else if (this.CurrentRequest.Response == null)
                {
                    this.CurrentRequest.State = HTTPRequestStates.Error;
                }
                else
                {
                    this.CurrentRequest.State = HTTPRequestStates.Finished;
                }

                ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HTTPConnectionStates.Closed));
            }
        }
예제 #8
0
        public void TestAddListToItself()
        {
            var list = new StreamList();

            list.Add(new ByteArray(new byte[] { 5, 6 }));
            list.Add(list);
            Assert.Equal(4, list.Length);
            Assert.Equal(5, list.ReadByte(2));
        }
예제 #9
0
        public void TestFreeze()
        {
            var list = new StreamList();

            list.Add(EmptyData.Instance);
            Assert.False(list.IsFrozen);
            list.Freeze();
            Assert.True(list.IsFrozen);
            Assert.Throws <InvalidOperationException>(() => list.Add(EmptyData.Instance));
        }
예제 #10
0
        public static StreamList GetStreamList()
        {
            var streamList = new StreamList
            {
                StreamListItems = new List <StreamListItem>()
                {
                    GetRandomItem(rndStreamSource),
                    GetRandomItem(rndStreamSource)
                }
            };

            return(streamList);
        }
예제 #11
0
        private void parseChunkedBody()
        {
            if (contentData.Length == 0)
            {
                // wait for some data
                return;
            }

            var seg = new StreamSegment(contentData);

            while (seg.Length > 0)
            {
                ChunkedDecoder.DecodeOneInfo chunkInfo;
                try
                {
                    chunkInfo = ChunkedDecoder.DecodeOneChunk(seg);
                }
                catch (PartialChunkException)
                {
                    // wait for more data
                    contentData = new StreamList();
                    if (seg.Length > 0)
                    {
                        contentData.Add(new ByteArray(seg));
                    }
                    return;
                }
                catch
                {
                    throw new HttpInvalidMessageException();
                }
                // finished
                if (chunkInfo.DataLength == 0)
                {
                    seg         = new StreamSegment(seg, chunkInfo.ChunkLength);
                    contentData = new StreamList();
                    contentData.Add(new ByteArray(seg));
                    state = ParsingState.CheckingChunedTrailer;
                    return;
                }
                else
                {
                    dechunkedLength += chunkInfo.DataLength;
                    seg              = new StreamSegment(contentData, seg.Offset + chunkInfo.ChunkLength, seg.Length - chunkInfo.ChunkLength);
                }
            }
            contentData = new StreamList();
            return;
        }
예제 #12
0
        public void TestStreamList()
        {
            var list = new StreamList();

            Assert.Equal(0, list.Length);
            var stream = new ByteArray(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });

            list.Add(stream);
            Assert.Equal(10, list.Length);
            list.Add(stream);
            Assert.Equal(20, list.Length);
            list.Add(EmptyData.Instance);
            Assert.Equal(20, list.Length);
            list.Add(new ByteArray(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }));
            Assert.Equal(31, list.Length);
            Assert.Equal(1, list.ReadByte(0));
            Assert.Equal(1, list.ReadByte(10));
            Assert.Equal(2, list.ReadByte(11));
            Assert.Equal(11, list.ReadByte(30));
            var buffer = new byte[50];

            buffer[1]  = 99;
            buffer[2]  = 99;
            buffer[3]  = 99;
            buffer[13] = 99;
            list.ReadBytesToBuffer(buffer, 5, 0, 2);
            Assert.Equal(99, buffer[1]);
            Assert.Equal(99, buffer[2]);
            list.ReadBytesToBuffer(buffer, 5, 1, 2);
            Assert.Equal(6, buffer[2]);
            Assert.Equal(99, buffer[3]);
            list.ReadBytesToBuffer(buffer, 9, 10, 3);
            Assert.Equal(10, buffer[3]);
            Assert.Equal(4, buffer[7]);
            Assert.Equal(5, buffer[8]);
            Assert.Equal(9, buffer[12]);
            Assert.Equal(99, buffer[13]);
            // test read-all for possible off-by-one errors
            list.ReadBytesToBuffer(buffer);
            // test start > contentData.streams[0].length
            list.ReadBytesToBuffer(buffer, 16, 5);
            Assert.Equal(7, buffer[0]);
        }
예제 #13
0
        private void init()
        {
            tmpData = new StreamList();
            var chunks = innerStream.Length / chunkSize;

            if (chunks > 0)
            {
                tmpData.Add(new RegularyChunkedStream(innerStream, chunkSize, chunks));
            }
            var lastChunkLength = (int)(innerStream.Length % chunkSize);

            if (lastChunkLength > 0)
            {
                tmpData.Add(createChunkStart(lastChunkLength));
                tmpData.Add(new StreamSegment(innerStream, chunkSize * (innerStream.Length / chunkSize)));
                tmpData.Add(chunkEnd);
            }
            tmpData.Add(streamEnd);
            tmpData.Freeze();
        }
예제 #14
0
        /// <summary>
        /// 直播流列表
        /// </summary>
        /// <param name="prefix">直播流名称前缀</param>
        /// <param name="living">是否正在直播中</param>
        /// <param name="count">取几条记录</param>
        /// <returns></returns>
        public pili_sdk.pili.StreamList StreamList(string prefix, bool?living, long count)
        {
            string marker      = null;   // optional
            long   limit       = count;  // optional
            string titlePrefix = prefix; // optional

            try
            {
                StreamList     streamList = Pili.API <IStream>().List(marker, limit, titlePrefix, living);
                IList <Stream> list       = streamList.Streams;
                foreach (Stream s in list)
                {
                    // access the stream
                }
                return(streamList);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        async Task LoadDropDownData()
        {
            List <string> liYeaNo = new List <string>();

            liYeaNo.Add("Yes");
            liYeaNo.Add("No");

            DomicileUksList          = liYeaNo;
            FreedomFightersList      = liYeaNo;
            DefencePersonalList      = liYeaNo;
            PhysicallyChallengesList = liYeaNo;
            PunishedByCourtList      = liYeaNo;
            DabarredCollegeList      = liYeaNo;
            EWS = liYeaNo;

            ExamCenterList.Add("Almora");
            ExamCenterList.Add("Bageshwar");
            ExamCenterList.Add("Haldwani");
            ExamCenterList.Add("Kashipur");
            ExamCenterList.Add("Nainital");
            ExamCenterList.Add("Pithoragarh");
            ExamCenterList.Add("Ram Nagar");
            ExamCenterList.Add("Rudrapur");
            ExamCenterList.Add("Ranikhet");
            ExamCenterList.Add("Khatima");
            ExamCenterList.Add("Dwarahat");
            ExamCenterList.Add("Lohaghat");
            ExamCenterList.Add("Kichha");
            ExamCenterList.Add("Berinag");

            GroupList.Add("Arts");
            GroupList.Add("Commerce");
            GroupList.Add("Science");

            MaritalStatusList.Add("Single");
            MaritalStatusList.Add("Married");

            NationalityList.Add("Indian");
            NationalityList.Add("Others");

            CategoryList.Add("Unreserved General");
            CategoryList.Add("Schedule Cast (SC)");
            CategoryList.Add("Schedule Tribe (ST)");
            CategoryList.Add("Other Backward Class (OBC) - Creamy");
            CategoryList.Add("Other Backward Class (OBC) - Non Creamy");

            PhysicallyChallengesTypeList.Add("Physically Challenged");
            PhysicallyChallengesTypeList.Add("Visually Challenged");
            PhysicallyChallengesTypeList.Add("None");

            GendersList.Add("Male");
            GendersList.Add("Female");
            GendersList.Add("Transgender");

            StreamList.Add("Humanities/Arts");
            StreamList.Add("Commerce");
            StreamList.Add("Science");

            CoursesList.Add("Bachelor of Education");
            CoursesList.Add("Master of Education");

            PassingYearList.Add("Appearing");
            PassingYearList.Add("2020");
            PassingYearList.Add("2019");
            PassingYearList.Add("2018");
            PassingYearList.Add("2017");
            PassingYearList.Add("2016");
            PassingYearList.Add("2015");
            PassingYearList.Add("2014");
            PassingYearList.Add("2013");
            PassingYearList.Add("2012");
            PassingYearList.Add("2011");
            PassingYearList.Add("2010");

            M_EdGraducationRequired.Add("B.Ed. Theory");
            M_EdGraducationRequired.Add("B.T. Theory");
            M_EdGraducationRequired.Add("L.T. Theory");
            M_EdGraducationRequired.Add("B.EI.Ed. Theory");
            M_EdGraducationRequired.Add("D.EI.Ed. Theory");
            M_EdGraducationRequired.Add("B.A B.Ed. Theory");
            M_EdGraducationRequired.Add("B.Sc. B.Ed. Theory");

            var response = await _httpClient.GetAsync("https://api.covidindiatracker.com/state_data.json");

            if (response.IsSuccessStatusCode)
            {
                var result =
                    Newtonsoft.Json.JsonConvert.DeserializeObject <IEnumerable <StateData> >(
                        await response.Content.ReadAsStringAsync());
                foreach (var state in result)
                {
                    StateList.Add(state.state);
                }
            }
        }
예제 #16
0
 public HttpData Receive(IDataStream s)
 {
     lock (contentLock)
     {
         if (useContentData)
         {
             contentData.Add(s);
         }
         dataBuilder.Append(s);
         if (state == ParsingState.Header)
         {
             try
             {
                 if (parser.Parse(contentData, isResponse))
                 {
                     state = ParsingState.Body;
                     try
                     {
                         var code = parser.StatusCode;
                         // header parsing is finished
                         if (LastRequestMethod == HttpRequestMethod.HEAD)
                         {
                             info = new HttpBodyLengthInfo((long)0);
                         }
                         else if (LastRequestMethod == HttpRequestMethod.CONNECT && code > 199 && code < 300)
                         {
                             info = new HttpBodyLengthInfo((long)0);
                         }
                         else
                         {
                             info = parser.GetBodyLengthInfo(!isResponse);
                         }
                         useContentData = info.Type == HttpBodyLengthInfo.LengthType.Chunked;
                         headerLength   = parser.HeaderLength;
                         if (contentData.Length - parser.HeaderLength > 0)
                         {
                             var tmpList      = new StreamList();
                             var contentStart = new ByteArray(contentData, parser.HeaderLength);
                             tmpList.Add(contentStart);
                             contentData = tmpList;
                         }
                         else
                         {
                             contentData = new StreamList();
                         }
                     }
                     catch (BadRequestException)
                     {
                         throw new HttpInvalidMessageException();
                     }
                 }
             }
             catch (HttpHeaderParserException)
             {
                 throw new HttpInvalidMessageException();
             }
         }
         if (state == ParsingState.Body)
         {
             if (info.Type == HttpBodyLengthInfo.LengthType.Exact && info.Length <= dataBuilder.Length - headerLength)
             {
                 var resStream = dataBuilder.Close();
                 return(parser.Create(new StreamSegment(resStream, 0, headerLength), new StreamSegment(resStream, headerLength, info.Length), resStream));
             }
             else if (info.Type == HttpBodyLengthInfo.LengthType.Chunked)
             {
                 parseChunkedBody();
             }
         }
     }
     if (state == ParsingState.CheckingChunedTrailer)
     {
         if (contentData.Length >= 2)
         {
             // check CRLF
             bool chunkedEnd = contentData.ReadByte(0) == 13 && contentData.ReadByte(1) == 10;
             if (chunkedEnd)
             {
                 contentData = new StreamList();
                 var resStream = dataBuilder.Close();
                 return(parser.Create(new StreamSegment(resStream, 0, headerLength), new StreamSegment(resStream, headerLength), resStream));
             }
             else
             {
                 parser.ParseChunkedTrailer();
                 state = ParsingState.ParsingChunkedTrailer;
             }
         }
     }
     if (state == ParsingState.ParsingChunkedTrailer)
     {
         if (parser.Parse(contentData, isResponse))
         {
             contentData = new StreamList();
             var resStream = dataBuilder.Close();
             return(parser.Create(new StreamSegment(resStream, 0, headerLength), new StreamSegment(resStream, headerLength), resStream));
         }
     }
     return(null);
 }
예제 #17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="fin"></param>
        /// <param name="opcode"></param>
        /// <param name="maskingKey">either null which will set MASK bit to 0, or byte array of 4 items which will set MASK to 1</param>
        /// <param name="payload">unmasked data</param>
        /// <param name="rsv1"></param>
        /// <param name="rsv2"></param>
        /// <param name="rsv3"></param>
        public WebSocketMessage(bool fin, OpcodeType opcode, byte[] maskingKey, IDataStream payload, bool rsv1 = false, bool rsv2 = false, bool rsv3 = false)
        {
            if (MaskingKey != null && MaskingKey.Length != 4)
            {
                throw new ArgumentException("MaskingKey.Length != 4");
            }
            if (payload == null)
            {
                payload = EmptyData.Instance;
            }
            MaskingKey    = maskingKey;
            FIN           = fin;
            RSV1          = rsv1;
            RSV2          = rsv2;
            RSV3          = rsv3;
            Opcode        = opcode;
            MASK          = MaskingKey != null;
            PayloadLength = payload.Length;
            InnerData     = payload;
            var buffer = new byte[calculateHeaderLength()];

            buffer[0] = (byte)((FIN ? 128 : 0) + (RSV1 ? 64 : 0) + (RSV2 ? 32 : 0) + (RSV3 ? 16 : 0) + ((byte)Opcode));
            int i = 2;

            if (PayloadLength > 125)
            {
                if (PayloadLength <= UInt16.MaxValue)
                {
                    buffer[1] = 126;
                    var bytes = BitConverter.GetBytes((UInt16)PayloadLength);
                    if (BitConverter.IsLittleEndian)
                    {
                        byte b0 = bytes[0];
                        bytes[0] = bytes[1];
                        bytes[1] = b0;
                    }
                    buffer[2] = bytes[0];
                    buffer[3] = bytes[1];
                    i         = 4;
                }
                else
                {
                    buffer[1] = 127;
                    var bytes = BitConverter.GetBytes((UInt64)PayloadLength);
                    if (BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(bytes);
                    }
                    Array.Copy(bytes, 0, buffer, 2, 8);
                    i = 10;
                }
            }
            else
            {
                buffer[1] = (byte)PayloadLength;
            }
            buffer[1] += (byte)(MASK ? 128 : 0);
            if (MASK)
            {
                Array.Copy(MaskingKey, 0, buffer, i, 4);
            }
            var header = new ByteArray(buffer);

            if (MASK)
            {
                payload = new MaskedStream(maskingKey, payload);
            }
            var res = new StreamList();

            res.Add(header);
            res.Add(payload);
            if (PayloadLength < 4096)
            {
                binaryStream = new ByteArray(res);
            }
            else
            {
                binaryStream = res;
            }
        }
예제 #18
0
        public MainModule(OpenTokService opentokService)
        {
            Get["/"] = _ => View["index"];

            Get["/host"] = _ =>
            {
                dynamic locals = new ExpandoObject();

                locals.ApiKey             = opentokService.OpenTok.ApiKey.ToString();
                locals.SessionId          = opentokService.Session.Id;
                locals.Token              = opentokService.Session.GenerateToken(Role.PUBLISHER, 0, null, new List <string> (new string[] { "focus" }));
                locals.InitialBroadcastId = opentokService.broadcastId;
                locals.FocusStreamId      = opentokService.focusStreamId;
                locals.InitialLayout      = OpenTokUtils.convertToCamelCase(opentokService.layout.ToString());

                return(View["host", locals]);
            };

            Get["/participant"] = _ =>
            {
                dynamic locals = new ExpandoObject();

                locals.ApiKey        = opentokService.OpenTok.ApiKey.ToString();
                locals.SessionId     = opentokService.Session.Id;
                locals.Token         = opentokService.Session.GenerateToken();
                locals.FocusStreamId = opentokService.focusStreamId;
                locals.Layout        = OpenTokUtils.convertToCamelCase(opentokService.layout.ToString());

                return(View["participant", locals]);
            };

            Post["/start"] = _ =>
            {
                bool            horizontal  = Request.Form["layout"] == "horizontalPresentation";
                BroadcastLayout layoutType  = new BroadcastLayout(horizontal ? BroadcastLayout.LayoutType.HorizontalPresentation : BroadcastLayout.LayoutType.VerticalPresentation);
                int             maxDuration = 7200;
                if (Request.Form["maxDuration"] != null)
                {
                    maxDuration = int.Parse(Request.Form["maxDuration"]);
                }
                Broadcast broadcast = opentokService.OpenTok.StartBroadcast(
                    opentokService.Session.Id,
                    hls: true,
                    rtmpList: null,
                    resolution: Request.Form["resolution"],
                    maxDuration: maxDuration,
                    layout: layoutType
                    );
                opentokService.broadcastId = broadcast.Id.ToString();
                return(broadcast);
            };

            Get["/stop/{id}"] = parameters =>
            {
                Broadcast broadcast = opentokService.OpenTok.StopBroadcast(parameters.id);
                opentokService.broadcastId = "";
                return(broadcast);
            };

            Get["/broadcast"] = _ =>
            {
                if (!String.IsNullOrEmpty(opentokService.broadcastId))
                {
                    try
                    {
                        Broadcast broadcast = opentokService.OpenTok.GetBroadcast(opentokService.broadcastId);
                        if (broadcast.Status == Broadcast.BroadcastStatus.STARTED)
                        {
                            return(Response.AsRedirect(broadcast.Hls));
                        }
                        else
                        {
                            return(Response.AsText("Broadcast not in progress."));
                        }
                    }
                    catch (Exception ex)
                    {
                        return(Response.AsText("Could not get broadcast " + opentokService.broadcastId + ". Exception Message: " + ex.Message));
                    }
                }
                else
                {
                    return(Response.AsText("There's no broadcast running right now."));
                }
            };

            Get["/broadcast/{id}/layout/{layout}"] = parameters =>
            {
                bool            horizontal = parameters.layout == "horizontalPresentation";
                BroadcastLayout layout     = new BroadcastLayout(horizontal ? BroadcastLayout.LayoutType.HorizontalPresentation : BroadcastLayout.LayoutType.VerticalPresentation);
                opentokService.OpenTok.SetBroadcastLayout(parameters.id, layout);
                return(HttpStatusCode.OK);
            };

            Post["/focus"] = _ =>
            {
                string focusStreamId = Request.Form["focus"];
                opentokService.focusStreamId = focusStreamId;
                StreamList streamList = opentokService.OpenTok.ListStreams(opentokService.Session.Id);
                List <StreamProperties> streamPropertiesList = new List <StreamProperties>();
                foreach (Stream stream in streamList)
                {
                    StreamProperties streamProperties = new StreamProperties(stream.Id, null);
                    if (focusStreamId.Equals(stream.Id))
                    {
                        streamProperties.addLayoutClass("focus");
                    }
                    streamPropertiesList.Add(streamProperties);
                }
                opentokService.OpenTok.SetStreamClassLists(opentokService.Session.Id, streamPropertiesList);
                return(HttpStatusCode.OK);
            };
        }