OLD | NEW |
1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2010 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/http/http_cache_transaction.h" | 5 #include "net/http/http_cache_transaction.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 | 8 |
9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 DCHECK(!callback_); | 165 DCHECK(!callback_); |
166 DCHECK(!reading_); | 166 DCHECK(!reading_); |
167 DCHECK(!network_trans_.get()); | 167 DCHECK(!network_trans_.get()); |
168 DCHECK(!entry_); | 168 DCHECK(!entry_); |
169 | 169 |
170 if (!cache_) | 170 if (!cache_) |
171 return ERR_UNEXPECTED; | 171 return ERR_UNEXPECTED; |
172 | 172 |
173 SetRequest(net_log, request); | 173 SetRequest(net_log, request); |
174 | 174 |
175 int rv; | 175 // We have to wait until the backend is initialized so we start the SM. |
176 | 176 next_state_ = STATE_GET_BACKEND; |
177 if (!ShouldPassThrough()) { | 177 int rv = DoLoop(OK); |
178 cache_key_ = cache_->GenerateCacheKey(request); | |
179 | |
180 // Requested cache access mode. | |
181 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { | |
182 mode_ = READ; | |
183 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { | |
184 mode_ = WRITE; | |
185 } else { | |
186 mode_ = READ_WRITE; | |
187 } | |
188 | |
189 // Downgrade to UPDATE if the request has been externally conditionalized. | |
190 if (external_validation_.initialized) { | |
191 if (mode_ & WRITE) { | |
192 // Strip off the READ_DATA bit (and maybe add back a READ_META bit | |
193 // in case READ was off). | |
194 mode_ = UPDATE; | |
195 } else { | |
196 mode_ = NONE; | |
197 } | |
198 } | |
199 } | |
200 | |
201 // If must use cache, then we must fail. This can happen for back/forward | |
202 // navigations to a page generated via a form post. | |
203 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) | |
204 return ERR_CACHE_MISS; | |
205 | |
206 if (mode_ == NONE) { | |
207 if (partial_.get()) | |
208 partial_->RestoreHeaders(&custom_request_->extra_headers); | |
209 rv = BeginNetworkRequest(); | |
210 } else { | |
211 rv = AddToEntry(); | |
212 } | |
213 | 178 |
214 // Setting this here allows us to check for the existance of a callback_ to | 179 // Setting this here allows us to check for the existance of a callback_ to |
215 // determine if we are still inside Start. | 180 // determine if we are still inside Start. |
216 if (rv == ERR_IO_PENDING) | 181 if (rv == ERR_IO_PENDING) |
217 callback_ = callback; | 182 callback_ = callback; |
218 | 183 |
219 return rv; | 184 return rv; |
220 } | 185 } |
221 | 186 |
222 int HttpCache::Transaction::RestartIgnoringLastError( | 187 int HttpCache::Transaction::RestartIgnoringLastError( |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 } | 386 } |
422 | 387 |
423 int HttpCache::Transaction::DoLoop(int result) { | 388 int HttpCache::Transaction::DoLoop(int result) { |
424 DCHECK(next_state_ != STATE_NONE); | 389 DCHECK(next_state_ != STATE_NONE); |
425 | 390 |
426 int rv = result; | 391 int rv = result; |
427 do { | 392 do { |
428 State state = next_state_; | 393 State state = next_state_; |
429 next_state_ = STATE_NONE; | 394 next_state_ = STATE_NONE; |
430 switch (state) { | 395 switch (state) { |
| 396 case STATE_GET_BACKEND: |
| 397 DCHECK_EQ(OK, rv); |
| 398 rv = DoGetBackend(); |
| 399 break; |
| 400 case STATE_GET_BACKEND_COMPLETE: |
| 401 rv = DoGetBackendComplete(rv); |
| 402 break; |
431 case STATE_SEND_REQUEST: | 403 case STATE_SEND_REQUEST: |
432 DCHECK_EQ(OK, rv); | 404 DCHECK_EQ(OK, rv); |
433 rv = DoSendRequest(); | 405 rv = DoSendRequest(); |
434 break; | 406 break; |
435 case STATE_SEND_REQUEST_COMPLETE: | 407 case STATE_SEND_REQUEST_COMPLETE: |
436 rv = DoSendRequestComplete(rv); | 408 rv = DoSendRequestComplete(rv); |
437 break; | 409 break; |
438 case STATE_SUCCESSFUL_SEND_REQUEST: | 410 case STATE_SUCCESSFUL_SEND_REQUEST: |
439 DCHECK_EQ(OK, rv); | 411 DCHECK_EQ(OK, rv); |
440 rv = DoSuccessfulSendRequest(); | 412 rv = DoSuccessfulSendRequest(); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 break; | 527 break; |
556 } | 528 } |
557 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 529 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
558 | 530 |
559 if (rv != ERR_IO_PENDING) | 531 if (rv != ERR_IO_PENDING) |
560 HandleResult(rv); | 532 HandleResult(rv); |
561 | 533 |
562 return rv; | 534 return rv; |
563 } | 535 } |
564 | 536 |
| 537 int HttpCache::Transaction::DoGetBackend() { |
| 538 cache_pending_ = true; |
| 539 next_state_ = STATE_GET_BACKEND_COMPLETE; |
| 540 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WAITING, NULL); |
| 541 return cache_->GetBackendForTransaction(this); |
| 542 } |
| 543 |
| 544 int HttpCache::Transaction::DoGetBackendComplete(int result) { |
| 545 DCHECK(result == OK || result == ERR_FAILED); |
| 546 net_log_.EndEvent(NetLog::TYPE_HTTP_CACHE_WAITING, NULL); |
| 547 cache_pending_ = false; |
| 548 |
| 549 if (!ShouldPassThrough()) { |
| 550 cache_key_ = cache_->GenerateCacheKey(request_); |
| 551 |
| 552 // Requested cache access mode. |
| 553 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { |
| 554 mode_ = READ; |
| 555 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { |
| 556 mode_ = WRITE; |
| 557 } else { |
| 558 mode_ = READ_WRITE; |
| 559 } |
| 560 |
| 561 // Downgrade to UPDATE if the request has been externally conditionalized. |
| 562 if (external_validation_.initialized) { |
| 563 if (mode_ & WRITE) { |
| 564 // Strip off the READ_DATA bit (and maybe add back a READ_META bit |
| 565 // in case READ was off). |
| 566 mode_ = UPDATE; |
| 567 } else { |
| 568 mode_ = NONE; |
| 569 } |
| 570 } |
| 571 } |
| 572 |
| 573 // If must use cache, then we must fail. This can happen for back/forward |
| 574 // navigations to a page generated via a form post. |
| 575 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) |
| 576 return ERR_CACHE_MISS; |
| 577 |
| 578 if (mode_ == NONE) { |
| 579 if (partial_.get()) |
| 580 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 581 next_state_ = STATE_SEND_REQUEST; |
| 582 } else { |
| 583 next_state_ = STATE_INIT_ENTRY; |
| 584 } |
| 585 |
| 586 return OK; |
| 587 } |
| 588 |
565 int HttpCache::Transaction::DoSendRequest() { | 589 int HttpCache::Transaction::DoSendRequest() { |
566 DCHECK(mode_ & WRITE || mode_ == NONE); | 590 DCHECK(mode_ & WRITE || mode_ == NONE); |
567 DCHECK(!network_trans_.get()); | 591 DCHECK(!network_trans_.get()); |
568 | 592 |
569 // Create a network transaction. | 593 // Create a network transaction. |
570 int rv = cache_->network_layer_->CreateTransaction(&network_trans_); | 594 int rv = cache_->network_layer_->CreateTransaction(&network_trans_); |
571 if (rv != OK) | 595 if (rv != OK) |
572 return rv; | 596 return rv; |
573 | 597 |
574 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 598 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 return OK; | 919 return OK; |
896 } | 920 } |
897 | 921 |
898 // We change the value of Content-Length for partial content. | 922 // We change the value of Content-Length for partial content. |
899 if (server_responded_206_ && partial_.get()) | 923 if (server_responded_206_ && partial_.get()) |
900 partial_->FixContentLength(new_response_->headers); | 924 partial_->FixContentLength(new_response_->headers); |
901 | 925 |
902 response_ = *new_response_; | 926 response_ = *new_response_; |
903 target_state_ = STATE_TRUNCATE_CACHED_DATA; | 927 target_state_ = STATE_TRUNCATE_CACHED_DATA; |
904 next_state_ = truncated_ ? STATE_CACHE_WRITE_TRUNCATED_RESPONSE : | 928 next_state_ = truncated_ ? STATE_CACHE_WRITE_TRUNCATED_RESPONSE : |
905 STATE_CACHE_WRITE_RESPONSE; | 929 STATE_CACHE_WRITE_RESPONSE; |
906 return OK; | 930 return OK; |
907 } | 931 } |
908 | 932 |
909 int HttpCache::Transaction::DoTruncateCachedData() { | 933 int HttpCache::Transaction::DoTruncateCachedData() { |
910 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; | 934 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE; |
911 if (!entry_) | 935 if (!entry_) |
912 return OK; | 936 return OK; |
913 | 937 |
914 // Truncate the stream. | 938 // Truncate the stream. |
915 int rv = WriteToEntry(kResponseContentIndex, 0, NULL, 0, NULL); | 939 int rv = WriteToEntry(kResponseContentIndex, 0, NULL, 0, NULL); |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 return false; | 1285 return false; |
1262 | 1286 |
1263 if (request_->method == "POST" && | 1287 if (request_->method == "POST" && |
1264 request_->upload_data && request_->upload_data->identifier()) | 1288 request_->upload_data && request_->upload_data->identifier()) |
1265 return false; | 1289 return false; |
1266 | 1290 |
1267 // TODO(darin): add support for caching HEAD responses | 1291 // TODO(darin): add support for caching HEAD responses |
1268 return true; | 1292 return true; |
1269 } | 1293 } |
1270 | 1294 |
1271 int HttpCache::Transaction::AddToEntry() { | |
1272 next_state_ = STATE_INIT_ENTRY; | |
1273 cache_pending_ = false; | |
1274 return DoLoop(OK); | |
1275 } | |
1276 | |
1277 int HttpCache::Transaction::BeginCacheRead() { | 1295 int HttpCache::Transaction::BeginCacheRead() { |
1278 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges. | 1296 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges. |
1279 if (response_.headers->response_code() == 206 || partial_.get()) { | 1297 if (response_.headers->response_code() == 206 || partial_.get()) { |
1280 NOTREACHED(); | 1298 NOTREACHED(); |
1281 return ERR_CACHE_MISS; | 1299 return ERR_CACHE_MISS; |
1282 } | 1300 } |
1283 | 1301 |
1284 // We don't have the whole resource. | 1302 // We don't have the whole resource. |
1285 if (truncated_) | 1303 if (truncated_) |
1286 return ERR_CACHE_MISS; | 1304 return ERR_CACHE_MISS; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1381 // The externally conditionalized request is not a validation request | 1399 // The externally conditionalized request is not a validation request |
1382 // for our existing cache entry. Proceed with caching disabled. | 1400 // for our existing cache entry. Proceed with caching disabled. |
1383 DoneWritingToEntry(true); | 1401 DoneWritingToEntry(true); |
1384 } | 1402 } |
1385 } | 1403 } |
1386 | 1404 |
1387 next_state_ = STATE_SEND_REQUEST; | 1405 next_state_ = STATE_SEND_REQUEST; |
1388 return OK; | 1406 return OK; |
1389 } | 1407 } |
1390 | 1408 |
1391 int HttpCache::Transaction::BeginNetworkRequest() { | |
1392 next_state_ = STATE_SEND_REQUEST; | |
1393 return DoLoop(OK); | |
1394 } | |
1395 | |
1396 int HttpCache::Transaction::RestartNetworkRequest() { | 1409 int HttpCache::Transaction::RestartNetworkRequest() { |
1397 DCHECK(mode_ & WRITE || mode_ == NONE); | 1410 DCHECK(mode_ & WRITE || mode_ == NONE); |
1398 DCHECK(network_trans_.get()); | 1411 DCHECK(network_trans_.get()); |
1399 DCHECK_EQ(STATE_NONE, next_state_); | 1412 DCHECK_EQ(STATE_NONE, next_state_); |
1400 | 1413 |
1401 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 1414 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
1402 int rv = network_trans_->RestartIgnoringLastError(&io_callback_); | 1415 int rv = network_trans_->RestartIgnoringLastError(&io_callback_); |
1403 if (rv != ERR_IO_PENDING) | 1416 if (rv != ERR_IO_PENDING) |
1404 return DoLoop(rv); | 1417 return DoLoop(rv); |
1405 return rv; | 1418 return rv; |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1800 // |value| goes from 0 to 63. Actually, the max value should be 47 (0x2f) | 1813 // |value| goes from 0 to 63. Actually, the max value should be 47 (0x2f) |
1801 // but we'll see. | 1814 // but we'll see. |
1802 UMA_HISTOGRAM_ENUMERATION("HttpCache.ResponseHeaders", value, 65); | 1815 UMA_HISTOGRAM_ENUMERATION("HttpCache.ResponseHeaders", value, 65); |
1803 } | 1816 } |
1804 | 1817 |
1805 void HttpCache::Transaction::OnIOComplete(int result) { | 1818 void HttpCache::Transaction::OnIOComplete(int result) { |
1806 DoLoop(result); | 1819 DoLoop(result); |
1807 } | 1820 } |
1808 | 1821 |
1809 } // namespace net | 1822 } // namespace net |
OLD | NEW |