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;
        }
Esempio n. 3
0
        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));
        }
Esempio n. 5
0
 public static string GenerateRangeHeaderValue(
     this StaticRangeRequest range,
     long length)
 => $"bytes {range.From.Str()}-{range.To.Str()}/{length.Str()}";
Esempio n. 6
0
 public static string GenerateRangeHeaderKeyAndValue(
     this StaticRangeRequest rangeRequest,
     long length)
 {
     return($"{HttpKeys.ContentRange}: {GenerateRangeHeaderValue(rangeRequest, length)}");
 }