Skip to content
This repository has been archived by the owner on Dec 20, 2018. It is now read-only.

Add Vary: Accept-Encoding if response was compressed #199

Merged
merged 1 commit into from
Jan 20, 2017

Conversation

JunTaoLuo
Copy link
Contributor

@JunTaoLuo JunTaoLuo commented Jan 11, 2017

Fixes #187

@@ -214,6 +214,11 @@ private void OnWrite()
var compressionProvider = ResolveCompressionProvider();
if (compressionProvider != null)
{
if (!HeaderUtilities.ContainsCacheDirective(HeaderNames.Vary, HeaderNames.AcceptEncoding))
{
_context.Response.Headers.Add(HeaderNames.Vary, HeaderNames.AcceptEncoding);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Append or AppendCommaSeperatedValue

@@ -214,6 +214,11 @@ private void OnWrite()
var compressionProvider = ResolveCompressionProvider();
if (compressionProvider != null)
{
if (!HeaderUtilities.ContainsCacheDirective(HeaderNames.Vary, HeaderNames.AcceptEncoding))
Copy link
Contributor Author

@JunTaoLuo JunTaoLuo Jan 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This utility is named poorly but does what is needed which is to scan the values of the headers and see if the specific value, in this case Accept-Encoding, exist. Maybe we need to rename it in HeaderUtilities or at least add a comment here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File a bug for it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually what I said previously isn't accurate, the logic in HeaderUtilities is specific for cache directives. This is because it only handles the cases where the header values are in the format valueName=<someValue>, ... which doesn't generalize to other headers such as Accept where the headers can look like valueName;q=<qValue>, .... For the use case here, the layout of the header value is even simpler since it is a comma separated list of tokens. I'll add a separate helper function.

var containsVaryAcceptEncoding = false;
foreach (var value in response.Headers.GetValues(HeaderNames.Vary))
{
if (value.Contains(HeaderNames.AcceptEncoding))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why a Contains vs. an exact match?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or are you trying to avoid parsing the header into multiple segments?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case either would work since the tests only set one value to the Vary header but in general when we are dealing with headers, we can't just assume each string in StringValues contains one value. We ran into this problem when we received Header["Cache-Control"] = new[] {"no-cache,no-store"} from MVC for example. So it's best to check using contains rather than exact match.

In the same regard, we also shouldn't be assuming the format of the headers. For example, the test could break with a bad Vary header like Headers["Vary"] = new [] {"badValue=Accept-Encoding"} but I ignored this corner case in the tests.

Copy link
Member

@Tratcher Tratcher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you actually tested this together with the caching middleware? Middleware order would matter, you need to make sure this works as expected regardless of which middleware came first. E.g. the vary should only affect caching if the content gets compressed before caching.

@@ -9,12 +9,32 @@
using Microsoft.AspNetCore.Http;
using Moq;
using Xunit;
using Microsoft.Net.Http.Headers;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort

@JunTaoLuo
Copy link
Contributor Author

Tested with the response caching middleware and filed a bug aspnet/ResponseCaching#92. Currently if the response is compressed before being cached, the expected behaviour where the response is cached per accept encoding is observed. If the compression comes after caching, however, the response is still cached per accept encoding. This issue will be fixed in the response caching middleware.

@JunTaoLuo JunTaoLuo changed the title Add Vary: Accept-Encoding if response was compressed WIP Add Vary: Accept-Encoding if response was compressed Jan 19, 2017
@JunTaoLuo JunTaoLuo merged commit 6855f9b into dev Jan 20, 2017
@JunTaoLuo JunTaoLuo deleted the johluo/vary-accept-encoding branch January 20, 2017 23:06
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants