Bug 960902 - Disallow concurrent HTTP cache read read when validation is needed, r=michal

This commit is contained in:
Honza Bambas 2014-03-06 14:36:20 +01:00
Родитель a6dad90e47
Коммит f90a76df78
1 изменённых файлов: 28 добавлений и 13 удалений

Просмотреть файл

@ -2831,7 +2831,6 @@ nsHttpChannel::OnCacheEntryCheck(nsICacheEntry* entry, nsIApplicationCache* appC
LOG(("Validating based on MustValidate() returning TRUE\n"));
doValidation = true;
}
else if (MustValidateBasedOnQueryUrl()) {
LOG(("Validating based on RFC 2616 section 13.9 "
"(query-url w/o explicit expiration-time)\n"));
@ -2942,21 +2941,37 @@ nsHttpChannel::OnCacheEntryCheck(nsICacheEntry* entry, nsIApplicationCache* appC
(mRequestHead.Method() == nsHttp::Get ||
mRequestHead.Method() == nsHttp::Head) &&
!mCustomConditionalRequest) {
const char *val;
// Add If-Modified-Since header if a Last-Modified was given
// and we are allowed to do this (see bugs 510359 and 269303)
if (canAddImsHeader) {
val = mCachedResponseHead->PeekHeader(nsHttp::Last_Modified);
if (mConcurentCacheAccess) {
// In case of concurrent read and also validation request we
// must wait for the current writer to close the output stream
// first. Otherwise, when the writer's job would have been interrupted
// before all the data were downloaded, we'd have to do a range request
// which would be a second request in line during this channel's
// life-time. nsHttpChannel is not designed to do that, so rather
// turn off concurrent read and wait for entry's completion.
// Then only re-validation or range-re-validation request will go out.
mConcurentCacheAccess = 0;
// This will cause that OnCacheEntryCheck is called again with the same
// entry after the writer is done.
wantCompleteEntry = true;
} else {
const char *val;
// Add If-Modified-Since header if a Last-Modified was given
// and we are allowed to do this (see bugs 510359 and 269303)
if (canAddImsHeader) {
val = mCachedResponseHead->PeekHeader(nsHttp::Last_Modified);
if (val)
mRequestHead.SetHeader(nsHttp::If_Modified_Since,
nsDependentCString(val));
}
// Add If-None-Match header if an ETag was given in the response
val = mCachedResponseHead->PeekHeader(nsHttp::ETag);
if (val)
mRequestHead.SetHeader(nsHttp::If_Modified_Since,
mRequestHead.SetHeader(nsHttp::If_None_Match,
nsDependentCString(val));
mDidReval = true;
}
// Add If-None-Match header if an ETag was given in the response
val = mCachedResponseHead->PeekHeader(nsHttp::ETag);
if (val)
mRequestHead.SetHeader(nsHttp::If_None_Match,
nsDependentCString(val));
mDidReval = true;
}
}