private static IEnumerable <Tuple <long, long> > CreateByteRanges(string rangeString, int size) { return(RangeHeader.Parse(new Dictionary <string, string[]>(StringComparer.OrdinalIgnoreCase) { { "Range", new[] { rangeString } } }, size)); }
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); }); }
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); }); }
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); }); }
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)); }
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)); }