Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: content/browser/loader/async_revalidation_manager.cc

Issue 1041993004: content::ResourceDispatcherHostImpl changes for stale-while-revalidate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@s-w-r-yhirano-patch
Patch Set: Remove unnecessary copied comment. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/loader/async_revalidation_manager.h"
6
7 #include <utility>
8
9 #include "base/logging.h"
10 #include "content/browser/loader/async_revalidation_driver.h"
11 #include "content/browser/loader/resource_message_filter.h"
12 #include "content/browser/loader/resource_request_info_impl.h"
13 #include "content/browser/loader/resource_scheduler.h"
14 #include "content/common/resource_messages.h"
15 #include "content/public/browser/resource_throttle.h"
16 #include "net/base/load_flags.h"
17 #include "net/http/http_transaction_factory.h"
18 #include "net/http/http_util.h"
19 #include "net/url_request/url_request.h"
20 #include "net/url_request/url_request_context.h"
21 #include "url/gurl.h"
22
23 namespace content {
24
25 AsyncRevalidationManager::AsyncRevalidationKey::AsyncRevalidationKey(
26 const ResourceContext* resource_context,
27 const net::HttpCache* http_cache,
28 const GURL& url)
29 : resource_context(resource_context),
30 http_cache(http_cache),
31 url_key(net::HttpUtil::SpecForRequest(url)) {}
32
33 AsyncRevalidationManager::AsyncRevalidationKey::AsyncRevalidationKey(
34 const ResourceContext* resource_context)
35 : resource_context(resource_context), http_cache(nullptr), url_key() {}
36
37 AsyncRevalidationManager::AsyncRevalidationKey::~AsyncRevalidationKey() {}
38
39 bool AsyncRevalidationManager::AsyncRevalidationKey::LessThan::operator()(
40 const AsyncRevalidationKey& lhs,
41 const AsyncRevalidationKey& rhs) const {
42 if (lhs.resource_context != rhs.resource_context)
43 return lhs.resource_context < rhs.resource_context;
44
45 if (lhs.http_cache != rhs.http_cache)
46 return lhs.http_cache < rhs.http_cache;
47
48 return lhs.url_key < rhs.url_key;
kinuko 2015/11/19 07:00:29 nit: I think now you could do return std::tie(lhs
Adam Rice 2015/11/19 21:13:52 Done.
49 }
50
51 AsyncRevalidationManager::AsyncRevalidationManager() {}
52
53 AsyncRevalidationManager::~AsyncRevalidationManager() {
54 DCHECK(in_progress_.empty());
55 }
56
57 void AsyncRevalidationManager::BeginAsyncRevalidation(
58 net::URLRequest* for_request,
59 ResourceScheduler* scheduler) {
60 DCHECK_EQ(for_request->url_chain().size(), 1u);
61 ResourceRequestInfoImpl* info =
62 ResourceRequestInfoImpl::ForRequest(for_request);
63 DCHECK(info);
64 if (!info->filter()) {
65 // The child has gone away. Since it never received the body of the stale
66 // resource, it is okay not to perform an async revalidation.
67 return;
68 }
69
70 int child_id = info->GetChildID();
71 int route_id = info->GetRouteID();
72
73 // ResourceMsgFilter::GetContexts requires a ResourceHostMsg_Request object be
74 // passed but only cares about the resource_type field.
75 ResourceHostMsg_Request dummy_resource_host_msg_request;
76 dummy_resource_host_msg_request.resource_type = info->GetResourceType();
77 ResourceContext* resource_context = nullptr;
78 net::URLRequestContext* request_context = nullptr;
79
80 // This |request_context| needs to be valid until
81 // RemoveResourceContext(resource_context) is called. This is currently
82 // correct, see the comment about member variable ordering in
83 // //chrome/browser/profiles/profile_io_data.h.
84 info->filter()->GetContexts(dummy_resource_host_msg_request,
85 &resource_context, &request_context);
86
87 AsyncRevalidationKey async_revalidation_key(
88 resource_context, request_context->http_transaction_factory()->GetCache(),
89 for_request->url());
90 std::pair<AsyncRevalidationMap::iterator, bool> insert_result =
91 in_progress_.insert(
92 AsyncRevalidationMap::value_type(async_revalidation_key, nullptr));
93 if (!insert_result.second) {
94 // A matching async revalidation is already in progress for this cache; we
95 // don't need another one.
96 return;
97 }
98 auto& async_revalidation = insert_result.first->second;
99 DCHECK(async_revalidation == nullptr);
100
101 net::HttpRequestHeaders headers;
102 headers.AddHeadersFromString(info->original_headers());
103
104 // Construct the request.
105 scoped_ptr<net::URLRequest> new_request = request_context->CreateRequest(
106 for_request->url(), net::MINIMUM_PRIORITY, nullptr);
107
108 new_request->set_method(for_request->method());
109 new_request->set_first_party_for_cookies(
110 for_request->first_party_for_cookies());
111 new_request->set_first_party_url_policy(
112 for_request->first_party_url_policy());
113
114 new_request->SetReferrer(for_request->referrer());
115 new_request->set_referrer_policy(for_request->referrer_policy());
116
117 new_request->SetExtraRequestHeaders(headers);
118
119 int load_flags = for_request->load_flags() &
120 ~net::LOAD_SUPPORT_ASYNC_REVALIDATION &
121 ~net::LOAD_MAIN_FRAME;
122 DCHECK_EQ(load_flags & net::LOAD_IGNORE_LIMITS, 0);
123 new_request->SetLoadFlags(load_flags);
124
125 scoped_ptr<ResourceThrottle> throttle =
126 scheduler->ScheduleRequest(child_id, route_id, false, new_request.get());
127 // This use of base::Unretained() is safe because the AsyncRevalidatonDriver
128 // object will be destroyed before this object is. The use of the raw iterator
129 // is safe because objects are only erased from the map after being deleted,
130 // and a deleted AsyncRevalidationDriver will not call the completion
131 // callback.
132 async_revalidation = new AsyncRevalidationDriver(
kinuko 2015/11/19 08:38:34 Hmm it's slightly hard to follow that this is actu
Adam Rice 2015/11/19 21:13:52 Done.
133 new_request.Pass(), throttle.Pass(),
134 base::Bind(&AsyncRevalidationManager::OnAsyncRevalidationComplete,
135 base::Unretained(this), insert_result.first));
136 async_revalidation->StartRequest();
137 }
138
139 void AsyncRevalidationManager::CancelAsyncRevalidationsForResourceContext(
140 ResourceContext* resource_context) {
141 // For this algorithm to work, elements using |resource_context| must be
142 // contiguous in the map (ie. it must form the first part of the key).
143 AsyncRevalidationKey partial_key(resource_context);
144 for (auto it = in_progress_.lower_bound(partial_key);
145 it != in_progress_.end() &&
146 it->first.resource_context == resource_context;) {
147 // It is necessary to delete behind the iterator because an iterator can't
148 // be incremented once it has been removed from the map.
149 auto prev_it = it;
150 ++it;
151 prev_it->second->CancelRequest();
152 delete prev_it->second;
153 in_progress_.erase(prev_it);
154 }
155 }
156
157 bool AsyncRevalidationManager::QualifiesForAsyncRevalidation(
158 const ResourceHostMsg_Request& request) {
159 if (request.load_flags &
160 (net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
161 net::LOAD_VALIDATE_CACHE | net::LOAD_PREFERRING_CACHE |
162 net::LOAD_ONLY_FROM_CACHE | net::LOAD_IGNORE_LIMITS)) {
163 return false;
164 }
165 if (request.method != "GET")
166 return false;
167 // A GET request should not have a body, but don't leave it to chance.
168 if (request.request_body.get())
169 return false;
170 if (!request.url.SchemeIsHTTPOrHTTPS())
171 return false;
172
173 return true;
174 }
175
176 void AsyncRevalidationManager::OnAsyncRevalidationComplete(
177 AsyncRevalidationMap::iterator it) {
178 delete it->second;
179 in_progress_.erase(it);
180 }
181
182 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698