public void ToString_UseDifferentRangeItems_AllSerializedCorrectly()
        {
            // Make sure ToString() doesn't add any separators.
            var rangeItem = new RangeItemHeaderValue(1000000000, 2000000000);
            Assert.Equal("1000000000-2000000000", rangeItem.ToString());

            rangeItem = new RangeItemHeaderValue(5, null);
            Assert.Equal("5-", rangeItem.ToString());

            rangeItem = new RangeItemHeaderValue(null, 10);
            Assert.Equal("-10", rangeItem.ToString());
        }
        public void GetHashCode_UseSameAndDifferentRangeItems_SameOrDifferentHashCodes()
        {
            var rangeItem1 = new RangeItemHeaderValue(1, 2);
            var rangeItem2 = new RangeItemHeaderValue(1, null);
            var rangeItem3 = new RangeItemHeaderValue(null, 2);
            var rangeItem4 = new RangeItemHeaderValue(2, 2);
            var rangeItem5 = new RangeItemHeaderValue(1, 2);

            Assert.NotEqual(rangeItem1.GetHashCode(), rangeItem2.GetHashCode());
            Assert.NotEqual(rangeItem1.GetHashCode(), rangeItem3.GetHashCode());
            Assert.NotEqual(rangeItem1.GetHashCode(), rangeItem4.GetHashCode());
            Assert.Equal(rangeItem1.GetHashCode(), rangeItem5.GetHashCode());
        }
        public void Equals_UseSameAndDifferentRanges_EqualOrNotEqualNoExceptions()
        {
            var rangeItem1 = new RangeItemHeaderValue(1, 2);
            var rangeItem2 = new RangeItemHeaderValue(1, null);
            var rangeItem3 = new RangeItemHeaderValue(null, 2);
            var rangeItem4 = new RangeItemHeaderValue(2, 2);
            var rangeItem5 = new RangeItemHeaderValue(1, 2);

            Assert.False(rangeItem1.Equals(rangeItem2), "1-2 vs. 1-.");
            Assert.False(rangeItem2.Equals(rangeItem1), "1- vs. 1-2.");
            Assert.False(rangeItem1.Equals(null), "1-2 vs. null.");
            Assert.False(rangeItem1.Equals(rangeItem3), "1-2 vs. -2.");
            Assert.False(rangeItem3.Equals(rangeItem1), "-2 vs. 1-2.");
            Assert.False(rangeItem1.Equals(rangeItem4), "1-2 vs. 2-2.");
            Assert.True(rangeItem1.Equals(rangeItem5), "1-2 vs. 1-2.");
        }
        internal static int GetRangeItemLength(string input, int startIndex, out RangeItemHeaderValue parsedValue)
        {
            Contract.Requires(startIndex >= 0);

            // This parser parses number ranges: e.g. '1-2', '1-', '-2'.

            parsedValue = null;

            if (string.IsNullOrEmpty(input) || (startIndex >= input.Length))
            {
                return 0;
            }

            // Caller must remove leading whitespaces. If not, we'll return 0.
            var current = startIndex;

            // Try parse the first value of a value pair.
            var fromStartIndex = current;
            var fromLength = HttpRuleParser.GetNumberLength(input, current, false);

            if (fromLength > HttpRuleParser.MaxInt64Digits)
            {
                return 0;
            }

            current = current + fromLength;
            current = current + HttpRuleParser.GetWhitespaceLength(input, current);

            // Afer the first value, the '-' character must follow.
            if ((current == input.Length) || (input[current] != '-'))
            {
                // We need a '-' character otherwise this can't be a valid range.
                return 0;
            }

            current++; // skip the '-' character
            current = current + HttpRuleParser.GetWhitespaceLength(input, current);

            var toStartIndex = current;
            var toLength = 0;

            // If we didn't reach the end of the string, try parse the second value of the range.
            if (current < input.Length)
            {
                toLength = HttpRuleParser.GetNumberLength(input, current, false);

                if (toLength > HttpRuleParser.MaxInt64Digits)
                {
                    return 0;
                }

                current = current + toLength;
                current = current + HttpRuleParser.GetWhitespaceLength(input, current);
            }

            if ((fromLength == 0) && (toLength == 0))
            {
                return 0; // At least one value must be provided in order to be a valid range.
            }

            // Try convert first value to int64
            long from = 0;
            if ((fromLength > 0) && !HeaderUtilities.TryParseInt64(input.Substring(fromStartIndex, fromLength), out from))
            {
                return 0;
            }

            // Try convert second value to int64
            long to = 0;
            if ((toLength > 0) && !HeaderUtilities.TryParseInt64(input.Substring(toStartIndex, toLength), out to))
            {
                return 0;
            }

            // 'from' must not be greater than 'to'
            if ((fromLength > 0) && (toLength > 0) && (from > to))
            {
                return 0;
            }

            parsedValue = new RangeItemHeaderValue((fromLength == 0 ? (long?)null : (long?)from),
                (toLength == 0 ? (long?)null : (long?)to));
            return current - startIndex;
        }
예제 #5
0
 // Note: This assumes ranges have been normalized to absolute byte offsets.
 private ContentRangeHeaderValue ComputeContentRange(RangeItemHeaderValue range, out long start, out long length)
 {
     start = range.From.Value;
     long end = range.To.Value;
     length = end - start + 1;
     return new ContentRangeHeaderValue(start, end, _length);
 }
예제 #6
0
        private async Task WriteDataToResponseBody(HttpResponse response, RangeItemHeaderValue rangeValue)
        {
            var startIndex = rangeValue.From ?? 0;
            var endIndex = rangeValue.To ?? 0;

            byte[] buffer = new byte[BufferSize];
            long totalToSend = endIndex - startIndex;
            int count = 0;

            long bytesRemaining = totalToSend + 1;
            response.ContentLength = bytesRemaining;

            FileStream.Seek(startIndex, SeekOrigin.Begin);

            while (bytesRemaining > 0)
            {
                try
                {
                    if (bytesRemaining <= buffer.Length)
                        count = FileStream.Read(buffer, 0, (int)bytesRemaining);
                    else
                        count = FileStream.Read(buffer, 0, buffer.Length);

                    if (count == 0)
                        return;

                    await response.Body.WriteAsync(buffer, 0, count);

                    bytesRemaining -= count;
                }
                catch (IndexOutOfRangeException)
                {
                    await response.Body.FlushAsync();
                    return;
                }
                finally
                {
                    await response.Body.FlushAsync();
                }
            }
        }
 public void Ctor_ValidFormat_SuccessfullyCreated()
 {
     var rangeItem = new RangeItemHeaderValue(1, 2);
     Assert.Equal(1, rangeItem.From);
     Assert.Equal(2, rangeItem.To);
 }
        internal static int GetRangeItemLength(StringSegment input, int startIndex, out RangeItemHeaderValue parsedValue)
        {
            Contract.Requires(startIndex >= 0);

            // This parser parses number ranges: e.g. '1-2', '1-', '-2'.

            parsedValue = null;

            if (StringSegment.IsNullOrEmpty(input) || (startIndex >= input.Length))
            {
                return(0);
            }

            // Caller must remove leading whitespaces. If not, we'll return 0.
            var current = startIndex;

            // Try parse the first value of a value pair.
            var fromStartIndex = current;
            var fromLength     = HttpRuleParser.GetNumberLength(input, current, false);

            if (fromLength > HttpRuleParser.MaxInt64Digits)
            {
                return(0);
            }

            current = current + fromLength;
            current = current + HttpRuleParser.GetWhitespaceLength(input, current);

            // Afer the first value, the '-' character must follow.
            if ((current == input.Length) || (input[current] != '-'))
            {
                // We need a '-' character otherwise this can't be a valid range.
                return(0);
            }

            current++; // skip the '-' character
            current = current + HttpRuleParser.GetWhitespaceLength(input, current);

            var toStartIndex = current;
            var toLength     = 0;

            // If we didn't reach the end of the string, try parse the second value of the range.
            if (current < input.Length)
            {
                toLength = HttpRuleParser.GetNumberLength(input, current, false);

                if (toLength > HttpRuleParser.MaxInt64Digits)
                {
                    return(0);
                }

                current = current + toLength;
                current = current + HttpRuleParser.GetWhitespaceLength(input, current);
            }

            if ((fromLength == 0) && (toLength == 0))
            {
                return(0); // At least one value must be provided in order to be a valid range.
            }

            // Try convert first value to int64
            long from = 0;

            if ((fromLength > 0) && !HeaderUtilities.TryParseNonNegativeInt64(input.Subsegment(fromStartIndex, fromLength), out from))
            {
                return(0);
            }

            // Try convert second value to int64
            long to = 0;

            if ((toLength > 0) && !HeaderUtilities.TryParseNonNegativeInt64(input.Subsegment(toStartIndex, toLength), out to))
            {
                return(0);
            }

            // 'from' must not be greater than 'to'
            if ((fromLength > 0) && (toLength > 0) && (from > to))
            {
                return(0);
            }

            parsedValue = new RangeItemHeaderValue((fromLength == 0 ? (long?)null : (long?)from),
                                                   (toLength == 0 ? (long?)null : (long?)to));
            return(current - startIndex);
        }