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

Side by Side Diff: net/tools/quic/quic_http_response_cache.cc

Issue 2740453006: Add QuicStringPiece which is actually StringPiece. (Closed)
Patch Set: fix compile error and rebase Created 3 years, 9 months 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/tools/quic/quic_http_response_cache.h" 5 #include "net/tools/quic/quic_http_response_cache.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/files/file_enumerator.h" 9 #include "base/files/file_enumerator.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
11 #include "net/http/http_util.h" 11 #include "net/http/http_util.h"
12 #include "net/quic/platform/api/quic_bug_tracker.h" 12 #include "net/quic/platform/api/quic_bug_tracker.h"
13 #include "net/quic/platform/api/quic_logging.h" 13 #include "net/quic/platform/api/quic_logging.h"
14 #include "net/quic/platform/api/quic_map_util.h" 14 #include "net/quic/platform/api/quic_map_util.h"
15 #include "net/quic/platform/api/quic_ptr_util.h" 15 #include "net/quic/platform/api/quic_ptr_util.h"
16 #include "net/quic/platform/api/quic_text_utils.h" 16 #include "net/quic/platform/api/quic_text_utils.h"
17 #include "net/spdy/spdy_http_utils.h" 17 #include "net/spdy/spdy_http_utils.h"
18 18
19 using base::FilePath; 19 using base::FilePath;
20 using base::IntToString; 20 using base::IntToString;
21 using base::StringPiece;
22 using std::string; 21 using std::string;
23 22
24 namespace net { 23 namespace net {
25 24
26 QuicHttpResponseCache::ServerPushInfo::ServerPushInfo(QuicUrl request_url, 25 QuicHttpResponseCache::ServerPushInfo::ServerPushInfo(QuicUrl request_url,
27 SpdyHeaderBlock headers, 26 SpdyHeaderBlock headers,
28 SpdyPriority priority, 27 SpdyPriority priority,
29 string body) 28 string body)
30 : request_url(request_url), 29 : request_url(request_url),
31 headers(std::move(headers)), 30 headers(std::move(headers)),
(...skipping 28 matching lines...) Expand all
60 if (pos == string::npos) { 59 if (pos == string::npos) {
61 QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: " 60 QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: "
62 << file_name_.value(); 61 << file_name_.value();
63 return; 62 return;
64 } 63 }
65 size_t len = pos - start; 64 size_t len = pos - start;
66 // Support both dos and unix line endings for convenience. 65 // Support both dos and unix line endings for convenience.
67 if (file_contents_[pos - 1] == '\r') { 66 if (file_contents_[pos - 1] == '\r') {
68 len -= 1; 67 len -= 1;
69 } 68 }
70 StringPiece line(file_contents_.data() + start, len); 69 QuicStringPiece line(file_contents_.data() + start, len);
71 start = pos + 1; 70 start = pos + 1;
72 // Headers end with an empty line. 71 // Headers end with an empty line.
73 if (line.empty()) { 72 if (line.empty()) {
74 break; 73 break;
75 } 74 }
76 // Extract the status from the HTTP first line. 75 // Extract the status from the HTTP first line.
77 if (line.substr(0, 4) == "HTTP") { 76 if (line.substr(0, 4) == "HTTP") {
78 pos = line.find(" "); 77 pos = line.find(" ");
79 if (pos == string::npos) { 78 if (pos == string::npos) {
80 QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: " 79 QUIC_LOG(DFATAL) << "Headers invalid or empty, ignoring: "
(...skipping 22 matching lines...) Expand all
103 if (it != spdy_headers_.end()) { 102 if (it != spdy_headers_.end()) {
104 x_original_url_ = it->second; 103 x_original_url_ = it->second;
105 HandleXOriginalUrl(); 104 HandleXOriginalUrl();
106 } 105 }
107 106
108 // X-Push-URL header is a relatively quick way to support sever push 107 // X-Push-URL header is a relatively quick way to support sever push
109 // in the toy server. A production server should use link=preload 108 // in the toy server. A production server should use link=preload
110 // stuff as described in https://w3c.github.io/preload/. 109 // stuff as described in https://w3c.github.io/preload/.
111 it = spdy_headers_.find("x-push-url"); 110 it = spdy_headers_.find("x-push-url");
112 if (it != spdy_headers_.end()) { 111 if (it != spdy_headers_.end()) {
113 StringPiece push_urls = it->second; 112 QuicStringPiece push_urls = it->second;
114 size_t start = 0; 113 size_t start = 0;
115 while (start < push_urls.length()) { 114 while (start < push_urls.length()) {
116 size_t pos = push_urls.find('\0', start); 115 size_t pos = push_urls.find('\0', start);
117 if (pos == string::npos) { 116 if (pos == string::npos) {
118 push_urls_.push_back( 117 push_urls_.push_back(QuicStringPiece(push_urls.data() + start,
119 StringPiece(push_urls.data() + start, push_urls.length() - start)); 118 push_urls.length() - start));
120 break; 119 break;
121 } 120 }
122 push_urls_.push_back(StringPiece(push_urls.data() + start, pos)); 121 push_urls_.push_back(QuicStringPiece(push_urls.data() + start, pos));
123 start += pos + 1; 122 start += pos + 1;
124 } 123 }
125 } 124 }
126 125
127 body_ = 126 body_ = QuicStringPiece(file_contents_.data() + start,
128 StringPiece(file_contents_.data() + start, file_contents_.size() - start); 127 file_contents_.size() - start);
129 } 128 }
130 129
131 void QuicHttpResponseCache::ResourceFile::SetHostPathFromBase( 130 void QuicHttpResponseCache::ResourceFile::SetHostPathFromBase(
132 StringPiece base) { 131 QuicStringPiece base) {
133 size_t path_start = base.find_first_of('/'); 132 size_t path_start = base.find_first_of('/');
134 DCHECK_LT(0UL, path_start); 133 DCHECK_LT(0UL, path_start);
135 host_ = base.substr(0, path_start); 134 host_ = base.substr(0, path_start);
136 size_t query_start = base.find_first_of(','); 135 size_t query_start = base.find_first_of(',');
137 if (query_start > 0) { 136 if (query_start > 0) {
138 path_ = base.substr(path_start, query_start - 1); 137 path_ = base.substr(path_start, query_start - 1);
139 } else { 138 } else {
140 path_ = base.substr(path_start); 139 path_ = base.substr(path_start);
141 } 140 }
142 } 141 }
143 142
144 StringPiece QuicHttpResponseCache::ResourceFile::RemoveScheme(StringPiece url) { 143 QuicStringPiece QuicHttpResponseCache::ResourceFile::RemoveScheme(
144 QuicStringPiece url) {
145 if (QuicTextUtils::StartsWith(url, "https://")) { 145 if (QuicTextUtils::StartsWith(url, "https://")) {
146 url.remove_prefix(8); 146 url.remove_prefix(8);
147 } else if (QuicTextUtils::StartsWith(url, "http://")) { 147 } else if (QuicTextUtils::StartsWith(url, "http://")) {
148 url.remove_prefix(7); 148 url.remove_prefix(7);
149 } 149 }
150 return url; 150 return url;
151 } 151 }
152 152
153 void QuicHttpResponseCache::ResourceFile::HandleXOriginalUrl() { 153 void QuicHttpResponseCache::ResourceFile::HandleXOriginalUrl() {
154 StringPiece url(x_original_url_); 154 QuicStringPiece url(x_original_url_);
155 // Remove the protocol so we can add it below. 155 // Remove the protocol so we can add it below.
156 url = RemoveScheme(url); 156 url = RemoveScheme(url);
157 SetHostPathFromBase(url); 157 SetHostPathFromBase(url);
158 } 158 }
159 159
160 const QuicHttpResponseCache::Response* QuicHttpResponseCache::GetResponse( 160 const QuicHttpResponseCache::Response* QuicHttpResponseCache::GetResponse(
161 StringPiece host, 161 QuicStringPiece host,
162 StringPiece path) const { 162 QuicStringPiece path) const {
163 QuicWriterMutexLock lock(&response_mutex_); 163 QuicWriterMutexLock lock(&response_mutex_);
164 164
165 auto it = responses_.find(GetKey(host, path)); 165 auto it = responses_.find(GetKey(host, path));
166 if (it == responses_.end()) { 166 if (it == responses_.end()) {
167 DVLOG(1) << "Get response for resource failed: host " << host << " path " 167 DVLOG(1) << "Get response for resource failed: host " << host << " path "
168 << path; 168 << path;
169 if (default_response_.get()) { 169 if (default_response_.get()) {
170 return default_response_.get(); 170 return default_response_.get();
171 } 171 }
172 return nullptr; 172 return nullptr;
173 } 173 }
174 return it->second.get(); 174 return it->second.get();
175 } 175 }
176 176
177 typedef QuicHttpResponseCache::ServerPushInfo ServerPushInfo; 177 typedef QuicHttpResponseCache::ServerPushInfo ServerPushInfo;
178 178
179 void QuicHttpResponseCache::AddSimpleResponse(StringPiece host, 179 void QuicHttpResponseCache::AddSimpleResponse(QuicStringPiece host,
180 StringPiece path, 180 QuicStringPiece path,
181 int response_code, 181 int response_code,
182 StringPiece body) { 182 QuicStringPiece body) {
183 SpdyHeaderBlock response_headers; 183 SpdyHeaderBlock response_headers;
184 response_headers[":status"] = QuicTextUtils::Uint64ToString(response_code); 184 response_headers[":status"] = QuicTextUtils::Uint64ToString(response_code);
185 response_headers["content-length"] = 185 response_headers["content-length"] =
186 QuicTextUtils::Uint64ToString(body.length()); 186 QuicTextUtils::Uint64ToString(body.length());
187 AddResponse(host, path, std::move(response_headers), body); 187 AddResponse(host, path, std::move(response_headers), body);
188 } 188 }
189 189
190 void QuicHttpResponseCache::AddSimpleResponseWithServerPushResources( 190 void QuicHttpResponseCache::AddSimpleResponseWithServerPushResources(
191 StringPiece host, 191 QuicStringPiece host,
192 StringPiece path, 192 QuicStringPiece path,
193 int response_code, 193 int response_code,
194 StringPiece body, 194 QuicStringPiece body,
195 std::list<ServerPushInfo> push_resources) { 195 std::list<ServerPushInfo> push_resources) {
196 AddSimpleResponse(host, path, response_code, body); 196 AddSimpleResponse(host, path, response_code, body);
197 MaybeAddServerPushResources(host, path, push_resources); 197 MaybeAddServerPushResources(host, path, push_resources);
198 } 198 }
199 199
200 void QuicHttpResponseCache::AddDefaultResponse(Response* response) { 200 void QuicHttpResponseCache::AddDefaultResponse(Response* response) {
201 QuicWriterMutexLock lock(&response_mutex_); 201 QuicWriterMutexLock lock(&response_mutex_);
202 default_response_.reset(response); 202 default_response_.reset(response);
203 } 203 }
204 204
205 void QuicHttpResponseCache::AddResponse(StringPiece host, 205 void QuicHttpResponseCache::AddResponse(QuicStringPiece host,
206 StringPiece path, 206 QuicStringPiece path,
207 SpdyHeaderBlock response_headers, 207 SpdyHeaderBlock response_headers,
208 StringPiece response_body) { 208 QuicStringPiece response_body) {
209 AddResponseImpl(host, path, REGULAR_RESPONSE, std::move(response_headers), 209 AddResponseImpl(host, path, REGULAR_RESPONSE, std::move(response_headers),
210 response_body, SpdyHeaderBlock()); 210 response_body, SpdyHeaderBlock());
211 } 211 }
212 212
213 void QuicHttpResponseCache::AddResponse(StringPiece host, 213 void QuicHttpResponseCache::AddResponse(QuicStringPiece host,
214 StringPiece path, 214 QuicStringPiece path,
215 SpdyHeaderBlock response_headers, 215 SpdyHeaderBlock response_headers,
216 StringPiece response_body, 216 QuicStringPiece response_body,
217 SpdyHeaderBlock response_trailers) { 217 SpdyHeaderBlock response_trailers) {
218 AddResponseImpl(host, path, REGULAR_RESPONSE, std::move(response_headers), 218 AddResponseImpl(host, path, REGULAR_RESPONSE, std::move(response_headers),
219 response_body, std::move(response_trailers)); 219 response_body, std::move(response_trailers));
220 } 220 }
221 221
222 void QuicHttpResponseCache::AddSpecialResponse( 222 void QuicHttpResponseCache::AddSpecialResponse(
223 StringPiece host, 223 QuicStringPiece host,
224 StringPiece path, 224 QuicStringPiece path,
225 SpecialResponseType response_type) { 225 SpecialResponseType response_type) {
226 AddResponseImpl(host, path, response_type, SpdyHeaderBlock(), "", 226 AddResponseImpl(host, path, response_type, SpdyHeaderBlock(), "",
227 SpdyHeaderBlock()); 227 SpdyHeaderBlock());
228 } 228 }
229 229
230 QuicHttpResponseCache::QuicHttpResponseCache() {} 230 QuicHttpResponseCache::QuicHttpResponseCache() {}
231 231
232 void QuicHttpResponseCache::InitializeFromDirectory( 232 void QuicHttpResponseCache::InitializeFromDirectory(
233 const string& cache_directory) { 233 const string& cache_directory) {
234 if (cache_directory.empty()) { 234 if (cache_directory.empty()) {
235 QUIC_BUG << "cache_directory must not be empty."; 235 QUIC_BUG << "cache_directory must not be empty.";
236 return; 236 return;
237 } 237 }
238 QUIC_LOG(INFO) 238 QUIC_LOG(INFO)
239 << "Attempting to initialize QuicHttpResponseCache from directory: " 239 << "Attempting to initialize QuicHttpResponseCache from directory: "
240 << cache_directory; 240 << cache_directory;
241 FilePath directory(FilePath::FromUTF8Unsafe(cache_directory)); 241 FilePath directory(FilePath::FromUTF8Unsafe(cache_directory));
242 base::FileEnumerator file_list(directory, true, base::FileEnumerator::FILES); 242 base::FileEnumerator file_list(directory, true, base::FileEnumerator::FILES);
243 std::list<std::unique_ptr<ResourceFile>> resource_files; 243 std::list<std::unique_ptr<ResourceFile>> resource_files;
244 for (FilePath file_iter = file_list.Next(); !file_iter.empty(); 244 for (FilePath file_iter = file_list.Next(); !file_iter.empty();
245 file_iter = file_list.Next()) { 245 file_iter = file_list.Next()) {
246 // Need to skip files in .svn directories 246 // Need to skip files in .svn directories
247 if (file_iter.value().find(FILE_PATH_LITERAL("/.svn/")) != string::npos) { 247 if (file_iter.value().find(FILE_PATH_LITERAL("/.svn/")) != string::npos) {
248 continue; 248 continue;
249 } 249 }
250 250
251 std::unique_ptr<ResourceFile> resource_file(new ResourceFile(file_iter)); 251 std::unique_ptr<ResourceFile> resource_file(new ResourceFile(file_iter));
252 252
253 // Tease apart filename into host and path. 253 // Tease apart filename into host and path.
254 StringPiece base(resource_file->file_name()); 254 QuicStringPiece base(resource_file->file_name());
255 base.remove_prefix(cache_directory.length()); 255 base.remove_prefix(cache_directory.length());
256 if (base[0] == '/') { 256 if (base[0] == '/') {
257 base.remove_prefix(1); 257 base.remove_prefix(1);
258 } 258 }
259 259
260 resource_file->SetHostPathFromBase(base); 260 resource_file->SetHostPathFromBase(base);
261 resource_file->Read(); 261 resource_file->Read();
262 262
263 AddResponse(resource_file->host(), resource_file->path(), 263 AddResponse(resource_file->host(), resource_file->path(),
264 resource_file->spdy_headers().Clone(), resource_file->body()); 264 resource_file->spdy_headers().Clone(), resource_file->body());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 return resources; 298 return resources;
299 } 299 }
300 300
301 QuicHttpResponseCache::~QuicHttpResponseCache() { 301 QuicHttpResponseCache::~QuicHttpResponseCache() {
302 { 302 {
303 QuicWriterMutexLock lock(&response_mutex_); 303 QuicWriterMutexLock lock(&response_mutex_);
304 responses_.clear(); 304 responses_.clear();
305 } 305 }
306 } 306 }
307 307
308 void QuicHttpResponseCache::AddResponseImpl(StringPiece host, 308 void QuicHttpResponseCache::AddResponseImpl(QuicStringPiece host,
309 StringPiece path, 309 QuicStringPiece path,
310 SpecialResponseType response_type, 310 SpecialResponseType response_type,
311 SpdyHeaderBlock response_headers, 311 SpdyHeaderBlock response_headers,
312 StringPiece response_body, 312 QuicStringPiece response_body,
313 SpdyHeaderBlock response_trailers) { 313 SpdyHeaderBlock response_trailers) {
314 QuicWriterMutexLock lock(&response_mutex_); 314 QuicWriterMutexLock lock(&response_mutex_);
315 315
316 DCHECK(!host.empty()) << "Host must be populated, e.g. \"www.google.com\""; 316 DCHECK(!host.empty()) << "Host must be populated, e.g. \"www.google.com\"";
317 string key = GetKey(host, path); 317 string key = GetKey(host, path);
318 if (QuicContainsKey(responses_, key)) { 318 if (QuicContainsKey(responses_, key)) {
319 QUIC_BUG << "Response for '" << key << "' already exists!"; 319 QUIC_BUG << "Response for '" << key << "' already exists!";
320 return; 320 return;
321 } 321 }
322 auto new_response = QuicMakeUnique<Response>(); 322 auto new_response = QuicMakeUnique<Response>();
323 new_response->set_response_type(response_type); 323 new_response->set_response_type(response_type);
324 new_response->set_headers(std::move(response_headers)); 324 new_response->set_headers(std::move(response_headers));
325 new_response->set_body(response_body); 325 new_response->set_body(response_body);
326 new_response->set_trailers(std::move(response_trailers)); 326 new_response->set_trailers(std::move(response_trailers));
327 QUIC_DVLOG(1) << "Add response with key " << key; 327 QUIC_DVLOG(1) << "Add response with key " << key;
328 responses_[key] = std::move(new_response); 328 responses_[key] = std::move(new_response);
329 } 329 }
330 330
331 string QuicHttpResponseCache::GetKey(StringPiece host, StringPiece path) const { 331 string QuicHttpResponseCache::GetKey(QuicStringPiece host,
332 QuicStringPiece path) const {
332 return host.as_string() + path.as_string(); 333 return host.as_string() + path.as_string();
333 } 334 }
334 335
335 void QuicHttpResponseCache::MaybeAddServerPushResources( 336 void QuicHttpResponseCache::MaybeAddServerPushResources(
336 StringPiece request_host, 337 QuicStringPiece request_host,
337 StringPiece request_path, 338 QuicStringPiece request_path,
338 std::list<ServerPushInfo> push_resources) { 339 std::list<ServerPushInfo> push_resources) {
339 string request_url = GetKey(request_host, request_path); 340 string request_url = GetKey(request_host, request_path);
340 341
341 for (const auto& push_resource : push_resources) { 342 for (const auto& push_resource : push_resources) {
342 if (PushResourceExistsInCache(request_url, push_resource)) { 343 if (PushResourceExistsInCache(request_url, push_resource)) {
343 continue; 344 continue;
344 } 345 }
345 346
346 QUIC_DVLOG(1) << "Add request-resource association: request url " 347 QUIC_DVLOG(1) << "Add request-resource association: request url "
347 << request_url << " push url " 348 << request_url << " push url "
348 << push_resource.request_url.ToString() 349 << push_resource.request_url.ToString()
349 << " response headers " 350 << " response headers "
350 << push_resource.headers.DebugString(); 351 << push_resource.headers.DebugString();
351 { 352 {
352 QuicWriterMutexLock lock(&response_mutex_); 353 QuicWriterMutexLock lock(&response_mutex_);
353 server_push_resources_.insert(std::make_pair(request_url, push_resource)); 354 server_push_resources_.insert(std::make_pair(request_url, push_resource));
354 } 355 }
355 string host = push_resource.request_url.host(); 356 string host = push_resource.request_url.host();
356 if (host.empty()) { 357 if (host.empty()) {
357 host = request_host.as_string(); 358 host = request_host.as_string();
358 } 359 }
359 string path = push_resource.request_url.path(); 360 string path = push_resource.request_url.path();
360 bool found_existing_response = false; 361 bool found_existing_response = false;
361 { 362 {
362 QuicWriterMutexLock lock(&response_mutex_); 363 QuicWriterMutexLock lock(&response_mutex_);
363 found_existing_response = QuicContainsKey(responses_, GetKey(host, path)); 364 found_existing_response = QuicContainsKey(responses_, GetKey(host, path));
364 } 365 }
365 if (!found_existing_response) { 366 if (!found_existing_response) {
366 // Add a server push response to responses map, if it is not in the map. 367 // Add a server push response to responses map, if it is not in the map.
367 StringPiece body = push_resource.body; 368 QuicStringPiece body = push_resource.body;
368 QUIC_DVLOG(1) << "Add response for push resource: host " << host 369 QUIC_DVLOG(1) << "Add response for push resource: host " << host
369 << " path " << path; 370 << " path " << path;
370 AddResponse(host, path, push_resource.headers.Clone(), body); 371 AddResponse(host, path, push_resource.headers.Clone(), body);
371 } 372 }
372 } 373 }
373 } 374 }
374 375
375 bool QuicHttpResponseCache::PushResourceExistsInCache( 376 bool QuicHttpResponseCache::PushResourceExistsInCache(
376 string original_request_url, 377 string original_request_url,
377 ServerPushInfo resource) { 378 ServerPushInfo resource) {
378 QuicWriterMutexLock lock(&response_mutex_); 379 QuicWriterMutexLock lock(&response_mutex_);
379 auto resource_range = 380 auto resource_range =
380 server_push_resources_.equal_range(original_request_url); 381 server_push_resources_.equal_range(original_request_url);
381 for (auto it = resource_range.first; it != resource_range.second; ++it) { 382 for (auto it = resource_range.first; it != resource_range.second; ++it) {
382 ServerPushInfo push_resource = it->second; 383 ServerPushInfo push_resource = it->second;
383 if (push_resource.request_url.ToString() == 384 if (push_resource.request_url.ToString() ==
384 resource.request_url.ToString()) { 385 resource.request_url.ToString()) {
385 return true; 386 return true;
386 } 387 }
387 } 388 }
388 return false; 389 return false;
389 } 390 }
390 391
391 } // namespace net 392 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/quic/quic_http_response_cache.h ('k') | net/tools/quic/quic_http_response_cache_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698