public static StaticRangeRequest[] GetRequestedRanges( string rangeHeaderValue) { var matches = _pattern.Match(rangeHeaderValue); var result = new StaticRangeRequest[matches.Groups[1].Captures.Count]; if (false == matches.Success) { throw new ArgumentException(nameof(rangeHeaderValue)); } for (var i = 0; i < matches.Groups[1].Captures.Count; i++) { result[i] = GetRequestedRanges(matches, i); } return(result); }
static void TreatAsLastXBytes( StaticRangeRequest original, long contentLength, out long fromByte, out long toByte) { var numLastBytes = original.To; if (numLastBytes < 0) { throw new HttpBadRequestException(); } if (numLastBytes == 0) { throw new StaticRangeNotSatisfiableException( "Last number of bytes must be larger than 0" ); } fromByte = contentLength - numLastBytes; toByte = contentLength - 1; }
public static async Task WriteAsync( this IStaticFileServer inst, IHttpRequest request, StaticRangeRequest rangeRequest, IHttpResponse response, string pathToContentFile, int writeBufferSize) { Validation.RequireValidBufferSize(writeBufferSize); // Set headers response.Header[HttpKeys.ContentType] = inst.GetContentTypeHeader(pathToContentFile); // Open the file using (var fs = inst.OpenRead(pathToContentFile)) { // The requested range may contains relative values, // Convert them to absolute values here, as we knew the // content length rangeRequest = rangeRequest.ToAbsolute(fs.Length); // Set headers (cont) var contentLength = rangeRequest.To - rangeRequest.From + 1L; response.Header[HttpKeys.ContentLength] = contentLength.Str(); response.Header[HttpKeys.ContentRange] = rangeRequest.GenerateRangeHeaderValue(fs.Length); // Write body (for GET method only) if (request.Header.Method == HttpRequestMethod.GET) { fs.Position = rangeRequest.From; await fs.CopyToAsync( response.Body, count : contentLength, bufferSize : writeBufferSize); } } }
public static StaticRangeRequest ToAbsolute( this StaticRangeRequest original, long contentLength) { long fromByte; long toByte; if (contentLength < 0) { throw new ArgumentException(nameof(contentLength)); } if (original.From == long.MinValue && original.To == long.MinValue) { throw new HttpBadRequestException( "Must specify either 'from' or 'to' value of the range" ); } else if (original.From == long.MinValue) { TreatAsLastXBytes(original, contentLength, out fromByte, out toByte); } else if (original.To == long.MinValue) { fromByte = original.From; toByte = contentLength - 1; } else { fromByte = original.From; toByte = original.To; } Validate(fromByte, toByte, contentLength); return(new StaticRangeRequest(fromByte, toByte)); }
public static string GenerateRangeHeaderValue( this StaticRangeRequest range, long length) => $"bytes {range.From.Str()}-{range.To.Str()}/{length.Str()}";
public static string GenerateRangeHeaderKeyAndValue( this StaticRangeRequest rangeRequest, long length) { return($"{HttpKeys.ContentRange}: {GenerateRangeHeaderValue(rangeRequest, length)}"); }