Пример #1
0
 private static IEnumerable <Tuple <long, long> > CreateByteRanges(string rangeString, int size)
 {
     return(RangeHeader.Parse(new Dictionary <string, string[]>(StringComparer.OrdinalIgnoreCase)
     {
         { "Range", new[] { rangeString } }
     }, size));
 }
Пример #2
0
        public void OverlapDescendingTest()
        {
            var range      = RangeHeader.Parse("bytes=300-599,0-499");
            var rangeItems = range.Normalize(10000);

            Assert.Collection(
                rangeItems,
                rangeItem =>
            {
                Assert.Equal(0, rangeItem.From);
                Assert.Equal(599, rangeItem.To);
            });
        }
Пример #3
0
        public void FromToTest()
        {
            var range      = RangeHeader.Parse("bytes=0-499");
            var rangeItems = range.Normalize(10000);

            Assert.Collection(
                rangeItems,
                rangeItem =>
            {
                Assert.Equal(0, rangeItem.From);
                Assert.Equal(499, rangeItem.To);
            });
        }
Пример #4
0
        public void OverlapWithFromTest()
        {
            var range      = RangeHeader.Parse("bytes=4000-5999,5000-");
            var rangeItems = range.Normalize(10000);

            Assert.Collection(
                rangeItems,
                rangeItem =>
            {
                Assert.Equal(4000, rangeItem.From);
                Assert.Equal(9999, rangeItem.To);
            });
        }
Пример #5
0
        private Task Serve(IDictionary <string, object> env)
        {
            Request  request  = new Request(env);
            Response response = new Response(env);

            var fileInfo = new FileInfo(path);
            var size     = fileInfo.Length;

            if (!RangeHeader.IsValid(request.Headers))
            {
                response.StatusCode = OK;
                range = new Tuple <long, long>(0, size - 1);
            }
            else
            {
                var ranges = RangeHeader.Parse(request.Headers, size);

                if (ranges == null)
                {
                    // Unsatisfiable.  Return error and file size.
                    return(Fail(
                               RequestedRangeNotSatisfiable,
                               "Byte range unsatisfiable",
                               "Content-Range", "bytes */" + size)
                           .Invoke(env));
                }

                if (ranges.Count() > 1)
                {
                    // TODO: Support multiple byte ranges.
                    response.StatusCode = OK;
                    range = new Tuple <long, long>(0, size - 1);
                }
                else
                {
                    // Partial content
                    range = ranges.First();
                    response.StatusCode = PartialContent;
                    response.Headers.SetHeader("Content-Range", "bytes " + range.Item1 + "-" + range.Item2 + "/" + size);
                    size = range.Item2 - range.Item1 + 1;
                }
            }

            response.Headers
            .SetHeader("Last-Modified", fileInfo.LastWriteTimeUtc.ToHttpDateString())
            .SetHeader("Content-Type", Mime.MimeType(fileInfo.Extension, "text/plain"))
            .SetHeader("Content-Length", size.ToString(CultureInfo.InvariantCulture));

            return(new FileBody(path, range).Start(response.OutputStream));
        }
Пример #6
0
        private Task Serve(IDictionary <string, object> env, string path)
        {
            Request  request  = new Request(env);
            Response response = new Response(env);

            var fileInfo = new FileInfo(path);
            var size     = fileInfo.Length;
            Tuple <long, long> range;

            if (!RangeHeader.IsValid(request.Headers))
            {
                response.StatusCode = OK;
                range = new Tuple <long, long>(0, size - 1);
            }
            else
            {
                var ranges = RangeHeader.Parse(request.Headers, size);

                if (ranges == null)
                {
                    // Unsatisfiable.  Return error and file size.
                    return(Fail(
                               RequestedRangeNotSatisfiable,
                               "Byte range unsatisfiable",
                               "Content-Range", "bytes */" + size)
                           .Invoke(env));
                }

                if (ranges.Count() > 1)
                {
                    // TODO: Support multiple byte ranges.
                    response.StatusCode = OK;
                    range = new Tuple <long, long>(0, size - 1);
                }
                else
                {
                    // Partial content
                    range = ranges.First();
                    response.StatusCode = PartialContent;
                    response.Headers.SetHeader("Content-Range", "bytes " + range.Item1 + "-" + range.Item2 + "/" + size);
                    size = range.Item2 - range.Item1 + 1;
                }
            }

            response.Headers
            .SetHeader("Last-Modified", fileInfo.LastWriteTimeUtc.ToHttpDateString())
            .SetHeader("Content-Type", Mime.MimeType(fileInfo.Extension, "text/plain"))
            .SetHeader("Content-Length", size.ToString(CultureInfo.InvariantCulture));

            if ("HEAD".Equals(request.Method, StringComparison.OrdinalIgnoreCase))
            {
                // Suppress the body.
                return(TaskHelpers.Completed());
            }

            FileBody body = new FileBody(path, range);

            //TODO: update for current send file spec
            //var req = new Request(env);
            //SendFileFunc sendFile = env.Get<SendFileFunc>("sendfile.Func");
            //if (sendFile != null)
            //{
            //    return body.Start(sendFile);
            //}

            return(body.Start(response.OutputStream));
        }