Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HttpKernel] Fix that the Store would not save responses with the X-Content-Digest header present #36833

Merged
merged 1 commit into from May 19, 2020

Conversation

mpdude
Copy link
Contributor

@mpdude mpdude commented May 16, 2020

Q A
Branch? 3.4
Bug fix? yes
New feature? no
Deprecations? no
Tickets
License MIT
Doc PR

Responses fetched from upstream sources might have a X-Content-Digest header, for example if the Symfony Cache is used upstream. This currently prevents the Store from saving such responses. In general, the value of this header should not be trusted.

As I consider this header an implementation detail of the Store, the fix tries to be local to that class; we should not rely on the HttpCache or other classes to remove untrustworthy headers for us.

This fixes the issue that when using the HttpCache in combination with the Symfony HttpClient, responses that have also been cached upstream in an instance of HttpCache are not cached locally. It adds the overhead of re-computing the content digest every time the HttpCache successfully re-validated a response.

@mpdude mpdude force-pushed the cache-upstream-content-digest-34 branch 2 times, most recently from aa18ef9 to 6726bac Compare May 17, 2020 09:44
@nicolas-grekas nicolas-grekas added this to the 3.4 milestone May 18, 2020
@nicolas-grekas nicolas-grekas force-pushed the cache-upstream-content-digest-34 branch from 60512dc to d8964fb Compare May 19, 2020 16:37
@nicolas-grekas
Copy link
Member

Thank you @mpdude.

@nicolas-grekas nicolas-grekas merged commit af0df4c into symfony:3.4 May 19, 2020
@mpdude mpdude deleted the cache-upstream-content-digest-34 branch May 19, 2020 16:48
mpdude added a commit to mpdude/symfony that referenced this pull request Jun 10, 2020
fabpot added a commit that referenced this pull request Jun 11, 2020
…sponse body correctly (mpdude)

This PR was squashed before being merged into the 3.4 branch.

Discussion
----------

[HttpKernel] Fix regression where Store does not return response body correctly

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #37174
| License       | MIT
| Doc PR        |

Since #36833, the `Store` no longer uses or trusts the `X-Content-Digest` header present on a response, since that may come (in the case of using `CachingHttpClient`) from upstream HTTP sources. Instead, the `X-Content-Digest` is re-computed every time a response is written by the `Store`.

Additionally, the `Store` is implemented in a way that when restoring responses, it does _not_ actually load the response body, but just keeps the file path to the content on disk in another internal header called `X-Body-File`. It is up to others (`HttpCache`, for example) to actually load the content from there. For reasons I could not determine, the file path is also set as the response body.

When the `HttpCache` performs revalidations, it may happen that it wants the `Store` to persist a previously restored response. In that case, the `Store` fails to honor its own `X-Body-File` header. Instead, it would compute (since #36833) the `X-Content-Digest`, which now is a hash of the cache file path.

So, we end up with a response that still carries `X-Body-File` for the original, correct response. Since the `HttpCache` honors this value, we don't immediately notice that. But inside the `Store`, the request is now associated with the _new_ (bogus) content entry.

It takes another round of looking up the content in the `Store` to now get a response where the `X-Body-File` _also_ points to the wrong content entry.

Although I feel a bit uncomfortable with trusting headers that seemingly need to be evaluated in different classes and may come from elsewhere, my suggestion is to skip the write inside `Store` if `X-Body-File` and `X-Content-Digest` are both present and consistent with each other.

Additionally, a `file_exists` check could be added to provide additional assertions, at the cost of accessing the filesystem.

Commits
-------

176e769 [HttpKernel] Fix regression where Store does not return response body correctly
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants