Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
    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);
    }
Esempio n. 3
0
    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);
            }
        }
Esempio n. 5
0
    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);
    }
Esempio n. 8
0
        /// <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);
        }
Esempio n. 9
0
        /// <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);
            }
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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());
        }
Esempio n. 14
0
        /// <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);
        }
Esempio n. 15
0
        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();
        }
Esempio n. 16
0
        /// <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);
            }
        }
Esempio n. 19
0
        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);
        }
Esempio n. 20
0
    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);
    }
Esempio n. 21
0
        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);
        }
Esempio n. 22
0
        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);
        }
Esempio n. 23
0
        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);
        }
Esempio n. 24
0
        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();
        }
Esempio n. 25
0
        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);
        }
Esempio n. 27
0
        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");
        }
Esempio n. 28
0
        /// <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);
        }
Esempio n. 30
0
        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);
        }