aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs')
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs37
1 files changed, 27 insertions, 10 deletions
diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs
index 312e718e1..1ff199eb4 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs
@@ -1,4 +1,5 @@
-using ServiceStack.Web;
+using System.Threading;
+using ServiceStack.Web;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -64,7 +65,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
{
throw new ArgumentNullException("contentType");
}
-
+
RangeHeader = rangeHeader;
SourceStream = source;
IsHeadRequest = isHeadRequest;
@@ -98,11 +99,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
RangeStart = requestedRange.Key;
RangeLength = 1 + RangeEnd - RangeStart;
-
+
// Content-Length is the length of what we're serving, not the original content
Options["Content-Length"] = RangeLength.ToString(UsCulture);
Options["Content-Range"] = string.Format("bytes {0}-{1}/{2}", RangeStart, RangeEnd, TotalContentLength);
-
+
if (RangeStart > 0)
{
SourceStream.Position = RangeStart;
@@ -179,17 +180,33 @@ namespace MediaBrowser.Server.Implementations.HttpServer
using (var source = SourceStream)
{
// If the requested range is "0-", we can optimize by just doing a stream copy
- if (RangeEnd == TotalContentLength - 1)
+ if (RangeEnd >= TotalContentLength - 1)
{
await source.CopyToAsync(responseStream).ConfigureAwait(false);
}
else
{
- // Read the bytes we need
- var buffer = new byte[Convert.ToInt32(RangeLength)];
- await source.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
+ await CopyToAsyncInternal(source, responseStream, Convert.ToInt32(RangeLength), CancellationToken.None).ConfigureAwait(false);
+ }
+ }
+ }
- await responseStream.WriteAsync(buffer, 0, Convert.ToInt32(RangeLength)).ConfigureAwait(false);
+ private async Task CopyToAsyncInternal(Stream source, Stream destination, int copyLength, CancellationToken cancellationToken)
+ {
+ const int bufferSize = 81920;
+ var array = new byte[bufferSize];
+ int count;
+ while ((count = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0)
+ {
+ var bytesToCopy = Math.Min(count, copyLength);
+
+ await destination.WriteAsync(array, 0, bytesToCopy, cancellationToken).ConfigureAwait(false);
+
+ copyLength -= bytesToCopy;
+
+ if (copyLength <= 0)
+ {
+ break;
}
}
}
@@ -212,4 +229,4 @@ namespace MediaBrowser.Server.Implementations.HttpServer
public string StatusDescription { get; set; }
}
-}
+} \ No newline at end of file