| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2014, Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | |
| 31 #include "core/fetch/FetchContext.h" | |
| 32 #include "core/fetch/ImageResource.h" | |
| 33 #include "core/fetch/MemoryCache.h" | |
| 34 #include "core/fetch/MockFetchContext.h" | |
| 35 #include "core/fetch/RawResource.h" | |
| 36 #include "core/fetch/Resource.h" | |
| 37 #include "core/fetch/ResourceFetcher.h" | |
| 38 #include "platform/network/ResourceRequest.h" | |
| 39 #include "testing/gtest/include/gtest/gtest.h" | |
| 40 #include "wtf/RefPtr.h" | |
| 41 | |
| 42 namespace blink { | |
| 43 | |
| 44 // An URL for the original request. | |
| 45 const char kResourceURL[] = "http://resource.com/"; | |
| 46 | |
| 47 // The origin time of our first request. | |
| 48 const char kOriginalRequestDateAsString[] = "Thu, 25 May 1977 18:30:00 GMT"; | |
| 49 const double kOriginalRequestDateAsDouble = 233433000.; | |
| 50 | |
| 51 const char kOneDayBeforeOriginalRequest[] = "Wed, 24 May 1977 18:30:00 GMT"; | |
| 52 const char kOneDayAfterOriginalRequest[] = "Fri, 26 May 1977 18:30:00 GMT"; | |
| 53 | |
| 54 class CachingCorrectnessTest : public ::testing::Test { | |
| 55 protected: | |
| 56 static void advanceClock(double seconds) { s_timeElapsed += seconds; } | |
| 57 | |
| 58 Resource* resourceFromResourceResponse(ResourceResponse response, | |
| 59 Resource::Type type = Resource::Raw) { | |
| 60 if (response.url().isNull()) | |
| 61 response.setURL(KURL(ParsedURLString, kResourceURL)); | |
| 62 Resource* resource = nullptr; | |
| 63 switch (type) { | |
| 64 case Resource::Raw: | |
| 65 resource = RawResource::create(ResourceRequest(response.url()), type); | |
| 66 break; | |
| 67 case Resource::Image: | |
| 68 resource = ImageResource::create(ResourceRequest(response.url())); | |
| 69 break; | |
| 70 default: | |
| 71 EXPECT_TRUE(false) << "'Unreachable' code was reached"; | |
| 72 return nullptr; | |
| 73 } | |
| 74 resource->setResponse(response); | |
| 75 resource->finish(); | |
| 76 // Because we didn't give any real data, an image will have set its status | |
| 77 // to DecodeError. Override it so the resource is cacaheable for testing | |
| 78 // purposes. | |
| 79 if (type == Resource::Image) | |
| 80 resource->setStatus(Resource::Cached); | |
| 81 memoryCache()->add(resource); | |
| 82 | |
| 83 return resource; | |
| 84 } | |
| 85 | |
| 86 Resource* resourceFromResourceRequest(ResourceRequest request) { | |
| 87 if (request.url().isNull()) | |
| 88 request.setURL(KURL(ParsedURLString, kResourceURL)); | |
| 89 Resource* resource = RawResource::create(request, Resource::Raw); | |
| 90 resource->setResponse(ResourceResponse(KURL(ParsedURLString, kResourceURL), | |
| 91 "text/html", 0, nullAtom, String())); | |
| 92 resource->finish(); | |
| 93 memoryCache()->add(resource); | |
| 94 | |
| 95 return resource; | |
| 96 } | |
| 97 | |
| 98 Resource* fetch() { | |
| 99 ResourceRequest resourceRequest(KURL(ParsedURLString, kResourceURL)); | |
| 100 resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal); | |
| 101 FetchRequest fetchRequest(resourceRequest, FetchInitiatorInfo()); | |
| 102 return RawResource::fetch(fetchRequest, fetcher()); | |
| 103 } | |
| 104 | |
| 105 Resource* fetchImage() { | |
| 106 FetchRequest fetchRequest( | |
| 107 ResourceRequest(KURL(ParsedURLString, kResourceURL)), | |
| 108 FetchInitiatorInfo()); | |
| 109 return ImageResource::fetch(fetchRequest, fetcher()); | |
| 110 } | |
| 111 | |
| 112 ResourceFetcher* fetcher() const { return m_fetcher.get(); } | |
| 113 | |
| 114 private: | |
| 115 static double returnMockTime() { | |
| 116 return kOriginalRequestDateAsDouble + s_timeElapsed; | |
| 117 } | |
| 118 | |
| 119 virtual void SetUp() { | |
| 120 // Save the global memory cache to restore it upon teardown. | |
| 121 m_globalMemoryCache = replaceMemoryCacheForTesting(MemoryCache::create()); | |
| 122 | |
| 123 m_fetcher = ResourceFetcher::create( | |
| 124 MockFetchContext::create(MockFetchContext::kShouldNotLoadNewResource)); | |
| 125 | |
| 126 s_timeElapsed = 0.0; | |
| 127 m_originalTimeFunction = setTimeFunctionsForTesting(returnMockTime); | |
| 128 } | |
| 129 | |
| 130 virtual void TearDown() { | |
| 131 memoryCache()->evictResources(); | |
| 132 | |
| 133 // Yield the ownership of the global memory cache back. | |
| 134 replaceMemoryCacheForTesting(m_globalMemoryCache.release()); | |
| 135 | |
| 136 setTimeFunctionsForTesting(m_originalTimeFunction); | |
| 137 } | |
| 138 | |
| 139 Persistent<MemoryCache> m_globalMemoryCache; | |
| 140 Persistent<ResourceFetcher> m_fetcher; | |
| 141 TimeFunction m_originalTimeFunction; | |
| 142 static double s_timeElapsed; | |
| 143 }; | |
| 144 | |
| 145 double CachingCorrectnessTest::s_timeElapsed; | |
| 146 | |
| 147 TEST_F(CachingCorrectnessTest, FreshFromLastModified) { | |
| 148 ResourceResponse fresh200Response; | |
| 149 fresh200Response.setHTTPStatusCode(200); | |
| 150 fresh200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); | |
| 151 fresh200Response.setHTTPHeaderField("Last-Modified", | |
| 152 kOneDayBeforeOriginalRequest); | |
| 153 | |
| 154 Resource* fresh200 = resourceFromResourceResponse(fresh200Response); | |
| 155 | |
| 156 // Advance the clock within the implicit freshness period of this resource | |
| 157 // before we make a request. | |
| 158 advanceClock(600.); | |
| 159 | |
| 160 Resource* fetched = fetch(); | |
| 161 EXPECT_EQ(fresh200, fetched); | |
| 162 } | |
| 163 | |
| 164 TEST_F(CachingCorrectnessTest, FreshFromExpires) { | |
| 165 ResourceResponse fresh200Response; | |
| 166 fresh200Response.setHTTPStatusCode(200); | |
| 167 fresh200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); | |
| 168 fresh200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest); | |
| 169 | |
| 170 Resource* fresh200 = resourceFromResourceResponse(fresh200Response); | |
| 171 | |
| 172 // Advance the clock within the freshness period of this resource before we | |
| 173 // make a request. | |
| 174 advanceClock(24. * 60. * 60. - 15.); | |
| 175 | |
| 176 Resource* fetched = fetch(); | |
| 177 EXPECT_EQ(fresh200, fetched); | |
| 178 } | |
| 179 | |
| 180 TEST_F(CachingCorrectnessTest, FreshFromMaxAge) { | |
| 181 ResourceResponse fresh200Response; | |
| 182 fresh200Response.setHTTPStatusCode(200); | |
| 183 fresh200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); | |
| 184 fresh200Response.setHTTPHeaderField("Cache-Control", "max-age=600"); | |
| 185 | |
| 186 Resource* fresh200 = resourceFromResourceResponse(fresh200Response); | |
| 187 | |
| 188 // Advance the clock within the freshness period of this resource before we | |
| 189 // make a request. | |
| 190 advanceClock(500.); | |
| 191 | |
| 192 Resource* fetched = fetch(); | |
| 193 EXPECT_EQ(fresh200, fetched); | |
| 194 } | |
| 195 | |
| 196 // The strong validator causes a revalidation to be launched, and the proxy and | |
| 197 // original resources leak because of their reference loop. | |
| 198 TEST_F(CachingCorrectnessTest, DISABLED_ExpiredFromLastModified) { | |
| 199 ResourceResponse expired200Response; | |
| 200 expired200Response.setHTTPStatusCode(200); | |
| 201 expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); | |
| 202 expired200Response.setHTTPHeaderField("Last-Modified", | |
| 203 kOneDayBeforeOriginalRequest); | |
| 204 | |
| 205 Resource* expired200 = resourceFromResourceResponse(expired200Response); | |
| 206 | |
| 207 // Advance the clock beyond the implicit freshness period. | |
| 208 advanceClock(24. * 60. * 60. * 0.2); | |
| 209 | |
| 210 Resource* fetched = fetch(); | |
| 211 EXPECT_NE(expired200, fetched); | |
| 212 } | |
| 213 | |
| 214 TEST_F(CachingCorrectnessTest, ExpiredFromExpires) { | |
| 215 ResourceResponse expired200Response; | |
| 216 expired200Response.setHTTPStatusCode(200); | |
| 217 expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); | |
| 218 expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest); | |
| 219 | |
| 220 Resource* expired200 = resourceFromResourceResponse(expired200Response); | |
| 221 | |
| 222 // Advance the clock within the expiredness period of this resource before we | |
| 223 // make a request. | |
| 224 advanceClock(24. * 60. * 60. + 15.); | |
| 225 | |
| 226 Resource* fetched = fetch(); | |
| 227 EXPECT_NE(expired200, fetched); | |
| 228 } | |
| 229 | |
| 230 // If the image hasn't been loaded in this "document" before, then it shouldn't | |
| 231 // have list of available images logic. | |
| 232 TEST_F(CachingCorrectnessTest, NewImageExpiredFromExpires) { | |
| 233 ResourceResponse expired200Response; | |
| 234 expired200Response.setHTTPStatusCode(200); | |
| 235 expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); | |
| 236 expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest); | |
| 237 | |
| 238 Resource* expired200 = | |
| 239 resourceFromResourceResponse(expired200Response, Resource::Image); | |
| 240 | |
| 241 // Advance the clock within the expiredness period of this resource before we | |
| 242 // make a request. | |
| 243 advanceClock(24. * 60. * 60. + 15.); | |
| 244 | |
| 245 Resource* fetched = fetchImage(); | |
| 246 EXPECT_NE(expired200, fetched); | |
| 247 } | |
| 248 | |
| 249 // If the image has been loaded in this "document" before, then it should have | |
| 250 // list of available images logic, and so normal cache testing should be | |
| 251 // bypassed. | |
| 252 TEST_F(CachingCorrectnessTest, ReuseImageExpiredFromExpires) { | |
| 253 ResourceResponse expired200Response; | |
| 254 expired200Response.setHTTPStatusCode(200); | |
| 255 expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); | |
| 256 expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest); | |
| 257 | |
| 258 Resource* expired200 = | |
| 259 resourceFromResourceResponse(expired200Response, Resource::Image); | |
| 260 | |
| 261 // Advance the clock within the freshness period, and make a request to add | |
| 262 // this image to the document resources. | |
| 263 advanceClock(15.); | |
| 264 Resource* firstFetched = fetchImage(); | |
| 265 EXPECT_EQ(expired200, firstFetched); | |
| 266 | |
| 267 // Advance the clock within the expiredness period of this resource before we | |
| 268 // make a request. | |
| 269 advanceClock(24. * 60. * 60. + 15.); | |
| 270 | |
| 271 Resource* fetched = fetchImage(); | |
| 272 EXPECT_EQ(expired200, fetched); | |
| 273 } | |
| 274 | |
| 275 TEST_F(CachingCorrectnessTest, ExpiredFromMaxAge) { | |
| 276 ResourceResponse expired200Response; | |
| 277 expired200Response.setHTTPStatusCode(200); | |
| 278 expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); | |
| 279 expired200Response.setHTTPHeaderField("Cache-Control", "max-age=600"); | |
| 280 | |
| 281 Resource* expired200 = resourceFromResourceResponse(expired200Response); | |
| 282 | |
| 283 // Advance the clock within the expiredness period of this resource before we | |
| 284 // make a request. | |
| 285 advanceClock(700.); | |
| 286 | |
| 287 Resource* fetched = fetch(); | |
| 288 EXPECT_NE(expired200, fetched); | |
| 289 } | |
| 290 | |
| 291 TEST_F(CachingCorrectnessTest, FreshButNoCache) { | |
| 292 ResourceResponse fresh200NocacheResponse; | |
| 293 fresh200NocacheResponse.setHTTPStatusCode(200); | |
| 294 fresh200NocacheResponse.setHTTPHeaderField(HTTPNames::Date, | |
| 295 kOriginalRequestDateAsString); | |
| 296 fresh200NocacheResponse.setHTTPHeaderField(HTTPNames::Expires, | |
| 297 kOneDayAfterOriginalRequest); | |
| 298 fresh200NocacheResponse.setHTTPHeaderField(HTTPNames::Cache_Control, | |
| 299 "no-cache"); | |
| 300 | |
| 301 Resource* fresh200Nocache = | |
| 302 resourceFromResourceResponse(fresh200NocacheResponse); | |
| 303 | |
| 304 // Advance the clock within the freshness period of this resource before we | |
| 305 // make a request. | |
| 306 advanceClock(24. * 60. * 60. - 15.); | |
| 307 | |
| 308 Resource* fetched = fetch(); | |
| 309 EXPECT_NE(fresh200Nocache, fetched); | |
| 310 } | |
| 311 | |
| 312 TEST_F(CachingCorrectnessTest, RequestWithNoCahe) { | |
| 313 ResourceRequest noCacheRequest; | |
| 314 noCacheRequest.setHTTPHeaderField(HTTPNames::Cache_Control, "no-cache"); | |
| 315 Resource* noCacheResource = resourceFromResourceRequest(noCacheRequest); | |
| 316 Resource* fetched = fetch(); | |
| 317 EXPECT_NE(noCacheResource, fetched); | |
| 318 } | |
| 319 | |
| 320 TEST_F(CachingCorrectnessTest, FreshButNoStore) { | |
| 321 ResourceResponse fresh200NostoreResponse; | |
| 322 fresh200NostoreResponse.setHTTPStatusCode(200); | |
| 323 fresh200NostoreResponse.setHTTPHeaderField(HTTPNames::Date, | |
| 324 kOriginalRequestDateAsString); | |
| 325 fresh200NostoreResponse.setHTTPHeaderField(HTTPNames::Expires, | |
| 326 kOneDayAfterOriginalRequest); | |
| 327 fresh200NostoreResponse.setHTTPHeaderField(HTTPNames::Cache_Control, | |
| 328 "no-store"); | |
| 329 | |
| 330 Resource* fresh200Nostore = | |
| 331 resourceFromResourceResponse(fresh200NostoreResponse); | |
| 332 | |
| 333 // Advance the clock within the freshness period of this resource before we | |
| 334 // make a request. | |
| 335 advanceClock(24. * 60. * 60. - 15.); | |
| 336 | |
| 337 Resource* fetched = fetch(); | |
| 338 EXPECT_NE(fresh200Nostore, fetched); | |
| 339 } | |
| 340 | |
| 341 TEST_F(CachingCorrectnessTest, RequestWithNoStore) { | |
| 342 ResourceRequest noStoreRequest; | |
| 343 noStoreRequest.setHTTPHeaderField(HTTPNames::Cache_Control, "no-store"); | |
| 344 Resource* noStoreResource = resourceFromResourceRequest(noStoreRequest); | |
| 345 Resource* fetched = fetch(); | |
| 346 EXPECT_NE(noStoreResource, fetched); | |
| 347 } | |
| 348 | |
| 349 // FIXME: Determine if ignoring must-revalidate for blink is correct behaviour. | |
| 350 // See crbug.com/340088 . | |
| 351 TEST_F(CachingCorrectnessTest, DISABLED_FreshButMustRevalidate) { | |
| 352 ResourceResponse fresh200MustRevalidateResponse; | |
| 353 fresh200MustRevalidateResponse.setHTTPStatusCode(200); | |
| 354 fresh200MustRevalidateResponse.setHTTPHeaderField( | |
| 355 HTTPNames::Date, kOriginalRequestDateAsString); | |
| 356 fresh200MustRevalidateResponse.setHTTPHeaderField( | |
| 357 HTTPNames::Expires, kOneDayAfterOriginalRequest); | |
| 358 fresh200MustRevalidateResponse.setHTTPHeaderField(HTTPNames::Cache_Control, | |
| 359 "must-revalidate"); | |
| 360 | |
| 361 Resource* fresh200MustRevalidate = | |
| 362 resourceFromResourceResponse(fresh200MustRevalidateResponse); | |
| 363 | |
| 364 // Advance the clock within the freshness period of this resource before we | |
| 365 // make a request. | |
| 366 advanceClock(24. * 60. * 60. - 15.); | |
| 367 | |
| 368 Resource* fetched = fetch(); | |
| 369 EXPECT_NE(fresh200MustRevalidate, fetched); | |
| 370 } | |
| 371 | |
| 372 TEST_F(CachingCorrectnessTest, FreshWithFreshRedirect) { | |
| 373 KURL redirectUrl(ParsedURLString, kResourceURL); | |
| 374 const char redirectTargetUrlString[] = "http://redirect-target.com"; | |
| 375 KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString); | |
| 376 | |
| 377 Resource* firstResource = | |
| 378 RawResource::create(ResourceRequest(redirectUrl), Resource::Raw); | |
| 379 | |
| 380 ResourceResponse fresh301Response; | |
| 381 fresh301Response.setURL(redirectUrl); | |
| 382 fresh301Response.setHTTPStatusCode(301); | |
| 383 fresh301Response.setHTTPHeaderField(HTTPNames::Date, | |
| 384 kOriginalRequestDateAsString); | |
| 385 fresh301Response.setHTTPHeaderField(HTTPNames::Location, | |
| 386 redirectTargetUrlString); | |
| 387 fresh301Response.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=600"); | |
| 388 | |
| 389 // Add the redirect to our request. | |
| 390 ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl); | |
| 391 firstResource->willFollowRedirect(redirectRequest, fresh301Response); | |
| 392 | |
| 393 // Add the final response to our request. | |
| 394 ResourceResponse fresh200Response; | |
| 395 fresh200Response.setURL(redirectTargetUrl); | |
| 396 fresh200Response.setHTTPStatusCode(200); | |
| 397 fresh200Response.setHTTPHeaderField(HTTPNames::Date, | |
| 398 kOriginalRequestDateAsString); | |
| 399 fresh200Response.setHTTPHeaderField(HTTPNames::Expires, | |
| 400 kOneDayAfterOriginalRequest); | |
| 401 | |
| 402 firstResource->setResponse(fresh200Response); | |
| 403 firstResource->finish(); | |
| 404 memoryCache()->add(firstResource); | |
| 405 | |
| 406 advanceClock(500.); | |
| 407 | |
| 408 Resource* fetched = fetch(); | |
| 409 EXPECT_EQ(firstResource, fetched); | |
| 410 } | |
| 411 | |
| 412 TEST_F(CachingCorrectnessTest, FreshWithStaleRedirect) { | |
| 413 KURL redirectUrl(ParsedURLString, kResourceURL); | |
| 414 const char redirectTargetUrlString[] = "http://redirect-target.com"; | |
| 415 KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString); | |
| 416 | |
| 417 Resource* firstResource = | |
| 418 RawResource::create(ResourceRequest(redirectUrl), Resource::Raw); | |
| 419 | |
| 420 ResourceResponse stale301Response; | |
| 421 stale301Response.setURL(redirectUrl); | |
| 422 stale301Response.setHTTPStatusCode(301); | |
| 423 stale301Response.setHTTPHeaderField(HTTPNames::Date, | |
| 424 kOriginalRequestDateAsString); | |
| 425 stale301Response.setHTTPHeaderField(HTTPNames::Location, | |
| 426 redirectTargetUrlString); | |
| 427 | |
| 428 // Add the redirect to our request. | |
| 429 ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl); | |
| 430 firstResource->willFollowRedirect(redirectRequest, stale301Response); | |
| 431 | |
| 432 // Add the final response to our request. | |
| 433 ResourceResponse fresh200Response; | |
| 434 fresh200Response.setURL(redirectTargetUrl); | |
| 435 fresh200Response.setHTTPStatusCode(200); | |
| 436 fresh200Response.setHTTPHeaderField(HTTPNames::Date, | |
| 437 kOriginalRequestDateAsString); | |
| 438 fresh200Response.setHTTPHeaderField(HTTPNames::Expires, | |
| 439 kOneDayAfterOriginalRequest); | |
| 440 | |
| 441 firstResource->setResponse(fresh200Response); | |
| 442 firstResource->finish(); | |
| 443 memoryCache()->add(firstResource); | |
| 444 | |
| 445 advanceClock(500.); | |
| 446 | |
| 447 Resource* fetched = fetch(); | |
| 448 EXPECT_NE(firstResource, fetched); | |
| 449 } | |
| 450 | |
| 451 TEST_F(CachingCorrectnessTest, PostToSameURLTwice) { | |
| 452 ResourceRequest request1(KURL(ParsedURLString, kResourceURL)); | |
| 453 request1.setHTTPMethod(HTTPNames::POST); | |
| 454 Resource* resource1 = | |
| 455 RawResource::create(ResourceRequest(request1.url()), Resource::Raw); | |
| 456 resource1->setStatus(Resource::Pending); | |
| 457 memoryCache()->add(resource1); | |
| 458 | |
| 459 ResourceRequest request2(KURL(ParsedURLString, kResourceURL)); | |
| 460 request2.setHTTPMethod(HTTPNames::POST); | |
| 461 FetchRequest fetch2(request2, FetchInitiatorInfo()); | |
| 462 Resource* resource2 = RawResource::fetchSynchronously(fetch2, fetcher()); | |
| 463 | |
| 464 EXPECT_EQ(resource2, memoryCache()->resourceForURL(request2.url())); | |
| 465 EXPECT_NE(resource1, resource2); | |
| 466 } | |
| 467 | |
| 468 TEST_F(CachingCorrectnessTest, 302RedirectNotImplicitlyFresh) { | |
| 469 KURL redirectUrl(ParsedURLString, kResourceURL); | |
| 470 const char redirectTargetUrlString[] = "http://redirect-target.com"; | |
| 471 KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString); | |
| 472 | |
| 473 Resource* firstResource = | |
| 474 RawResource::create(ResourceRequest(redirectUrl), Resource::Raw); | |
| 475 | |
| 476 ResourceResponse fresh302Response; | |
| 477 fresh302Response.setURL(redirectUrl); | |
| 478 fresh302Response.setHTTPStatusCode(302); | |
| 479 fresh302Response.setHTTPHeaderField(HTTPNames::Date, | |
| 480 kOriginalRequestDateAsString); | |
| 481 fresh302Response.setHTTPHeaderField(HTTPNames::Last_Modified, | |
| 482 kOneDayBeforeOriginalRequest); | |
| 483 fresh302Response.setHTTPHeaderField(HTTPNames::Location, | |
| 484 redirectTargetUrlString); | |
| 485 | |
| 486 // Add the redirect to our request. | |
| 487 ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl); | |
| 488 firstResource->willFollowRedirect(redirectRequest, fresh302Response); | |
| 489 | |
| 490 // Add the final response to our request. | |
| 491 ResourceResponse fresh200Response; | |
| 492 fresh200Response.setURL(redirectTargetUrl); | |
| 493 fresh200Response.setHTTPStatusCode(200); | |
| 494 fresh200Response.setHTTPHeaderField(HTTPNames::Date, | |
| 495 kOriginalRequestDateAsString); | |
| 496 fresh200Response.setHTTPHeaderField(HTTPNames::Expires, | |
| 497 kOneDayAfterOriginalRequest); | |
| 498 | |
| 499 firstResource->setResponse(fresh200Response); | |
| 500 firstResource->finish(); | |
| 501 memoryCache()->add(firstResource); | |
| 502 | |
| 503 advanceClock(500.); | |
| 504 | |
| 505 Resource* fetched = fetch(); | |
| 506 EXPECT_NE(firstResource, fetched); | |
| 507 } | |
| 508 | |
| 509 TEST_F(CachingCorrectnessTest, 302RedirectExplicitlyFreshMaxAge) { | |
| 510 KURL redirectUrl(ParsedURLString, kResourceURL); | |
| 511 const char redirectTargetUrlString[] = "http://redirect-target.com"; | |
| 512 KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString); | |
| 513 | |
| 514 Resource* firstResource = | |
| 515 RawResource::create(ResourceRequest(redirectUrl), Resource::Raw); | |
| 516 | |
| 517 ResourceResponse fresh302Response; | |
| 518 fresh302Response.setURL(redirectUrl); | |
| 519 fresh302Response.setHTTPStatusCode(302); | |
| 520 fresh302Response.setHTTPHeaderField(HTTPNames::Date, | |
| 521 kOriginalRequestDateAsString); | |
| 522 fresh302Response.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=600"); | |
| 523 fresh302Response.setHTTPHeaderField(HTTPNames::Location, | |
| 524 redirectTargetUrlString); | |
| 525 | |
| 526 // Add the redirect to our request. | |
| 527 ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl); | |
| 528 firstResource->willFollowRedirect(redirectRequest, fresh302Response); | |
| 529 | |
| 530 // Add the final response to our request. | |
| 531 ResourceResponse fresh200Response; | |
| 532 fresh200Response.setURL(redirectTargetUrl); | |
| 533 fresh200Response.setHTTPStatusCode(200); | |
| 534 fresh200Response.setHTTPHeaderField(HTTPNames::Date, | |
| 535 kOriginalRequestDateAsString); | |
| 536 fresh200Response.setHTTPHeaderField(HTTPNames::Expires, | |
| 537 kOneDayAfterOriginalRequest); | |
| 538 | |
| 539 firstResource->setResponse(fresh200Response); | |
| 540 firstResource->finish(); | |
| 541 memoryCache()->add(firstResource); | |
| 542 | |
| 543 advanceClock(500.); | |
| 544 | |
| 545 Resource* fetched = fetch(); | |
| 546 EXPECT_EQ(firstResource, fetched); | |
| 547 } | |
| 548 | |
| 549 TEST_F(CachingCorrectnessTest, 302RedirectExplicitlyFreshExpires) { | |
| 550 KURL redirectUrl(ParsedURLString, kResourceURL); | |
| 551 const char redirectTargetUrlString[] = "http://redirect-target.com"; | |
| 552 KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString); | |
| 553 | |
| 554 Resource* firstResource = | |
| 555 RawResource::create(ResourceRequest(redirectUrl), Resource::Raw); | |
| 556 | |
| 557 ResourceResponse fresh302Response; | |
| 558 fresh302Response.setURL(redirectUrl); | |
| 559 fresh302Response.setHTTPStatusCode(302); | |
| 560 fresh302Response.setHTTPHeaderField(HTTPNames::Date, | |
| 561 kOriginalRequestDateAsString); | |
| 562 fresh302Response.setHTTPHeaderField(HTTPNames::Expires, | |
| 563 kOneDayAfterOriginalRequest); | |
| 564 fresh302Response.setHTTPHeaderField(HTTPNames::Location, | |
| 565 redirectTargetUrlString); | |
| 566 | |
| 567 // Add the redirect to our request. | |
| 568 ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl); | |
| 569 firstResource->willFollowRedirect(redirectRequest, fresh302Response); | |
| 570 | |
| 571 // Add the final response to our request. | |
| 572 ResourceResponse fresh200Response; | |
| 573 fresh200Response.setURL(redirectTargetUrl); | |
| 574 fresh200Response.setHTTPStatusCode(200); | |
| 575 fresh200Response.setHTTPHeaderField(HTTPNames::Date, | |
| 576 kOriginalRequestDateAsString); | |
| 577 fresh200Response.setHTTPHeaderField(HTTPNames::Expires, | |
| 578 kOneDayAfterOriginalRequest); | |
| 579 | |
| 580 firstResource->setResponse(fresh200Response); | |
| 581 firstResource->finish(); | |
| 582 memoryCache()->add(firstResource); | |
| 583 | |
| 584 advanceClock(500.); | |
| 585 | |
| 586 Resource* fetched = fetch(); | |
| 587 EXPECT_EQ(firstResource, fetched); | |
| 588 } | |
| 589 | |
| 590 } // namespace blink | |
| OLD | NEW |