public static async Task WriteFileAsync_IfRangeHeaderValid_WritesRangeRequest <TContext>( Func <FileContentResult, TContext, Task> function) { // Arrange var contentType = "text/plain"; var lastModified = DateTimeOffset.MinValue; var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var result = new FileContentResult(byteArray, contentType) { LastModified = lastModified, EntityTag = entityTag, EnableRangeProcessing = true, }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; requestHeaders.Range = new RangeHeaderValue(0, 4); requestHeaders.IfRange = new RangeConditionHeaderValue(DateTimeOffset.MinValue); httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)context); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); if (result.EnableRangeProcessing) { Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); var contentRange = new ContentRangeHeaderValue(0, 4, byteArray.Length); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(5, httpResponse.ContentLength); Assert.Equal("Hello", body); } else { Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal(11, httpResponse.ContentLength); Assert.Equal("Hello World", body); } }
public async Task WriteFileAsync_IfRangeHeaderInvalid_RangeRequestIgnored() { // Arrange var contentType = "text/plain"; var lastModified = DateTimeOffset.MinValue.AddDays(1); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; requestHeaders.Range = new RangeHeaderValue(0, 4); requestHeaders.IfRange = new RangeConditionHeaderValue(new EntityTagHeaderValue("\"NotEtag\"")); httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); // Act await ExecuteAsync(httpContext, byteArray, contentType, lastModified, entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal("Hello World", body); }
public async Task WriteFileAsync_PreconditionStateUnspecified_RangeRequestedNotSatisfiable(string rangeString) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var httpContext = GetHttpContext(); httpContext.Request.Headers.Range = rangeString; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); // Act await ExecuteAsync(httpContext, byteArray, contentType, lastModified, entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(byteArray.Length); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(0, httpResponse.ContentLength); Assert.Empty(body); }
public async Task WriteFileAsync_PreconditionStateShouldProcess_WritesRangeRequested_IfRangeProcessingOn(long?start, long?end, string expectedString, long contentLength) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var readStream = new MemoryStream(byteArray); readStream.SetLength(11); var result = new FileStreamResult(readStream, contentType) { LastModified = lastModified, EntityTag = entityTag, }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert start = start ?? 11 - end; end = start + contentLength - 1; var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(start.Value, end.Value, byteArray.Length); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]); if (AppContext.TryGetSwitch(FileResultExecutorBase.EnableRangeProcessingSwitch, out var enableRangeProcessingSwitch) && enableRangeProcessingSwitch) { Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.Equal(contentLength, httpResponse.ContentLength); Assert.Equal(expectedString, body); } else { Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal("Hello World", body); } }
public async Task WriteFileAsync_IfRangeHeaderInvalid_RangeRequestedIgnored() { // Arrange var path = Path.GetFullPath("helllo.txt"); var contentType = "text/plain; charset=us-ascii; p1=p1-value"; var appEnvironment = new Mock <IWebHostEnvironment>(); appEnvironment.Setup(app => app.WebRootFileProvider) .Returns(GetFileProvider(path)); var sendFileFeature = new TestSendFileFeature(); var httpContext = GetHttpContext(GetFileProvider(path)); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFileFeature); var entityTag = new EntityTagHeaderValue("\"Etag\""); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfModifiedSince = DateTimeOffset.MinValue; requestHeaders.Range = new RangeHeaderValue(0, 3); requestHeaders.IfRange = new RangeConditionHeaderValue(new EntityTagHeaderValue("\"NotEtag\"")); httpContext.Request.Method = HttpMethods.Get; // Act await ExecuteAsync(httpContext, path, contentType, entityTag : entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(path, sendFileFeature.Name); Assert.Equal(0, sendFileFeature.Offset); Assert.Null(sendFileFeature.Length); }
public async Task WriteFileAsync_PreconditionStateUnspecified_RangeRequestIgnored(string rangeString) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var readStream = new MemoryStream(byteArray); var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); httpContext.Request.Headers.Range = rangeString; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); // Act await ExecuteAsync(httpContext, readStream, contentType, lastModified, entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Empty(httpResponse.Headers.ContentRange); Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal("Hello World", body); Assert.False(readStream.CanSeek); }
public async Task WriteFileAsync_IfRangeHeaderValid_WritesRequestedRange() { // Arrange var path = Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")); var entityTag = new EntityTagHeaderValue("\"Etag\""); var sendFile = new TestSendFileFeature(); var httpContext = GetHttpContext(); httpContext.Features.Set <IHttpResponseBodyFeature>(sendFile); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfModifiedSince = DateTimeOffset.MinValue; requestHeaders.Range = new RangeHeaderValue(0, 3); requestHeaders.IfRange = new RangeConditionHeaderValue(new EntityTagHeaderValue("\"Etag\"")); httpContext.Request.Method = HttpMethods.Get; // Act await ExecuteAsync(httpContext, path, "text/plain", entityTag : entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); var contentRange = new ContentRangeHeaderValue(0, 3, 34); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.NotEmpty(httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(4, httpResponse.ContentLength); Assert.Equal(Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")), sendFile.Name); Assert.Equal(0, sendFile.Offset); Assert.Equal(4, sendFile.Length); }
/// <summary> /// Creates the ETag for the given entity. /// </summary> /// <param name="entityInstanceContext">The context for the entity instance being written.</param> /// <returns>The created ETag.</returns> public virtual string CreateETag(EntityInstanceContext entityInstanceContext) { if (entityInstanceContext.Request != null) { HttpConfiguration configuration = entityInstanceContext.Request.GetConfiguration(); if (configuration == null) { throw Error.InvalidOperation(SRResources.RequestMustContainConfiguration); } IEnumerable <IEdmStructuralProperty> concurrencyProperties = entityInstanceContext.EntityType.GetConcurrencyProperties().OrderBy(c => c.Name); IDictionary <string, object> properties = new Dictionary <string, object>(); foreach (IEdmStructuralProperty etagProperty in concurrencyProperties) { properties.Add(etagProperty.Name, entityInstanceContext.GetPropertyValue(etagProperty.Name)); } EntityTagHeaderValue etagHeaderValue = configuration.GetETagHandler().CreateETag(properties); if (etagHeaderValue != null) { return(etagHeaderValue.ToString()); } } return(null); }
/// <inheritdoc/> public override void OnActionExecuted(ActionExecutedContext actionExecutedContext) { if (actionExecutedContext == null) { throw Error.ArgumentNull("actionExecutedContext"); } // Need a value to operate on. ObjectResult result = actionExecutedContext.Result as ObjectResult; if (result == null) { return; } HttpResponse response = actionExecutedContext.HttpContext.Response; HttpRequest request = actionExecutedContext.HttpContext.Request; EntityTagHeaderValue etag = GetETag( response?.StatusCode, request.ODataFeature().Path, request.GetModel(), result.Value, request.GetETagHandler()); if (etag != null) { response.Headers["ETag"] = etag.ToString(); } }
public async Task WriteFileAsync_RangeRequested_FileLengthZeroOrNull(long?fileLength) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes(""); var readStream = new MemoryStream(byteArray); fileLength = fileLength ?? 0L; readStream.SetLength(fileLength.Value); var result = new FileStreamResult(readStream, contentType) { LastModified = lastModified, EntityTag = entityTag, }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(0, 5); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]); if (AppContext.TryGetSwitch(FileResultExecutorBase.EnableRangeProcessingSwitch, out var enableRangeProcessingSwitch) && enableRangeProcessingSwitch) { var contentRange = new ContentRangeHeaderValue(byteArray.Length); Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.Empty(body); } else { Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Empty(body); } }
public async Task WriteFileAsync_IfRangeHeaderValid_WritesRangeRequest_IfRangeProcessingOn() { // Arrange var contentType = "text/plain"; var lastModified = DateTimeOffset.MinValue; var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var result = new FileContentResult(byteArray, contentType) { LastModified = lastModified, EntityTag = entityTag }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; requestHeaders.Range = new RangeHeaderValue(0, 4); requestHeaders.IfRange = new RangeConditionHeaderValue(DateTimeOffset.MinValue); httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]); if (AppContext.TryGetSwitch(FileResultExecutorBase.EnableRangeProcessingSwitch, out var enableRangeProcessingSwitch) && enableRangeProcessingSwitch) { Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); var contentRange = new ContentRangeHeaderValue(0, 4, byteArray.Length); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.Equal(5, httpResponse.ContentLength); Assert.Equal("Hello", body); } else { Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal(11, httpResponse.ContentLength); Assert.Equal("Hello World", body); } }
public static async Task WriteFileAsync_PreconditionStateShouldProcess_WritesRangeRequested <TContext>( long?start, long?end, string expectedString, long contentLength, Func <FileContentResult, TContext, Task> function) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var result = new FileContentResult(byteArray, contentType) { LastModified = lastModified, EntityTag = entityTag, EnableRangeProcessing = true, }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)context); // Assert start = start ?? 11 - end; end = start + contentLength - 1; var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); var contentRange = new ContentRangeHeaderValue(start.Value, end.Value, byteArray.Length); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(contentLength, httpResponse.ContentLength); Assert.Equal(expectedString, body); }
public void ToString_UseDifferentETags_AllSerializedCorrectly() { EntityTagHeaderValue etag = new EntityTagHeaderValue("\"e tag\""); Assert.Equal("\"e tag\"", etag.ToString()); etag = new EntityTagHeaderValue("\"e tag\"", true); Assert.Equal("W/\"e tag\"", etag.ToString()); etag = new EntityTagHeaderValue("\"\"", false); Assert.Equal("\"\"", etag.ToString()); }
/// <summary> /// Creates an ETag from concurrency property names and values. /// </summary> /// <param name="properties">The input property names and values.</param> /// <returns>The generated ETag string.</returns> public string CreateETag(IDictionary <string, object> properties) { HttpConfiguration configuration = this.innerRequest.GetConfiguration(); if (configuration == null) { throw Error.InvalidOperation(SRResources.RequestMustContainConfiguration); } EntityTagHeaderValue etag = configuration.GetETagHandler().CreateETag(properties); return(etag != null?etag.ToString() : null); }
public void Get(string requestUri, EntityTagHeaderValue e) { var reqUriComposed = $"/{_version}/{requestUri}"; var req = _client.Request(reqUriComposed); if (e != null) { req.Headers.Add("If-None-Match", e.ToString()); } _lastResponse = req.GetAsync(); }
/// <inheritdoc/> public override void OnActionExecuted(ActionExecutedContext actionExecutedContext) { if (actionExecutedContext == null) { throw Error.ArgumentNull(nameof(actionExecutedContext)); } if (actionExecutedContext.HttpContext == null) { throw Error.ArgumentNull("httpContext"); } HttpRequest request = actionExecutedContext.HttpContext.Request; ODataPath path = request.ODataFeature().Path; if (path == null) { throw Error.ArgumentNull("path"); } IEdmModel model = request.GetModel(); if (model == null) { throw Error.ArgumentNull("model"); } IETagHandler etagHandler = request.GetETagHandler(); if (etagHandler == null) { throw Error.ArgumentNull("etagHandler"); } // Need a value to operate on. ObjectResult result = actionExecutedContext.Result as ObjectResult; if (result == null) { return; } HttpResponse response = actionExecutedContext.HttpContext.Response; EntityTagHeaderValue etag = GetETag(response?.StatusCode, path, model, result.Value, etagHandler); if (etag != null) { response.Headers["ETag"] = etag.ToString(); } }
public void ContentIsNotModified_IfNoneMatch_ExplicitWithMatch_True(EntityTagHeaderValue responseETag, EntityTagHeaderValue requestETag) { var sink = new TestSink(); var context = TestUtils.CreateTestContext(sink); context.CachedResponseHeaders = new HeaderDictionary(); context.CachedResponseHeaders[HeaderNames.ETag] = responseETag.ToString(); context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = requestETag.ToString(); Assert.True(ResponseCachingMiddleware.ContentIsNotModified(context)); TestUtils.AssertLoggedMessages( sink.Writes, LoggedMessage.NotModifiedIfNoneMatchMatched); }
public async Task WriteFileAsync_PreconditionStateUnspecified_RangeRequestedNotSatisfiable(string rangeString) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var result = new FileContentResult(byteArray, contentType) { LastModified = lastModified, EntityTag = entityTag }; var httpContext = GetHttpContext(); httpContext.Request.Headers[HeaderNames.Range] = rangeString; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(byteArray.Length); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]); if (AppContext.TryGetSwitch(FileResultExecutorBase.EnableRangeProcessingSwitch, out var enableRangeProcessingSwitch) && enableRangeProcessingSwitch) { Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); Assert.Equal(contentRange.ToString(), httpResponse.Headers[HeaderNames.ContentRange]); Assert.Empty(body); } else { Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal("Hello World", body); } }
public async Task WriteFileAsync_IfRangeHeaderInvalid_RangeRequestedIgnored() { // Arrange var contentType = "text/plain"; var lastModified = DateTimeOffset.MinValue.AddDays(1); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var readStream = new MemoryStream(byteArray); readStream.SetLength(11); var result = new FileStreamResult(readStream, contentType) { LastModified = lastModified, EntityTag = entityTag, EnableRangeProcessing = true, }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; requestHeaders.Range = new RangeHeaderValue(0, 4); requestHeaders.IfRange = new RangeConditionHeaderValue(DateTimeOffset.MinValue); httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]); Assert.Equal("Hello World", body); Assert.False(readStream.CanSeek); }
public async Task WriteFileAsync_PreconditionStateShouldProcess_WritesRangeRequested( long?start, long?end, string expectedString, long contentLength) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(start, end); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); // Act await ExecuteAsync(httpContext, byteArray, contentType, lastModified, entityTag, enableRangeProcessing : true); // Assert start = start ?? 11 - end; end = start + contentLength - 1; var httpResponse = httpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); var contentRange = new ContentRangeHeaderValue(start.Value, end.Value, byteArray.Length); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(contentLength, httpResponse.ContentLength); Assert.Equal(expectedString, body); }
public static async Task WriteFileAsync_PreconditionStateUnspecified_RangeRequestedNotSatisfiable <TContext>( string rangeString, Func <FileContentResult, TContext, Task> function) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var result = new FileContentResult(byteArray, contentType) { LastModified = lastModified, EntityTag = entityTag, EnableRangeProcessing = true, }; var httpContext = GetHttpContext(); httpContext.Request.Headers.Range = rangeString; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act object context = typeof(TContext) == typeof(HttpContext) ? httpContext : actionContext; await function(result, (TContext)context); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; var contentRange = new ContentRangeHeaderValue(byteArray.Length); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(0, httpResponse.ContentLength); Assert.Empty(body); }
public async Task WriteFileAsync_RangeRequested_FileLengthZeroOrNull(long?fileLength) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes(""); var readStream = new MemoryStream(byteArray); fileLength = fileLength ?? 0L; readStream.SetLength(fileLength.Value); var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.Range = new RangeHeaderValue(0, 5); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); // Act await ExecuteAsync(httpContext, readStream, contentType, lastModified, entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); var contentRange = new ContentRangeHeaderValue(byteArray.Length); Assert.Equal(StatusCodes.Status416RangeNotSatisfiable, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(0, httpResponse.ContentLength); Assert.Empty(body); Assert.False(readStream.CanSeek); }
public async Task WriteFileAsync_IfRangeHeaderValid_WritesRequestedRange() { // Arrange var contentType = "text/plain"; var lastModified = DateTimeOffset.MinValue; var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var readStream = new MemoryStream(byteArray); readStream.SetLength(11); var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); requestHeaders.IfMatch = new[] { new EntityTagHeaderValue("\"Etag\""), }; requestHeaders.Range = new RangeHeaderValue(0, 4); requestHeaders.IfRange = new RangeConditionHeaderValue(new EntityTagHeaderValue("\"Etag\"")); httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); // Act await ExecuteAsync(httpContext, readStream, contentType, lastModified, entityTag, enableRangeProcessing : true); // Assert var httpResponse = httpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Equal(lastModified.ToString("R"), httpResponse.Headers.LastModified); Assert.Equal(entityTag.ToString(), httpResponse.Headers.ETag); var contentRange = new ContentRangeHeaderValue(0, 4, byteArray.Length); Assert.Equal(StatusCodes.Status206PartialContent, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers.AcceptRanges); Assert.Equal(contentRange.ToString(), httpResponse.Headers.ContentRange); Assert.Equal(5, httpResponse.ContentLength); Assert.Equal("Hello", body); Assert.False(readStream.CanSeek); }
public void Get(string requestUri, EntityTagHeaderValue e) { var reqUriComposed = $"/{_version}/{requestUri}"; var req = _client.Request(reqUriComposed); if (_isAuthenticated) { _authContext.SetAuth(req); } if (e != null) { req.Headers.Add("If-None-Match", e.ToString()); } _lastResponse = req.GetAsync(); _lastResponse.GetAwaiter().GetResult(); }
private bool SetETagResponseHeader(HttpRequest request, HttpResponse response, string responseContent) { bool isReadOnly = request.Method == HttpMethod.Get.Method || request.Method == HttpMethod.Head.Method; if (isReadOnly && response.StatusCode == (int)HttpStatusCode.OK) { string url = request.GetEncodedUrl(); EntityTagHeaderValue responseETag = _eTagGenerator.Generate(url, responseContent); if (responseETag != null) { response.Headers.Add(HeaderNames.ETag, responseETag.ToString()); return(RequestContainsMatchingETag(request.Headers, responseETag)); } } return(false); }
public async Task PreconditionIfMatchFailWeakTest() { // Arrange string entityTag = EntityTag.ToString(); var tmpNewEntityTag = new EntityTagHeaderValue(entityTag, true); Client.DefaultRequestHeaders.Add("If-Match", tmpNewEntityTag.ToString()); // Act HttpResponseMessage response = await Client.GetAsync("/file/physical/true/true"); string responseString = await response.Content.ReadAsStringAsync(); // Assert Assert.Equal(HttpStatusCode.PreconditionFailed, response.StatusCode); Assert.Equal(string.Empty, responseString); Assert.NotEqual("bytes", response.Headers.AcceptRanges.ToString()); Assert.Equal(EntityTag, response.Headers.ETag); Assert.Null(response.Content.Headers.ContentRange); }
public async Task PreconditionIfMatchFailWeakTest() { // Arrange string entityTag = this.EntityTag.ToString(); var tmpNewEntityTag = new EntityTagHeaderValue(entityTag, true); this.Client.DefaultRequestHeaders.Add("If-Match", tmpNewEntityTag.ToString()); // Act HttpResponseMessage response = await this.Client.GetAsync("/test/file/physical/true/true"); string responseString = await response.Content.ReadAsStringAsync(); // Assert Assert.AreEqual(HttpStatusCode.PreconditionFailed, response.StatusCode, "StatusCode != PreconditionFailed"); Assert.AreEqual(string.Empty, responseString, "response is not empty"); Assert.AreNotEqual("bytes", response.Headers.AcceptRanges.ToString(), "AcceptRanges == bytes"); Assert.AreEqual(this.EntityTag, response.Headers.ETag, "ETag != EntityTag"); Assert.IsNull(response.Content.Headers.ContentRange, "Content-Range != null"); Assert.AreEqual("attachment", response.Content.Headers.ContentDisposition.DispositionType, "DispositionType != attachment"); }
/// <summary> /// Creates the ETag for the given entity. /// </summary> /// <param name="entityInstanceContext">The context for the entity instance being written.</param> /// <returns>The created ETag.</returns> public virtual string CreateETag(EntityInstanceContext entityInstanceContext) { if (entityInstanceContext.Request != null) { IEnumerable <IEdmStructuralProperty> concurrencyProperties = entityInstanceContext.EntityType.GetConcurrencyProperties().OrderBy(c => c.Name); IDictionary <string, object> properties = new Dictionary <string, object>(); foreach (IEdmStructuralProperty etagProperty in concurrencyProperties) { properties.Add(etagProperty.Name, entityInstanceContext.GetPropertyValue(etagProperty.Name)); } EntityTagHeaderValue etagHeaderValue = entityInstanceContext.Request.ETagHandler().CreateETag(properties); if (etagHeaderValue != null) { return(etagHeaderValue.ToString()); } } return(null); }
public async Task PreconditionIfNoneMatchSuccessWeakTest() { // Arrange var tmpNewEntityTag = new EntityTagHeaderValue("\"xyzzy\"", true); Client.DefaultRequestHeaders.Add("If-None-Match", tmpNewEntityTag.ToString()); // Act HttpResponseMessage response = await Client.GetAsync("/file/physical/true/true"); response.EnsureSuccessStatusCode(); string responseString = await response.Content.ReadAsStringAsync(); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("0123456789abcdefghijklmnopgrstuvwxyzABCDEFGHIJKLMNOPGRSTUVWXYZ", responseString); Assert.Equal("bytes", response.Headers.AcceptRanges.ToString()); Assert.Equal(EntityTag, response.Headers.ETag); Assert.Null(response.Content.Headers.ContentRange); }
public async Task WriteFileAsync_PreconditionStateUnspecified_RangeRequestIgnored(string rangeString) { // Arrange var contentType = "text/plain"; var lastModified = new DateTimeOffset(); var entityTag = new EntityTagHeaderValue("\"Etag\""); var byteArray = Encoding.ASCII.GetBytes("Hello World"); var readStream = new MemoryStream(byteArray); var result = new FileStreamResult(readStream, contentType) { LastModified = lastModified, EntityTag = entityTag, }; var httpContext = GetHttpContext(); var requestHeaders = httpContext.Request.GetTypedHeaders(); httpContext.Request.Headers[HeaderNames.Range] = rangeString; httpContext.Request.Method = HttpMethods.Get; httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert var httpResponse = actionContext.HttpContext.Response; httpResponse.Body.Seek(0, SeekOrigin.Begin); var streamReader = new StreamReader(httpResponse.Body); var body = streamReader.ReadToEndAsync().Result; Assert.Empty(httpResponse.Headers[HeaderNames.ContentRange]); Assert.Equal(StatusCodes.Status200OK, httpResponse.StatusCode); Assert.Equal("bytes", httpResponse.Headers[HeaderNames.AcceptRanges]); Assert.Equal(lastModified.ToString("R"), httpResponse.Headers[HeaderNames.LastModified]); Assert.Equal(entityTag.ToString(), httpResponse.Headers[HeaderNames.ETag]); Assert.Equal("Hello World", body); }