Exemple #1
0
        async Task HandleMediaPlayerContextAsync(HttpListenerContext context, CancellationToken token)
        {
            long firstByte = 0;
            long lastByte  = Stream.Length - 1;

            var range = context.Request.Headers["Range"];

            if (range != null && range.StartsWith("bytes="))
            {
                Debug.WriteLine(string.Format("Client requested: {0}", range));
                var parts = range.Substring("bytes=".Length).Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length == 1)
                {
                    firstByte = long.Parse(parts[0]);
                }
                else if (parts.Length == 2)
                {
                    firstByte = long.Parse(parts[0]);
                    lastByte  = long.Parse(parts[1]); // The range is inclusive, so we should add '1' to this offset so we send the last byte.
                }
            }

            // Clamp the last byte in case someone's player is over-reading. UWP likes to overread because it's terrible.
            if (lastByte > Stream.Length - 1)
            {
                lastByte = Stream.Length - 1;
            }

            // Some HTTP magic
            var buffer = new byte[64 * 1024];

            context.Response.SendChunked = true;
            context.Response.AppendHeader("Content-Range", $"bytes {firstByte}-{lastByte}");
            context.Response.StatusCode      = (int)HttpStatusCode.PartialContent;
            context.Response.ContentLength64 = lastByte - firstByte + 1;
            Debug.WriteLine($"Requested {firstByte} -> {lastByte}. Length: {context.Response.ContentLength64}");
            while (firstByte <= lastByte)
            {
                // Read the data and stream it back to the media player.
                try {
                    await ReadLocker.WaitAsync();

                    token.ThrowIfCancellationRequested();
                    if (Stream.Position != firstByte)
                    {
                        Stream.Seek(firstByte, SeekOrigin.Begin);
                    }
                    var read = await Stream.ReadAsync(buffer, 0, (int)Math.Min(lastByte - firstByte + 1, buffer.Length), token);

                    await context.Response.OutputStream.WriteAsync(buffer, 0, read, token);

                    await context.Response.OutputStream.FlushAsync(token);

                    firstByte += read;
                } finally {
                    ReadLocker.Release();
                }
            }
            Debug.WriteLine("Successfully transferred {0} -> {1}. Length: {2}", firstByte, lastByte, context.Response.ContentLength64);
        }
Exemple #2
0
 private void LogLockCallback(IEnumerable collection, object context, Action accessMethod, bool writeAccess)
 {
     if (writeAccess)
     {
         using (WriteLocker locker = new WriteLocker(_logListLocker))
         {
             accessMethod?.Invoke();
         }
     }
     else
     {
         using (ReadLocker locker = new ReadLocker(_logListLocker))
         {
             accessMethod?.Invoke();
         }
     }
 }
Exemple #3
0
                public static ReadLocker FromBaseObject(BaseObject baseObj)
                {
                    if (baseObj == null || baseObj.NativeObject == IntPtr.Zero)
                    {
                        return(null);
                    }
                    ReadLocker obj = baseObj as  ReadLocker;

                    if (object.Equals(obj, null))
                    {
                        obj = new ReadLocker(CreatedWhenConstruct.CWC_NotToCreate);
                        obj.BindNativeObject(baseObj.NativeObject, "CReadLocker");
                        obj.IncreaseCast();
                    }

                    return(obj);
                }
Exemple #4
0
        async Task HandleMediaPlayerContextAsync(HttpListenerContext context, CancellationToken token)
        {
            long firstByte = 0;
            long lastByte  = Stream.Length - 1;

            var range = context.Request.Headers["Range"];

            if (range != null && range.StartsWith("bytes="))
            {
                Debug.WriteLine(string.Format("Client requested: {0}", range));
                var parts = range.Substring("bytes=".Length).Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length == 1)
                {
                    firstByte = long.Parse(parts[0]);
                }
                else if (parts.Length == 2)
                {
                    firstByte = long.Parse(parts[0]);
                    lastByte  = long.Parse(parts[1]); // The range is inclusive, so we should add '1' to this offset so we send the last byte.
                }
            }

            // Clamp the last byte in case someone's player is over-reading. UWP likes to overread because it's terrible.
            if (lastByte > Stream.Length - 1)
            {
                lastByte = Stream.Length - 1;
            }

            // Some HTTP magic
            var buffer = new byte[64 * 1024];

            context.Response.SendChunked = true;
            context.Response.AppendHeader("Content-Range", $"bytes {firstByte}-{lastByte}");

            //--- CORS Policy Declined goes away. A lot of SocketExceptions and MonoTorrent.Tracker Exceptions happen. When reverting to original Pre-release 132 Nupackage. No exceptions thrown.
            //--- HTML5 Player uses HLS.JS and does something, enables play button. When going to Url obtained from CreateHttpStreamAsync, Download Failed - No File.
            //--- NodeJS Express Server CORS enabled is: 127.0.0.1:8888
            context.Response.AppendHeader("Access-Control-Allow-Origin", "*");  //-- should allow CORS from another domain.
            context.Response.AppendHeader("Access-Control-Allow-Headers", "Content-Type,x-requested-with");
            context.Response.AppendHeader("Access-Control-Allow-Methods", "GET,POST,PUT,HEAD,DELETE,OPTIONS");

            context.Response.StatusCode      = (int)HttpStatusCode.PartialContent;
            context.Response.ContentLength64 = lastByte - firstByte + 1;
            Debug.WriteLine($"Requested {firstByte} -> {lastByte}. Length: {context.Response.ContentLength64}");
            while (firstByte <= lastByte)
            {
                // Read the data and stream it back to the media player.
                try {
                    await ReadLocker.WaitAsync();

                    token.ThrowIfCancellationRequested();
                    if (Stream.Position != firstByte)
                    {
                        Stream.Seek(firstByte, SeekOrigin.Begin);
                    }
                    var read = await Stream.ReadAsync(buffer, 0, (int)Math.Min(lastByte - firstByte + 1, buffer.Length), token);

                    await context.Response.OutputStream.WriteAsync(buffer, 0, read, token);

                    await context.Response.OutputStream.FlushAsync(token);

                    firstByte += read;
                } finally {
                    ReadLocker.Release();
                }
            }
            Debug.WriteLine("Successfully transferred {0} -> {1}. Length: {2}", firstByte, lastByte, context.Response.ContentLength64);
        }
Exemple #5
0
                public BaseObject Create()
                {
                    ReadLocker emptyInstance = new ReadLocker(CreatedWhenConstruct.CWC_NotToCreate);

                    return(emptyInstance);
                }
Exemple #6
0
 public RwLocker()
 {
     _ReadLocker    = new ReadLocker(_Locker);
     _WriteLocker   = new WriteLocker(_Locker);
     _UpgradeLocker = new UpgradeLocker(_Locker);
 }