Created
November 9, 2018 10:24
-
-
Save SlyNet/d3fe78140d91165f351110e6ab1ae4df to your computer and use it in GitHub Desktop.
Progressive download response message for asp.net webapi that supports video streaming and partial download and not broken
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ProgressiveDownload | |
{ | |
private readonly HttpRequestMessage request; | |
public ProgressiveDownload(HttpRequestMessage request) | |
{ | |
this.request = request; | |
} | |
public HttpResponseMessage HeaderInfoMessage(long contentLength, string mediaType) | |
{ | |
var response = this.request.CreateResponse(); | |
response.Content = new ByteArrayContent(Array.Empty<byte>()); | |
response.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(mediaType); | |
response.Content.Headers.ContentLength = contentLength; | |
response.Headers.AcceptRanges.Add("bytes"); | |
return response; | |
} | |
public HttpResponseMessage ResultMessage(Stream stream, string mediaType) | |
{ | |
var rangeHeader = this.request.Headers.Range?.Ranges.FirstOrDefault(); | |
if (rangeHeader != null) | |
{ | |
var byteRange = new ByteRangeStreamContent(stream, this.request.Headers.Range, mediaType); | |
var partialResponse = this.request.CreateResponse(HttpStatusCode.PartialContent); | |
partialResponse.Content = new PushStreamContent((outputStream, content, context) => | |
{ | |
try | |
{ | |
stream.Seek(rangeHeader.From ?? 0, SeekOrigin.Begin); | |
long bufferSize = 32 * 1024; | |
byte[] buffer = new byte[bufferSize]; | |
while (true) | |
{ | |
if (rangeHeader.To != null) | |
{ | |
bufferSize = Math.Min(bufferSize, rangeHeader.To.Value - stream.Position); | |
} | |
int count = stream.Read(buffer, 0, (int) bufferSize); | |
if (count != 0) | |
outputStream.Write(buffer, 0, count); | |
else | |
break; | |
} | |
} | |
catch (HttpException) | |
{ | |
} | |
finally | |
{ | |
outputStream.Close(); | |
} | |
}); | |
partialResponse.Content.Headers.ContentType = byteRange.Headers.ContentType; | |
partialResponse.Content.Headers.ContentLength = byteRange.Headers.ContentLength; | |
partialResponse.Content.Headers.ContentRange = byteRange.Headers.ContentRange; | |
return partialResponse; | |
} | |
var nonPartialResponse = this.request.CreateResponse(HttpStatusCode.OK); | |
nonPartialResponse.Content = new StreamContent(stream); | |
nonPartialResponse.Content.Headers.ContentType = new MediaTypeHeaderValue(mediaType); | |
return nonPartialResponse; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment