public void NoOverlappingRangesThrowException( string ranges, int innerStreamLength, string contentRange ) { // Arrange string data = new String('a', innerStreamLength); byte[] bytes = Encoding.UTF8.GetBytes(data); MemoryStream memStream = new MemoryStream(bytes); RangeHeaderValue range = RangeHeaderValue.Parse(ranges); // Act try { new ByteRangeStreamContent(memStream, range, _expectedMediatype); } catch (InvalidByteRangeException invalidByteRangeException) { ContentRangeHeaderValue expectedContentRange = ContentRangeHeaderValue.Parse( contentRange ); Assert.Equal(expectedContentRange, invalidByteRangeException.ContentRange); } }
public void SingleRangeGeneratesNonMultipartContent( string ranges, int innerStreamLength, string contentRange ) { // Arrange string data = new String('a', innerStreamLength); byte[] bytes = Encoding.UTF8.GetBytes(data); MemoryStream memStream = new MemoryStream(bytes); RangeHeaderValue range = RangeHeaderValue.Parse(ranges); // Act ByteRangeStreamContent rangeContent = new ByteRangeStreamContent( memStream, range, _expectedMediatype ); // Assert Assert.Equal(_expectedMediatype, rangeContent.Headers.ContentType); ContentRangeHeaderValue expectedContentRange = ContentRangeHeaderValue.Parse( contentRange ); Assert.Equal(expectedContentRange, rangeContent.Headers.ContentRange); }
public void Parse() { var res = ContentRangeHeaderValue.Parse("bytes 0 - 499/ 9223372036854775807"); Assert.AreEqual(0, res.From, "#1"); Assert.AreEqual(499, res.To, "#2"); Assert.AreEqual(9223372036854775807, res.Length, "#3"); Assert.AreEqual("bytes 0-499/9223372036854775807", res.ToString(), "#4"); res = ContentRangeHeaderValue.Parse("bytes */ 8"); Assert.IsNull(res.From, "#11"); Assert.IsNull(res.To, "#12"); Assert.AreEqual(8, res.Length, "#13"); Assert.AreEqual("bytes */8", res.ToString(), "#14"); res = ContentRangeHeaderValue.Parse("by */*"); Assert.IsNull(res.From, "#21"); Assert.IsNull(res.To, "#22"); Assert.IsNull(res.Length, "#23"); Assert.AreEqual("by */*", res.ToString(), "#24"); res = ContentRangeHeaderValue.Parse("bytes 199999999999999999 - 999999999999999999/ 9223372036854775807"); Assert.AreEqual(199999999999999999, res.From, "#31"); Assert.AreEqual(999999999999999999, res.To, "#32"); Assert.AreEqual(9223372036854775807, res.Length, "#33"); Assert.AreEqual("bytes 199999999999999999-999999999999999999/9223372036854775807", res.ToString(), "#34"); }
public async Task <string> PutChunk( string id, string uploadKey, string chunkKey, string sequentialState, int chunkIndex, int totalChunks, CancellationToken cancellationToken = default(CancellationToken)) { Logger.LogDebug($"SequentialState: {sequentialState}"); var range = ContentRangeHeaderValue.Parse(Request.Headers["X-Content-Range"]); long length = (long)range.To - (long)range.From + 1; using (var requestStream = new StreamRequestWrapper(Request.Body, length)) return(await backend.ChunkedUploadChunkAsync( context, id, uploadKey, chunkKey, chunkIndex, totalChunks, sequentialState, (long)range.From, (long)range.To, (long)range.Length, requestStream, cancellationToken )); }
public async Task <UploadContextModel> PatchRange( UploadContextModel uploadContext, int chunkIndex, CancellationToken cancellationToken = default(CancellationToken) ) { if (Request.Headers["Content-Range"].Count == 0) { throw new Exception("Missing required Content-Range header"); } var range = ContentRangeHeaderValue.Parse(Request.Headers["Content-Range"].ToString()); if (range.From == null) { throw new ArgumentNullException("Range Header From must be specified"); } if (range.To == null) { throw new ArgumentNullException("Range Header To must be specified"); } if ((long)range.Length != uploadContext.FileLength) { throw new ArgumentNullException("Range Header Length does not match UploadContext.FileLength"); } return(await FileContentsService.UploadChunkAsync( uploadContext, (long)range.From, (long)range.To, Request.Body, chunkIndex, cancellationToken)); }
/// <summary> /// Copies content headers. /// </summary> /// <param name="httpRequest">Outgoing request.</param> /// <param name="headerMap">Incoming request header map.</param> public static void CopyContentHeaders(this HttpRequestMessage httpRequest, Dictionary <string, string> headerMap) { httpRequest.Content.Headers.ContentDisposition = headerMap.ContainsKey("Content-Disposition") ? ContentDispositionHeaderValue.Parse(headerMap["Content-Disposition"]) : httpRequest.Content.Headers.ContentDisposition; httpRequest.Content.Headers.ContentLocation = headerMap.ContainsKey("Content-Location") ? new Uri(headerMap["Content-Location"]) : httpRequest.Content.Headers.ContentLocation; httpRequest.Content.Headers.ContentRange = headerMap.ContainsKey("Content-Range") ? ContentRangeHeaderValue.Parse(headerMap["Content-Range"]) : httpRequest.Content.Headers.ContentRange; httpRequest.Content.Headers.ContentType = headerMap.ContainsKey("Content-Type") ? MediaTypeHeaderValue.Parse(headerMap["Content-Type"]) : httpRequest.Content.Headers.ContentType; httpRequest.Content.Headers.Expires = headerMap.ContainsKey("Expires") ? DateTimeOffset.Parse(headerMap["Expires"]) : httpRequest.Content.Headers.Expires; httpRequest.Content.Headers.LastModified = headerMap.ContainsKey("Last-Modified") ? DateTimeOffset.Parse(headerMap["Last-Modified"]) : httpRequest.Content.Headers.LastModified; }
public async Task <HttpResponse> Send(Uri requestUri, HttpMethod method, RequestParameters requestParams, CancellationToken cancellationToken) { using (var request = new HttpRequestMessage(method, requestUri)) { if (requestParams.Content != null) { request.Content = requestParams.Content; if (!string.IsNullOrEmpty(requestParams.ContentType)) { request.Content.Headers.ContentType = new MediaTypeHeaderValue(requestParams.ContentType); } } foreach (var header in requestParams.Headers) { // When setting Content-Range as a Header on the HTTPRequestHeader directly, the call to SendAsync crashes out with the following exception: // "Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects." if (header.Key.Equals("Content-Range")) { request.Content.Headers.ContentRange = ContentRangeHeaderValue.Parse(header.Value); } else { request.Headers.Add(header.Key, header.Value); } } var response = await _httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false); return(new HttpResponse(response.Content, (int)response.StatusCode, response.ReasonPhrase)); } }
public void Parse_Invalid() { try { ContentRangeHeaderValue.Parse(null); Assert.Fail("#1"); } catch (FormatException) { } try { ContentRangeHeaderValue.Parse(" "); Assert.Fail("#2"); } catch (FormatException) { } try { ContentRangeHeaderValue.Parse("a b"); Assert.Fail("#3"); } catch (FormatException) { } try { ContentRangeHeaderValue.Parse("bytes 10/"); Assert.Fail("#4"); } catch (FormatException) { } }
public void MultipleRangesGeneratesMultipartByteRangesContent(string ranges, int innerStreamLength, int expectedBodyparts, string[] contentRanges) { // Arrange string data = new String('a', innerStreamLength); byte[] bytes = Encoding.UTF8.GetBytes(data); MemoryStream memStream = new MemoryStream(bytes); RangeHeaderValue range = RangeHeaderValue.Parse(ranges); // Act ByteRangeStreamContent content = new ByteRangeStreamContent(memStream, range, _expectedMediatype); MemoryStream result = new MemoryStream(); content.CopyToAsync(result).Wait(); MultipartMemoryStreamProvider multipart = content.ReadAsMultipartAsync().Result; // Assert Assert.Equal(expectedBodyparts, multipart.Contents.Count); for (int count = 0; count < multipart.Contents.Count; count++) { MediaTypeHeaderValue contentType = multipart.Contents[count].Headers.ContentType; Assert.Equal(_expectedMediatype, contentType); ContentRangeHeaderValue expectedContentRange = ContentRangeHeaderValue.Parse(contentRanges[count]); ContentRangeHeaderValue contentRange = multipart.Contents[count].Headers.ContentRange; Assert.Equal(expectedContentRange, contentRange); } }
public void Parse_SetOfValidValueStrings_ParsedCorrectly() { CheckValidParse(" bytes 1-2/3 ", new ContentRangeHeaderValue(1, 2, 3)); CheckValidParse("bytes * / 3", new ContentRangeHeaderValue(3)); CheckValidParse(" custom 1234567890123456789-1234567890123456799/*", new ContentRangeHeaderValue(1234567890123456789, 1234567890123456799) { Unit = "custom" }); CheckValidParse(" custom * / 123 ", new ContentRangeHeaderValue(123) { Unit = "custom" }); // Note that we don't have a public constructor for value 'bytes */*' since the RFC doesn't mention a // scenario for it. However, if a server returns this value, we're flexible and accept it. var result = ContentRangeHeaderValue.Parse("bytes */*"); Assert.Equal("bytes", result.Unit); Assert.Null(result.From); Assert.Null(result.To); Assert.Null(result.Length); Assert.False(result.HasRange, "HasRange"); Assert.False(result.HasLength, "HasLength"); }
public void GetRawHeaders_ReturnsExpectedHeaders() { // No headers HttpRequestMessage request = new HttpRequestMessage(); var headers = request.GetRawHeaders(); Assert.Equal(0, headers.Count); // One header request = new HttpRequestMessage(); string testHeader1 = "TestValue"; request.Headers.Add("Header1", testHeader1); headers = request.GetRawHeaders(); Assert.Equal(1, headers.Count); Assert.Equal(testHeader1, headers["Header1"]); // Multiple headers string userAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36"; string accept = "text/html, application/xhtml+xml, application/xml; q=0.9, */*; q=0.8"; string testHeader2 = "foo,bar,baz"; string testHeader3 = "foo bar baz"; string testHeader4 = "testValue4"; request.Headers.Add("User-Agent", userAgent); request.Headers.Add("Accept", accept); request.Headers.Add("Header2", testHeader2); request.Headers.Add("Header3", testHeader3); request.Headers.Add("Header4", testHeader4); request.Headers.Add("Empty", string.Empty); var str = request.Headers.ToString(); headers = request.GetRawHeaders(); Assert.Equal(7, headers.Count); Assert.Equal(userAgent, headers["User-Agent"]); Assert.Equal(accept, headers["Accept"]); Assert.Equal(testHeader1, headers["Header1"]); Assert.Equal(testHeader2, headers["Header2"]); Assert.Equal(testHeader3, headers["Header3"]); Assert.Equal(testHeader4, headers["Header4"]); Assert.Equal(testHeader4, headers["header4"]); Assert.Equal(string.Empty, headers["Empty"]); // Content headers request.Content = new StringContent("test"); request.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html"); request.Content.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse("form-data; name=\"fieldName\"; filename=\"filename.jpg\""); request.Content.Headers.ContentRange = ContentRangeHeaderValue.Parse("bytes 200-1000/67589"); headers = request.GetRawHeaders(); Assert.Equal(10, headers.Count); Assert.Equal("text/html", headers["Content-Type"]); Assert.Equal("form-data; name=\"fieldName\"; filename=\"filename.jpg\"", headers["Content-Disposition"]); Assert.Equal("bytes 200-1000/67589", headers["Content-Range"]); }
private async Task <Tuple <File, ContentRangeHeaderValue> > ProcessResumableUploadResponse(HttpResponseMessage response) { if (response.IsSuccessStatusCode) { return(new Tuple <File, ContentRangeHeaderValue>(await response.Content.ReadJsonAsync <File>(), null)); } if ((int)response.StatusCode == 308) { var range = response.Headers.GetValues("Range").First(); var r = ContentRangeHeaderValue.Parse("bytes " + range.Substring(6) + "/*"); return(new Tuple <File, ContentRangeHeaderValue>(null, r)); } else { throw await ProcessException(response); } }
public async Task TestResponseContentHeaders() { var mock = new MockHttpClient(); var currentDate = DateTime.UtcNow; var expectedExpires = new DateTimeOffset(currentDate.AddSeconds(60)); var expectedByteArray = new byte[] { 65 }; var expected = new ByteArrayContent(expectedByteArray); expected.Headers.Allow.Add("GET"); expected.Headers.Allow.Add("POST"); expected.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse("attachment"); expected.Headers.ContentLength = expectedByteArray.Length; expected.Headers.ContentLocation = new Uri("https://example.com"); expected.Headers.ContentRange = ContentRangeHeaderValue.Parse("bytes 200-1000/67589"); expected.Headers.ContentType = MediaTypeHeaderValue.Parse("text/plain"); expected.Headers.ContentMD5 = new byte[] { 1 }; expected.Headers.ContentLanguage.Add("en-US"); expected.Headers.ContentEncoding.Add("gzip"); expected.Headers.Expires = expectedExpires; expected.Headers.LastModified = currentDate; mock.SetupGet("/").ReturnsAsync(content: expected); var result = await mock.Object.GetAsync("/"); var resultByteArray = await result.Content.ReadAsByteArrayAsync(); Assert.Equal(expectedByteArray, resultByteArray); Assert.Equal("GET, POST", result.Content.Headers.Allow.ToString()); Assert.Equal("attachment", result.Content.Headers.ContentDisposition.ToString()); Assert.Equal(expectedByteArray.Length, result.Content.Headers.ContentLength); Assert.Equal("https://example.com/", result.Content.Headers.ContentLocation.AbsoluteUri); Assert.Equal("bytes 200-1000/67589", result.Content.Headers.ContentRange.ToString()); Assert.Equal("text/plain", result.Content.Headers.ContentType.ToString()); Assert.Equal(new byte[] { 1 }, result.Content.Headers.ContentMD5); Assert.Equal("en-US", result.Content.Headers.ContentLanguage.ToString()); Assert.Equal("gzip", result.Content.Headers.ContentEncoding.ToString()); Assert.NotNull(result.Content.Headers.Expires); Assert.NotNull(result.Content.Headers.LastModified); Assert.Equal(expectedExpires.ToString("s"), result.Content.Headers.Expires.Value.ToString("s")); Assert.Equal(currentDate.ToString("s"), result.Content.Headers.LastModified.Value.ToString("s")); }
public void Parse() { var res = ContentRangeHeaderValue.Parse("bytes 0 - 499/ 1234"); Assert.AreEqual(0, res.From, "#1"); Assert.AreEqual(499, res.To, "#2"); Assert.AreEqual(1234, res.Length, "#3"); Assert.AreEqual("bytes 0-499/1234", res.ToString(), "#4"); res = ContentRangeHeaderValue.Parse("bytes */ 8"); Assert.IsNull(res.From, "#11"); Assert.IsNull(res.To, "#12"); Assert.AreEqual(8, res.Length, "#13"); Assert.AreEqual("bytes */8", res.ToString(), "#14"); res = ContentRangeHeaderValue.Parse("by */*"); Assert.IsNull(res.From, "#21"); Assert.IsNull(res.To, "#22"); Assert.IsNull(res.Length, "#23"); Assert.AreEqual("by */*", res.ToString(), "#24"); }
/// <summary> /// Copies content headers. /// </summary> /// <param name="httpContent">Http content.</param> /// <param name="headerCollection">Header collection.</param> private static void CopyContentHeader(HttpContent httpContent, WebHeaderCollection headerCollection) { if (headerCollection["Content-Disposition"] != null) { httpContent.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse(headerCollection["Content-Disposition"]); } if (headerCollection[HttpRequestHeader.ContentLocation] != null) { httpContent.Headers.ContentLocation = new Uri(headerCollection[HttpRequestHeader.ContentLocation]); } if (headerCollection[HttpRequestHeader.ContentRange] != null) { httpContent.Headers.ContentRange = ContentRangeHeaderValue.Parse(headerCollection[HttpRequestHeader.ContentRange]); } if (headerCollection[HttpRequestHeader.ContentType] != null) { httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse(headerCollection[HttpRequestHeader.ContentType]); } if (headerCollection[HttpRequestHeader.Expires] != null) { httpContent.Headers.Expires = DateTimeOffset.Parse(headerCollection[HttpRequestHeader.Expires], CultureInfo.InvariantCulture); } if (headerCollection[HttpRequestHeader.LastModified] != null) { httpContent.Headers.LastModified = DateTimeOffset.Parse(headerCollection[HttpRequestHeader.LastModified], CultureInfo.InvariantCulture); } if (headerCollection[HttpRequestHeader.ContentLength] != null) { httpContent.Headers.ContentLength = long.Parse(headerCollection[HttpRequestHeader.ContentLength], CultureInfo.InvariantCulture); } }
/// <summary> /// Perform the WebDAV call and fire the callback when finished. /// </summary> /// <param name="uri"></param> /// <param name="headers"></param> /// <param name="method"></param> /// <param name="content"></param> private async Task <HttpResponseMessage> HttpUploadRequest(Uri uri, HttpMethod method, Stream content, IDictionary <string, string> headers = null, long?startbytes = null, long?endbytes = null, long?totalLength = null) { using (var request = new HttpRequestMessage(method, uri)) { request.Headers.Connection.Add("Keep-Alive"); if (!string.IsNullOrWhiteSpace(UserAgent)) { request.Headers.UserAgent.Add(new ProductInfoHeaderValue(UserAgent, UserAgentVersion)); } else { request.Headers.UserAgent.Add(new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion)); } if (headers != null) { foreach (string key in headers.Keys) { request.Headers.Add(key, headers[key]); } } // Need to send along content? if (content != null) { request.Content = new StreamContent(content); if (startbytes.HasValue && endbytes.HasValue) { var len = totalLength.HasValue ? totalLength.ToString() : "*"; request.Content.Headers.ContentRange = ContentRangeHeaderValue.Parse($"bytes {startbytes}-{endbytes}/{len}"); request.Content.Headers.ContentLength = endbytes - startbytes + 1; } } return(await _httpClientWrapper.SendUploadAsync(request).ConfigureAwait(false)); } }
/// <summary> /// Returns ContentRange from headers. /// </summary> /// <param name="headers">Headers collection</param> /// <returns>ContentRange object</returns> public static ContentRangeHeaderValue GetContentRange(this WebHeaderCollection headers) { Contract.Requires(headers != null); return(ContentRangeHeaderValue.Parse(headers["Content-Range"])); }
private void CheckInvalidParse(string input) { Assert.Throws <FormatException>(() => { ContentRangeHeaderValue.Parse(input); }); }
private void CheckValidParse(string input, ContentRangeHeaderValue expectedResult) { ContentRangeHeaderValue result = ContentRangeHeaderValue.Parse(input); Assert.Equal(expectedResult, result); }
public async Task <ActionResult> UploadChunk( PathIdentifier pathIdentifier, BrowserFileInformation fileInformation, string token, CancellationToken cancellationToken = default(CancellationToken) ) { if (!Request.ContentLength.HasValue) { throw new Exception("Missing Content-Length header"); } if (Request.Headers["Content-Range"].Count == 0) { throw new Exception("Missing Content-Range header"); } if (Request.Headers["Content-Disposition"].Count == 0) { throw new Exception("Missing Content-Disposition header"); } var range = ContentRangeHeaderValue.Parse(Request.Headers["Content-Range"]); if (!range.HasLength) { throw new Exception("Content-Range header does not include total length"); } long from = (long)range.From; long to = (long)range.To; long fileLength = (long)range.Length; var fileName = fileInformation?.Name; if (fileName == null) { var contentDisposition = ContentDispositionHeaderValue.Parse(Request.Headers["Content-Disposition"]); fileName = contentDisposition?.FileName; if (fileName == null) { throw new Exception("Filename is not specified in either Content-Disposition header or fileInformation"); } // for some dumb reason, the ContentDispositionHeaderValue parser doesn't finish parsing file names // it leaves them quoted if (fileName.StartsWith('"') && fileName.EndsWith('"') && fileName.Length > 1) { fileName = WebUtility.UrlDecode(fileName.Substring(1, fileName.Length - 2)); } } Stream stream = Request.Body; UploadContextModel tokenState = null; // test retries //if ((new Random()).NextDouble() < .3) // throw new Exception("Chaos Monkey"); bool isFirstChunk = from == 0; bool isLastChunk = to == (fileLength - 1); FileIdentifier fileIdentifier = null; var folderModel = await Connection.Folder.GetOrThrowAsync(pathIdentifier); var modules = ModuleConfigurator.GetActiveModules(folderModel); // === Step 1: Begin Upload if (isFirstChunk) { var fileModel = new FileModel { Identifier = new FileIdentifier(pathIdentifier, null), Name = fileName, Modified = fileInformation?.LastModified != null ? epoch.AddMilliseconds(fileInformation.LastModified.Value) : DateTime.UtcNow, Length = fileLength, MimeType = fileInformation?.Type ?? Request.ContentType ?? "application/octet-stream", }.InitializeEmptyMetadata(); fileModel.Created = new DateTime(Math.Min(DateTime.UtcNow.Ticks, fileModel.Modified.Ticks), DateTimeKind.Utc); // some browsers will send us the relative path of a file during a folder upload var relativePath = fileInformation?.FullPath; if (!string.IsNullOrWhiteSpace(relativePath) && relativePath != "/") { if (relativePath.StartsWith("/")) { relativePath = relativePath.Substring(1); } pathIdentifier = pathIdentifier.CreateChild(relativePath); } fileModel.MetaPathIdentifierWrite(pathIdentifier); foreach (var module in modules) { await module.PreUploadAsync(folderModel, fileModel); } tokenState = await Connection.File.UploadBeginAsync(fileModel, cancellationToken : cancellationToken); } else { if (token == null) { throw new Exception("Uploaded secondary chunk without token"); } tokenState = JsonConvert.DeserializeObject <UploadContextModel>(token); } // === Step 2: Send this Chunk using (stream) { if (!isLastChunk) { if (to - from != tokenState.ChunkSize - 1) { throw new Exception($"Chunk Size Mismatch: received ({to - from}) expected ({tokenState.ChunkSize})"); } } int chunkIndex = (int)(from / tokenState.ChunkSize); tokenState = await Connection.File.UploadSendChunkAsync( tokenState, chunkIndex, from, to, stream, cancellationToken : cancellationToken ); } // === Step 3: End the Upload if (isLastChunk) // if file is one chunk, all three steps happen in a single call { var fileModel = await Connection.File.UploadEndAsync(tokenState, cancellationToken : cancellationToken); fileIdentifier = fileModel.Identifier; foreach (var module in modules) { await module.PostUploadAsync(folderModel, fileModel); } } return(Json(new APIResponse <UploadedFileResponse> { Response = new UploadedFileResponse { FileIdentifier = fileIdentifier, Token = JsonConvert.SerializeObject(tokenState) } })); }
/// <summary> /// Returns ContentRange from headers. /// </summary> /// <param name="headers">Headers collection</param> /// <returns>ContentRange object</returns> public static ContentRangeHeaderValue GetContentRange(this WebHeaderCollection headers) { return(ContentRangeHeaderValue.Parse(headers["Content-Range"])); }
public void Parse_SetOfInvalidValueStrings_Throws(string?input) { Assert.Throws <FormatException>(() => ContentRangeHeaderValue.Parse(input)); }
/// <summary> /// Insert a content HTTP header /// </summary> /// <param name="header">A <see cref="System.Net.Http.Headers.HttpContentHeaders"/> object on wich the content header will be recorded.</param> /// <param name="name">The header attribute name.</param> /// <param name="value">The header attribute value.</param> public void AddContentHeader(HttpContentHeaders header, string name, string value) { if (name.Equals("Allow", StringComparison.OrdinalIgnoreCase)) { header.Add("Allow", value); } else if (name.Equals("Content-Disposition", StringComparison.OrdinalIgnoreCase)) { header.ContentDisposition = new ContentDispositionHeaderValue(value); } else if (name.Equals("Content-Encoding", StringComparison.OrdinalIgnoreCase)) { header.Add("Content-Encoding", value); } else if (name.Equals("Content-Language", StringComparison.OrdinalIgnoreCase)) { header.Add("Content-Language", value); } else if (name.Equals("Content-Length", StringComparison.OrdinalIgnoreCase)) { header.ContentLength = long.Parse(value); } else if (name.Equals("Content-Length", StringComparison.OrdinalIgnoreCase)) { header.ContentLength = long.Parse(value); } else if (name.Equals("Content-Location", StringComparison.OrdinalIgnoreCase)) { header.ContentLocation = new Uri(value); } else if (name.Equals("Content-MD5", StringComparison.OrdinalIgnoreCase)) { header.ContentMD5 = Encoding.ASCII.GetBytes(value); } else if (name.Equals("Content-Range", StringComparison.OrdinalIgnoreCase)) { header.ContentRange = ContentRangeHeaderValue.Parse(value); } else if (name.Equals("Content-Type", StringComparison.OrdinalIgnoreCase)) { header.Add("Content-Type", value); } // C# does not allow any value here... Don't know why // header.ContentType = new MediaTypeHeaderValue(value); else if (name.Equals("Expires", StringComparison.OrdinalIgnoreCase)) { header.Expires = DateTimeOffset.Parse(value); } else if (name.Equals("Last-Modified", StringComparison.OrdinalIgnoreCase)) { header.LastModified = DateTimeOffset.Parse(value); } else { throw new ArgumentException("Content has no attribute named: " + name); } }