| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |