public ByteRangeStream(Stream innerStream, RangeItemHeaderValue range) : base(innerStream) { if (range == null) { throw new ArgumentNullException("range"); } if (!innerStream.CanSeek) { throw new ArgumentException(RS.Format(Resources.ByteRangeStreamNotSeekable, typeof(ByteRangeStream).Name), "innerStream"); } if (innerStream.Length < 1) { throw new ArgumentOutOfRangeException("innerStream", innerStream.Length, RS.Format(Resources.ByteRangeStreamEmpty, typeof(ByteRangeStream).Name)); } if (range.From.HasValue && range.From.Value > innerStream.Length) { throw new ArgumentOutOfRangeException("range", range.From, RS.Format(Resources.ByteRangeStreamInvalidFrom, innerStream.Length)); } // Ranges are inclusive so 0-9 means the first 10 bytes long maxLength = innerStream.Length - 1; long upperbounds; if (range.To.HasValue) { if (range.From.HasValue) { // e.g bytes=0-499 (the first 500 bytes offsets 0-499) upperbounds = Math.Min(range.To.Value, maxLength); _lowerbounds = range.From.Value; } else { // e.g bytes=-500 (the final 500 bytes) upperbounds = maxLength; _lowerbounds = Math.Max(innerStream.Length - range.To.Value, 0); } } else { if (range.From.HasValue) { // e.g bytes=500- (from byte offset 500 and up) upperbounds = maxLength; _lowerbounds = range.From.Value; } else { // e.g. bytes=- (invalid so will never get here) upperbounds = maxLength; _lowerbounds = 0; } } _totalCount = upperbounds - _lowerbounds + 1; ContentRange = new ContentRangeHeaderValue(_lowerbounds, upperbounds, innerStream.Length); }
private void Initialize(ContentRangeHeaderValue contentRange) { if (contentRange == null) { throw Error.ArgumentNull("contentRange"); } this.ContentRange = contentRange; }
private void Initialize(ContentRangeHeaderValue contentRange) { if (contentRange == null) { throw new ArgumentNullException("contentRange"); } ContentRange = contentRange; }
private ContentRangeHeaderValue(ContentRangeHeaderValue source) { Contract.Requires(source != null); this.from = source.from; this.to = source.to; this.length = source.length; this.unit = source.unit; }
private void CheckValidParsedValue(string input, int startIndex, ContentRangeHeaderValue expectedResult, int expectedIndex) { HttpHeaderParser parser = GenericHeaderParser.ContentRangeParser; object result = null; Assert.True(parser.TryParseValue(input, null, ref startIndex, out result), string.Format("TryParse returned false. Input: '{0}'", input)); Assert.Equal(expectedIndex, startIndex); Assert.Equal(expectedResult, result); }
public void Ctor_FromToAndLengthOverloadValidValues_ValuesCorrectlySet() { ContentRangeHeaderValue range = new ContentRangeHeaderValue(0, 1, 2); Assert.True(range.HasRange); Assert.True(range.HasLength); Assert.Equal("bytes", range.Unit); Assert.Equal(0, range.From); Assert.Equal(1, range.To); Assert.Equal(2, range.Length); }
public void Ctor_LengthOnlyOverloadValidValues_ValuesCorrectlySet() { ContentRangeHeaderValue range = new ContentRangeHeaderValue(5); Assert.False(range.HasRange); Assert.True(range.HasLength); Assert.Equal("bytes", range.Unit); Assert.Null(range.From); Assert.Null(range.To); Assert.Equal(5, range.Length); }
public void Unit_GetAndSetValidAndInvalidValues_MatchExpectation() { ContentRangeHeaderValue range = new ContentRangeHeaderValue(0); range.Unit = "myunit"; Assert.Equal("myunit", range.Unit); // "Unit (custom value)" Assert.Throws<ArgumentException>(() => { range.Unit = null; }); // "<null>" Assert.Throws<ArgumentException>(() => { range.Unit = ""; }); // "empty string" Assert.Throws<FormatException>(() => { range.Unit = " x"; }); // "leading space" Assert.Throws<FormatException>(() => { range.Unit = "x "; }); // "trailing space" Assert.Throws<FormatException>(() => { range.Unit = "x y"; }); // "invalid token" }
public void Equals() { var value = new ContentRangeHeaderValue (8); Assert.AreEqual (value, new ContentRangeHeaderValue (8), "#1"); Assert.AreNotEqual (value, new ContentRangeHeaderValue (8, 30), "#2"); value = new ContentRangeHeaderValue (5, 30, 100); Assert.AreEqual (value, new ContentRangeHeaderValue (5, 30, 100), "#3"); Assert.AreNotEqual (value, new ContentRangeHeaderValue (5, 30, 101), "#4"); Assert.AreNotEqual (value, new ContentRangeHeaderValue (5, 30), "#5"); Assert.AreNotEqual (value, new ContentRangeHeaderValue (5, 30, 100) { Unit = "g" }, "#6"); }
public void Ctor_SetsContentRange() { // Arrange ContentRangeHeaderValue expectedContentRange = new ContentRangeHeaderValue(5, 9, 20); Mock<Stream> mockInnerStream = new Mock<Stream>(); mockInnerStream.Setup(s => s.CanSeek).Returns(true); mockInnerStream.Setup(s => s.Length).Returns(20); RangeItemHeaderValue range = new RangeItemHeaderValue(5, 9); // Act ByteRangeStream rangeStream = new ByteRangeStream(mockInnerStream.Object, range); // Assert Assert.Equal(expectedContentRange, rangeStream.ContentRange); }
private ContentRangeHeaderValue(ContentRangeHeaderValue source) { Contract.Requires(source != null); _from = source._from; _to = source._to; _length = source._length; _unit = source._unit; }
private ContentRangeHeaderValue(ContentRangeHeaderValue source) { Debug.Assert(source != null); _from = source._from; _to = source._to; _length = source._length; _unit = source._unit; }
public static bool TryParse(string input, out ContentRangeHeaderValue parsedValue) { parsedValue = null; var lexer = new Lexer(input); var t = lexer.Scan(); if (t != Token.Type.Token) { return(false); } var value = new ContentRangeHeaderValue(); value.unit = lexer.GetStringValue(t); t = lexer.Scan(); if (t != Token.Type.Token) { return(false); } int nvalue; if (!lexer.IsStarStringValue(t)) { if (!lexer.TryGetNumericValue(t, out nvalue)) { var s = lexer.GetStringValue(t); if (s.Length < 3) { return(false); } var sep = s.Split('-'); if (sep.Length != 2) { return(false); } if (!int.TryParse(sep[0], NumberStyles.None, CultureInfo.InvariantCulture, out nvalue)) { return(false); } value.From = nvalue; if (!int.TryParse(sep[1], NumberStyles.None, CultureInfo.InvariantCulture, out nvalue)) { return(false); } value.To = nvalue; } else { value.From = nvalue; t = lexer.Scan(); if (t != Token.Type.SeparatorDash) { return(false); } t = lexer.Scan(); if (!lexer.TryGetNumericValue(t, out nvalue)) { return(false); } value.To = nvalue; } } t = lexer.Scan(); if (t != Token.Type.SeparatorSlash) { return(false); } t = lexer.Scan(); if (!lexer.IsStarStringValue(t)) { if (!lexer.TryGetNumericValue(t, out nvalue)) { return(false); } value.Length = nvalue; } t = lexer.Scan(); if (t != Token.Type.End) { return(false); } parsedValue = value; return(true); }
HttpResponseMessage StreamFile(BlobId formatBlobId, FileNameWithExtension fileName = null) { var descriptor = _blobStore.GetDescriptor(formatBlobId); if (descriptor == null) { return Request.CreateErrorResponse( HttpStatusCode.NotFound, string.Format("File {0} not found", formatBlobId) ); } RangeHeaderValue rangeHeader = Request.Headers.Range; var response = Request.CreateResponse(HttpStatusCode.OK); response.Headers.AcceptRanges.Add("bytes"); // HEAD? bool isHead = false; if (Request.Method == HttpMethod.Head) { isHead = true; rangeHeader = null; } // full stream if (rangeHeader == null || !rangeHeader.Ranges.Any()) { if (isHead) { response.Content = new ByteArrayContent(new byte[0]); response.Content.Headers.ContentLength = descriptor.Length; } else { response.Content = new StreamContent(descriptor.OpenRead()); } response.Content.Headers.ContentType = new MediaTypeHeaderValue(descriptor.ContentType); if (fileName != null) { response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = fileName }; } return response; } // range stream long start = 0, end = 0; long totalLength = descriptor.Length; // 1. If the unit is not 'bytes'. // 2. If there are multiple ranges in header value. // 3. If start or end position is greater than file length. if (rangeHeader.Unit != "bytes" || rangeHeader.Ranges.Count > 1 || !TryReadRangeItem(rangeHeader.Ranges.First(), totalLength, out start, out end)) { response.StatusCode = HttpStatusCode.RequestedRangeNotSatisfiable; response.Content = new StreamContent(Stream.Null); // No content for this status. response.Content.Headers.ContentRange = new ContentRangeHeaderValue(totalLength); response.Content.Headers.ContentType = new MediaTypeHeaderValue(descriptor.ContentType); return response; } var contentRange = new ContentRangeHeaderValue(start, end, totalLength); // We are now ready to produce partial content. response.StatusCode = HttpStatusCode.PartialContent; response.Content = new PushStreamContent((outputStream, httpContent, transpContext) => { using (outputStream) // Copy the file to output stream in indicated range. using (Stream inputStream = descriptor.OpenRead()) CreatePartialContent(inputStream, outputStream, start, end); }, descriptor.ContentType); response.Content.Headers.ContentType = new MediaTypeHeaderValue(descriptor.ContentType); response.Content.Headers.ContentLength = end - start + 1; response.Content.Headers.ContentRange = contentRange; return response; }
public void CreateErrorResponseRangeNotSatisfiable_SetsCorrectStatusCodeAndContentRangeHeader() { // Arrange HttpRequestMessage request = new HttpRequestMessage(); ContentRangeHeaderValue expectedContentRange = new ContentRangeHeaderValue(length: 128); InvalidByteRangeException invalidByteRangeException = new InvalidByteRangeException(expectedContentRange); // Act HttpResponseMessage response = request.CreateErrorResponse(invalidByteRangeException); // Assert Assert.Equal(HttpStatusCode.RequestedRangeNotSatisfiable, response.StatusCode); Assert.Same(expectedContentRange, response.Content.Headers.ContentRange); }
public InvalidByteRangeException(ContentRangeHeaderValue contentRange, SerializationInfo info, StreamingContext context) : base(info, context) { this.Initialize(contentRange); }
public static bool TryParse(string input, out ContentRangeHeaderValue parsedValue) { }
public void CreateErrorResponseRangeNotSatisfiable_SetsCorrectStatusCodeAndContentRangeHeader() { // Arrange var context = new DefaultHttpContext(); context.RequestServices = CreateServices(new DefaultContentNegotiator()); var request = CreateRequest(context); var expectedContentRange = new ContentRangeHeaderValue(length: 128); var invalidByteRangeException = new InvalidByteRangeException(expectedContentRange); // Act var response = request.CreateErrorResponse(invalidByteRangeException); // Assert Assert.Equal(HttpStatusCode.RequestedRangeNotSatisfiable, response.StatusCode); Assert.Same(expectedContentRange, response.Content.Headers.ContentRange); }
public void ToString_UseDifferentRanges_AllSerializedCorrectly() { ContentRangeHeaderValue range = new ContentRangeHeaderValue(1, 2, 3); range.Unit = "myunit"; Assert.Equal("myunit 1-2/3", range.ToString()); // "Range with all fields set" range = new ContentRangeHeaderValue(123456789012345678, 123456789012345679); Assert.Equal("bytes 123456789012345678-123456789012345679/*", range.ToString()); // "Only range, no length" range = new ContentRangeHeaderValue(150); Assert.Equal("bytes */150", range.ToString()); // "Only length, no range" }
public void ContentRange_ReadAndWriteProperty_ValueMatchesPriorSetValue() { Assert.Null(_headers.ContentRange); ContentRangeHeaderValue value = new ContentRangeHeaderValue(1, 2, 3); _headers.ContentRange = value; Assert.Equal(value, _headers.ContentRange); _headers.ContentRange = null; Assert.Null(_headers.ContentRange); }
public ByteRangeStream(Stream innerStream, RangeItemHeaderValue range) : base(innerStream) { // Ranges are inclusive so 0-9 means the first 10 bytes long maxLength = innerStream.Length - 1; long upperbounds; if (range.To.HasValue) { if (range.From.HasValue) { // e.g bytes=0-499 (the first 500 bytes offsets 0-499) upperbounds = Math.Min(range.To.Value, maxLength); _lowerbounds = range.From.Value; } else { // e.g bytes=-500 (the final 500 bytes) upperbounds = maxLength; _lowerbounds = Math.Max(innerStream.Length - range.To.Value, 0); } } else { if (range.From.HasValue) { // e.g bytes=500- (from byte offset 500 and up) upperbounds = maxLength; _lowerbounds = range.From.Value; } else { // e.g. bytes=- (invalid so will never get here) upperbounds = maxLength; _lowerbounds = 0; } } _totalCount = upperbounds - _lowerbounds + 1; ContentRange = new ContentRangeHeaderValue(_lowerbounds, upperbounds, innerStream.Length); }
public static bool TryParse(string input, out ContentRangeHeaderValue parsedValue) { int index = 0; object output; parsedValue = null; if (GenericHeaderParser.ContentRangeParser.TryParseValue(input, null, ref index, out output)) { parsedValue = (ContentRangeHeaderValue)output; return true; } return false; }
public void Properties() { var value = new ContentRangeHeaderValue (4); Assert.IsNull (value.From, "#1"); Assert.IsTrue (value.HasLength, "#2"); Assert.IsFalse (value.HasRange, "#3"); Assert.AreEqual (4, value.Length, "#4"); Assert.IsNull (value.To, "#5"); Assert.AreEqual ("bytes", value.Unit, "#6"); value = new ContentRangeHeaderValue (1, 10, 20); value.Unit = "mu"; Assert.AreEqual (1, value.From, "#11"); Assert.IsTrue (value.HasLength, "#12"); Assert.IsTrue (value.HasRange, "#13"); Assert.AreEqual (20, value.Length, "#14"); Assert.AreEqual (10, value.To, "#15"); Assert.AreEqual ("mu", value.Unit, "#16"); }
/// <summary> /// 依傳入的標頭回傳一個ResponseMessage /// 正常來說直接回應給瀏覽器就可以了 /// this will return a ResponseMessage object /// and response to web browser general. /// </summary> /// <param name="rangeHeader">ApiController's property: Request.Headers.Range</param> /// <param name="fileName">video file name, it was getting from request's query string general</param> /// <returns>HttpResponseMessage</returns> public HttpResponseMessage CreateHttpResponseMessage(RangeHeaderValue rangeHeader, string fileName) { HttpResponseMessage response = new HttpResponseMessage(); // This can prevent some unnecessary accesses. // These kind of file names won't be existing at all. if (string.IsNullOrWhiteSpace(fileName) || AnyInvalidFileNameChars(fileName)) throw new HttpResponseException(HttpStatusCode.NotFound); FileInfo fileInfo = new FileInfo(Path.Combine(InitialDirectory, fileName)); if (!fileInfo.Exists) throw new HttpResponseException(HttpStatusCode.NotFound); long totalLength = fileInfo.Length; response.Headers.AcceptRanges.Add("bytes"); // The request will be treated as normal request if there is no Range header. if (rangeHeader == null || !rangeHeader.Ranges.Any()) { response.StatusCode = HttpStatusCode.OK; response.Content = new PushStreamContent((outputStream, httpContent, transpContext) => { using (outputStream) // Copy the file to output stream straightforward. using (Stream inputStream = fileInfo.OpenRead()) { try { inputStream.CopyTo(outputStream, ReadStreamBufferSize); } catch (Exception error) { Console.WriteLine(error); } } }, GetMimeNameFromExt(fileInfo.Extension)); response.Content.Headers.ContentLength = totalLength; return response; } long start = 0, end = 0; // 1. If the unit is not 'bytes'. // 2. If there are multiple ranges in header value. // 3. If start or end position is greater than file length. if (rangeHeader.Unit != "bytes" || rangeHeader.Ranges.Count > 1 || !TryReadRangeItem(rangeHeader.Ranges.First(), totalLength, out start, out end)) { response.StatusCode = HttpStatusCode.RequestedRangeNotSatisfiable; response.Content = new StreamContent(Stream.Null); // No content for this status. response.Content.Headers.ContentRange = new ContentRangeHeaderValue(totalLength); response.Content.Headers.ContentType = GetMimeNameFromExt(fileInfo.Extension); return response; } var contentRange = new ContentRangeHeaderValue(start, end, totalLength); // We are now ready to produce partial content. response.StatusCode = HttpStatusCode.PartialContent; response.Content = new PushStreamContent((outputStream, httpContent, transpContext) => { using (outputStream) // Copy the file to output stream in indicated range. using (Stream inputStream = fileInfo.OpenRead()) CreatePartialContent(inputStream, outputStream, start, end); }, GetMimeNameFromExt(fileInfo.Extension)); response.Content.Headers.ContentLength = end - start + 1; response.Content.Headers.ContentRange = contentRange; return response; }
private static bool TryCreateContentRange(string input, string unit, int fromStartIndex, int fromLength, int toStartIndex, int toLength, int lengthStartIndex, int lengthLength, out object parsedValue) { parsedValue = null; long from = 0; if ((fromLength > 0) && !HeaderUtilities.TryParseInt64(input.Substring(fromStartIndex, fromLength), out from)) { return false; } long to = 0; if ((toLength > 0) && !HeaderUtilities.TryParseInt64(input.Substring(toStartIndex, toLength), out to)) { return false; } // 'from' must not be greater than 'to' if ((fromLength > 0) && (toLength > 0) && (from > to)) { return false; } long length = 0; if ((lengthLength > 0) && !HeaderUtilities.TryParseInt64(input.Substring(lengthStartIndex, lengthLength), out length)) { return false; } // 'from' and 'to' must be less than 'length' if ((toLength > 0) && (lengthLength > 0) && (to >= length)) { return false; } ContentRangeHeaderValue result = new ContentRangeHeaderValue(); result._unit = unit; if (fromLength > 0) { result._from = from; result._to = to; } if (lengthLength > 0) { result._length = length; } parsedValue = result; return true; }
/// <summary> /// <see cref="HttpContent"/> implementation which provides a byte range view over a stream used to generate HTTP /// 206 (Partial Content) byte range responses. If none of the requested ranges overlap with the current extend /// of the selected resource represented by the <paramref name="content"/> parameter then an /// <see cref="InvalidByteRangeException"/> is thrown indicating the valid Content-Range of the content. /// </summary> /// <param name="content">The stream over which to generate a byte range view.</param> /// <param name="range">The range or ranges, typically obtained from the Range HTTP request header field.</param> /// <param name="mediaType">The media type of the content stream.</param> /// <param name="bufferSize">The buffer size used when copying the content stream.</param> public ByteRangeStreamContent(Stream content, RangeHeaderValue range, MediaTypeHeaderValue mediaType, int bufferSize) { if (content == null) { throw new ArgumentNullException("content"); } if (!content.CanSeek) { throw new ArgumentException("content", RS.Format(Resources.ByteRangeStreamNotSeekable, typeof(ByteRangeStreamContent).Name)); } if (range == null) { throw new ArgumentNullException("range"); } if (mediaType == null) { throw new ArgumentNullException("mediaType"); } if (bufferSize < MinBufferSize) { throw new ArgumentOutOfRangeException("bufferSize", bufferSize, RS.Format(Resources.ArgumentMustBeGreaterThanOrEqualTo, MinBufferSize)); } if (!range.Unit.Equals(SupportedRangeUnit, StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException(RS.Format(Resources.ByteRangeStreamContentNotBytesRange, range.Unit, SupportedRangeUnit), "range"); } try { // If we have more than one range then we use a multipart/byteranges content type as wrapper. // Otherwise we use a non-multipart response. if (range.Ranges.Count > 1) { // Create Multipart content and copy headers to this content MultipartContent rangeContent = new MultipartContent(ByteRangesContentSubtype); _byteRangeContent = rangeContent; foreach (RangeItemHeaderValue rangeValue in range.Ranges) { try { ByteRangeStream rangeStream = new ByteRangeStream(content, rangeValue); HttpContent rangeBodyPart = new StreamContent(rangeStream, bufferSize); rangeBodyPart.Headers.ContentType = mediaType; rangeBodyPart.Headers.ContentRange = rangeStream.ContentRange; rangeContent.Add(rangeBodyPart); } catch (ArgumentOutOfRangeException) { // We ignore range errors until we check that we have at least one valid range } } // If no overlapping ranges were found then stop if (!rangeContent.Any()) { ContentRangeHeaderValue actualContentRange = new ContentRangeHeaderValue(content.Length); string msg = RS.Format(Resources.ByteRangeStreamNoneOverlap, range.ToString()); throw new InvalidByteRangeException(actualContentRange, msg); } } else if (range.Ranges.Count == 1) { try { ByteRangeStream rangeStream = new ByteRangeStream(content, range.Ranges.First()); _byteRangeContent = new StreamContent(rangeStream, bufferSize); _byteRangeContent.Headers.ContentType = mediaType; _byteRangeContent.Headers.ContentRange = rangeStream.ContentRange; } catch (ArgumentOutOfRangeException) { ContentRangeHeaderValue actualContentRange = new ContentRangeHeaderValue(content.Length); string msg = RS.Format(Resources.ByteRangeStreamNoOverlap, range.ToString()); throw new InvalidByteRangeException(actualContentRange, msg); } } else { throw new ArgumentException(Resources.ByteRangeStreamContentNoRanges, "range"); } // Copy headers from byte range content so that we get the right content type etc. foreach (KeyValuePair<string, IEnumerable<string>> header in _byteRangeContent.Headers) { Headers.TryAddWithoutValidation(header.Key, header.Value); } _content = content; _start = content.Position; } catch { if (_byteRangeContent != null) { _byteRangeContent.Dispose(); } throw; } }
/// <summary> /// <see cref="HttpContent"/> implementation which provides a byte range view over a stream used to generate HTTP /// 206 (Partial Content) byte range responses. If none of the requested ranges overlap with the current extend /// of the selected resource represented by the <paramref name="content"/> parameter then an /// <see cref="InvalidByteRangeException"/> is thrown indicating the valid Content-Range of the content. /// </summary> /// <param name="content">The stream over which to generate a byte range view.</param> /// <param name="range">The range or ranges, typically obtained from the Range HTTP request header field.</param> /// <param name="mediaType">The media type of the content stream.</param> /// <param name="bufferSize">The buffer size used when copying the content stream.</param> public ByteRangeStreamContent(Stream content, RangeHeaderValue range, MediaTypeHeaderValue mediaType, int bufferSize) { try { // If we have more than one range then we use a multipart/byteranges content type as wrapper. // Otherwise we use a non-multipart response. if (range.Ranges.Count > 1) { // Create Multipart content and copy headers to this content MultipartContent rangeContent = new MultipartContent(ByteRangesContentSubtype); _byteRangeContent = rangeContent; foreach (RangeItemHeaderValue rangeValue in range.Ranges) { try { ByteRangeStream rangeStream = new ByteRangeStream(content, rangeValue); HttpContent rangeBodyPart = new StreamContent(rangeStream, bufferSize); rangeBodyPart.Headers.ContentType = mediaType; rangeBodyPart.Headers.ContentRange = rangeStream.ContentRange; rangeContent.Add(rangeBodyPart); } catch (ArgumentOutOfRangeException) { // We ignore range errors until we check that we have at least one valid range } } // If no overlapping ranges were found then stop if (!rangeContent.Any()) { ContentRangeHeaderValue actualContentRange = new ContentRangeHeaderValue(content.Length); string msg = "ByteRangeStreamNoneOverlap"; throw new InvalidByteRangeException(actualContentRange, msg); } } else if (range.Ranges.Count == 1) { try { ByteRangeStream rangeStream = new ByteRangeStream(content, range.Ranges.First()); _byteRangeContent = new StreamContent(rangeStream, bufferSize); _byteRangeContent.Headers.ContentType = mediaType; _byteRangeContent.Headers.ContentRange = rangeStream.ContentRange; } catch (ArgumentOutOfRangeException) { ContentRangeHeaderValue actualContentRange = new ContentRangeHeaderValue(content.Length); string msg = "ByteRangeStreamNoOverlap"; throw new InvalidByteRangeException(actualContentRange, msg); } } else { throw new ArgumentException("range"); } // Copy headers from byte range content so that we get the right content type etc. _byteRangeContent.Headers.CopyTo(Headers); _content = content; _start = content.Position; } catch { if (_byteRangeContent != null) { _byteRangeContent.Dispose(); } throw; } }
public void Ctor_SetsContentRange() { ContentRangeHeaderValue contentRange = new ContentRangeHeaderValue(0, 20, 100); InvalidByteRangeException invalidByteRangeException = new InvalidByteRangeException(contentRange); Assert.Same(contentRange, invalidByteRangeException.ContentRange); }
public void ContentRange_UseAddMethod_AddedValueCanBeRetrievedUsingProperty() { _headers.TryAddWithoutValidation("Content-Range", "custom 1-2/*"); ContentRangeHeaderValue value = new ContentRangeHeaderValue(1, 2); value.Unit = "custom"; Assert.Equal(value, _headers.ContentRange); }
public InvalidByteRangeException(ContentRangeHeaderValue contentRange) { this.Initialize(contentRange); }
public static bool TryParse (string input, out ContentRangeHeaderValue parsedValue) { parsedValue = null; var lexer = new Lexer (input); var t = lexer.Scan (); if (t != Token.Type.Token) return false; var value = new ContentRangeHeaderValue (); value.unit = lexer.GetStringValue (t); t = lexer.Scan (); if (t != Token.Type.Token) return false; int nvalue; if (!lexer.IsStarStringValue (t)) { if (!lexer.TryGetNumericValue (t, out nvalue)) { var s = lexer.GetStringValue (t); if (s.Length < 3) return false; var sep = s.Split ('-'); if (sep.Length != 2) return false; if (!int.TryParse (sep[0], NumberStyles.None, CultureInfo.InvariantCulture, out nvalue)) return false; value.From = nvalue; if (!int.TryParse (sep[1], NumberStyles.None, CultureInfo.InvariantCulture, out nvalue)) return false; value.To = nvalue; } else { value.From = nvalue; t = lexer.Scan (recognizeDash: true); if (t != Token.Type.SeparatorDash) return false; t = lexer.Scan (); if (!lexer.TryGetNumericValue (t, out nvalue)) return false; value.To = nvalue; } } t = lexer.Scan (); if (t != Token.Type.SeparatorSlash) return false; t = lexer.Scan (); if (!lexer.IsStarStringValue (t)) { long lvalue; if (!lexer.TryGetNumericValue (t, out lvalue)) return false; value.Length = lvalue; } t = lexer.Scan (); if (t != Token.Type.End) return false; parsedValue = value; return true; }
public InvalidByteRangeException(ContentRangeHeaderValue contentRange, string message, Exception innerException) : base(message, innerException) { this.Initialize(contentRange); }