| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2010, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2010, 2011 Apple Inc. All rights reserved. |
| 3 * (C) 2007 Graham Dennis (graham.dennis@gmail.com) | 3 * (C) 2007 Graham Dennis (graham.dennis@gmail.com) |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * | 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 #include "public/platform/WebData.h" | 44 #include "public/platform/WebData.h" |
| 45 #include "public/platform/WebThreadedDataReceiver.h" | 45 #include "public/platform/WebThreadedDataReceiver.h" |
| 46 #include "public/platform/WebURLError.h" | 46 #include "public/platform/WebURLError.h" |
| 47 #include "public/platform/WebURLRequest.h" | 47 #include "public/platform/WebURLRequest.h" |
| 48 #include "public/platform/WebURLResponse.h" | 48 #include "public/platform/WebURLResponse.h" |
| 49 #include "wtf/Assertions.h" | 49 #include "wtf/Assertions.h" |
| 50 #include "wtf/CurrentTime.h" | 50 #include "wtf/CurrentTime.h" |
| 51 | 51 |
| 52 namespace blink { | 52 namespace blink { |
| 53 | 53 |
| 54 PassRefPtrWillBeRawPtr<ResourceLoader> ResourceLoader::create(ResourceFetcher* f
etcher, Resource* resource, const ResourceRequest& request, const ResourceLoader
Options& options) | 54 ResourceLoader* ResourceLoader::create(ResourceFetcher* fetcher, Resource* resou
rce, const ResourceRequest& request, const ResourceLoaderOptions& options) |
| 55 { | 55 { |
| 56 RefPtrWillBeRawPtr<ResourceLoader> loader(adoptRefWillBeNoop(new ResourceLoa
der(fetcher, resource, options))); | 56 ResourceLoader* loader = new ResourceLoader(fetcher, resource, options); |
| 57 loader->init(request); | 57 loader->init(request); |
| 58 return loader.release(); | 58 return loader; |
| 59 } | 59 } |
| 60 | 60 |
| 61 ResourceLoader::ResourceLoader(ResourceFetcher* fetcher, Resource* resource, con
st ResourceLoaderOptions& options) | 61 ResourceLoader::ResourceLoader(ResourceFetcher* fetcher, Resource* resource, con
st ResourceLoaderOptions& options) |
| 62 : m_fetcher(fetcher) | 62 : m_fetcher(fetcher) |
| 63 , m_notifiedLoadComplete(false) | 63 , m_notifiedLoadComplete(false) |
| 64 , m_defersLoading(fetcher->defersLoading()) | 64 , m_defersLoading(fetcher->defersLoading()) |
| 65 , m_loadingMultipartContent(false) | 65 , m_loadingMultipartContent(false) |
| 66 , m_options(options) | 66 , m_options(options) |
| 67 , m_resource(resource) | 67 , m_resource(resource) |
| 68 , m_state(Initialized) | 68 , m_state(Initialized) |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 // attached. | 182 // attached. |
| 183 WebThreadedDataReceiver* webDataReceiver = new WebThreadedDataReceiver(t
hreadedDataReceiver); | 183 WebThreadedDataReceiver* webDataReceiver = new WebThreadedDataReceiver(t
hreadedDataReceiver); |
| 184 if (!m_loader->attachThreadedDataReceiver(webDataReceiver)) | 184 if (!m_loader->attachThreadedDataReceiver(webDataReceiver)) |
| 185 delete webDataReceiver; | 185 delete webDataReceiver; |
| 186 } | 186 } |
| 187 } | 187 } |
| 188 | 188 |
| 189 void ResourceLoader::didDownloadData(WebURLLoader*, int length, int encodedDataL
ength) | 189 void ResourceLoader::didDownloadData(WebURLLoader*, int length, int encodedDataL
ength) |
| 190 { | 190 { |
| 191 ASSERT(m_state != Terminated); | 191 ASSERT(m_state != Terminated); |
| 192 RefPtrWillBeRawPtr<ResourceLoader> protect(this); | |
| 193 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse); | 192 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse); |
| 194 m_fetcher->didDownloadData(m_resource, length, encodedDataLength); | 193 m_fetcher->didDownloadData(m_resource, length, encodedDataLength); |
| 195 if (m_state == Terminated) | 194 if (m_state == Terminated) |
| 196 return; | 195 return; |
| 197 m_resource->didDownloadData(length); | 196 m_resource->didDownloadData(length); |
| 198 } | 197 } |
| 199 | 198 |
| 200 void ResourceLoader::didFinishLoadingOnePart(double finishTime, int64_t encodedD
ataLength) | 199 void ResourceLoader::didFinishLoadingOnePart(double finishTime, int64_t encodedD
ataLength) |
| 201 { | 200 { |
| 202 // If load has been cancelled after finishing (which could happen with a | 201 // If load has been cancelled after finishing (which could happen with a |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 // If the load has already completed - succeeded, failed, or previously canc
elled - do nothing. | 235 // If the load has already completed - succeeded, failed, or previously canc
elled - do nothing. |
| 237 if (m_state == Terminated) | 236 if (m_state == Terminated) |
| 238 return; | 237 return; |
| 239 if (m_state == Finishing) { | 238 if (m_state == Finishing) { |
| 240 releaseResources(); | 239 releaseResources(); |
| 241 return; | 240 return; |
| 242 } | 241 } |
| 243 | 242 |
| 244 ResourceError nonNullError = error.isNull() ? ResourceError::cancelledError(
m_request.url()) : error; | 243 ResourceError nonNullError = error.isNull() ? ResourceError::cancelledError(
m_request.url()) : error; |
| 245 | 244 |
| 246 // This function calls out to clients at several points that might do | |
| 247 // something that causes the last reference to this object to go away. | |
| 248 RefPtrWillBeRawPtr<ResourceLoader> protector(this); | |
| 249 | |
| 250 WTF_LOG(ResourceLoading, "Cancelled load of '%s'.\n", m_resource->url().stri
ng().latin1().data()); | 245 WTF_LOG(ResourceLoading, "Cancelled load of '%s'.\n", m_resource->url().stri
ng().latin1().data()); |
| 251 if (m_state == Initialized) | 246 if (m_state == Initialized) |
| 252 m_state = Finishing; | 247 m_state = Finishing; |
| 253 m_resource->setResourceError(nonNullError); | 248 m_resource->setResourceError(nonNullError); |
| 254 | 249 |
| 255 if (m_loader) { | 250 if (m_loader) { |
| 256 m_connectionState = ConnectionStateCanceled; | 251 m_connectionState = ConnectionStateCanceled; |
| 257 m_loader->cancel(); | 252 m_loader->cancel(); |
| 258 m_loader.clear(); | 253 m_loader.clear(); |
| 259 } | 254 } |
| 260 | 255 |
| 261 if (!m_notifiedLoadComplete) { | 256 if (!m_notifiedLoadComplete) { |
| 262 m_notifiedLoadComplete = true; | 257 m_notifiedLoadComplete = true; |
| 263 m_fetcher->didFailLoading(m_resource, nonNullError); | 258 m_fetcher->didFailLoading(m_resource, nonNullError); |
| 264 } | 259 } |
| 265 | 260 |
| 266 if (m_state == Finishing) | 261 if (m_state == Finishing) |
| 267 m_resource->error(Resource::LoadError); | 262 m_resource->error(Resource::LoadError); |
| 268 if (m_state != Terminated) | 263 if (m_state != Terminated) |
| 269 releaseResources(); | 264 releaseResources(); |
| 270 } | 265 } |
| 271 | 266 |
| 272 void ResourceLoader::willSendRequest(WebURLLoader*, WebURLRequest& passedNewRequ
est, const WebURLResponse& passedRedirectResponse) | 267 void ResourceLoader::willSendRequest(WebURLLoader*, WebURLRequest& passedNewRequ
est, const WebURLResponse& passedRedirectResponse) |
| 273 { | 268 { |
| 274 ASSERT(m_state != Terminated); | 269 ASSERT(m_state != Terminated); |
| 275 RefPtrWillBeRawPtr<ResourceLoader> protect(this); | |
| 276 | 270 |
| 277 ResourceRequest& newRequest(applyOptions(passedNewRequest.toMutableResourceR
equest())); | 271 ResourceRequest& newRequest(applyOptions(passedNewRequest.toMutableResourceR
equest())); |
| 278 | 272 |
| 279 ASSERT(!newRequest.isNull()); | 273 ASSERT(!newRequest.isNull()); |
| 280 const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceRe
sponse()); | 274 const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceRe
sponse()); |
| 281 ASSERT(!redirectResponse.isNull()); | 275 ASSERT(!redirectResponse.isNull()); |
| 282 newRequest.setFollowedRedirect(true); | 276 newRequest.setFollowedRedirect(true); |
| 283 if (!m_fetcher->canAccessRedirect(m_resource, newRequest, redirectResponse,
m_options)) { | 277 if (!m_fetcher->canAccessRedirect(m_resource, newRequest, redirectResponse,
m_options)) { |
| 284 cancel(ResourceError::cancelledDueToAccessCheckError(newRequest.url())); | 278 cancel(ResourceError::cancelledDueToAccessCheckError(newRequest.url())); |
| 285 return; | 279 return; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 else | 352 else |
| 359 m_resource->setResponse(resourceResponse); | 353 m_resource->setResponse(resourceResponse); |
| 360 if (!m_fetcher->canAccessResource(resource, m_options.securityOrigin
.get(), response.url(), ResourceFetcher::ShouldLogAccessControlErrors)) { | 354 if (!m_fetcher->canAccessResource(resource, m_options.securityOrigin
.get(), response.url(), ResourceFetcher::ShouldLogAccessControlErrors)) { |
| 361 m_fetcher->didReceiveResponse(m_resource, resourceResponse); | 355 m_fetcher->didReceiveResponse(m_resource, resourceResponse); |
| 362 cancel(ResourceError::cancelledDueToAccessCheckError(KURL(respon
se.url()))); | 356 cancel(ResourceError::cancelledDueToAccessCheckError(KURL(respon
se.url()))); |
| 363 return; | 357 return; |
| 364 } | 358 } |
| 365 } | 359 } |
| 366 } | 360 } |
| 367 | 361 |
| 368 // Reference the object in this method since the additional processing can d
o | |
| 369 // anything including removing the last reference to this object. | |
| 370 RefPtrWillBeRawPtr<ResourceLoader> protect(this); | |
| 371 m_resource->responseReceived(resourceResponse, handle.release()); | 362 m_resource->responseReceived(resourceResponse, handle.release()); |
| 372 if (m_state == Terminated) | 363 if (m_state == Terminated) |
| 373 return; | 364 return; |
| 374 | 365 |
| 375 m_fetcher->didReceiveResponse(m_resource, resourceResponse); | 366 m_fetcher->didReceiveResponse(m_resource, resourceResponse); |
| 376 if (m_state == Terminated) | 367 if (m_state == Terminated) |
| 377 return; | 368 return; |
| 378 | 369 |
| 379 if (response.toResourceResponse().isMultipart()) { | 370 if (response.toResourceResponse().isMultipart()) { |
| 380 // We only support multipart for images, though the image may be loaded | 371 // We only support multipart for images, though the image may be loaded |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 ASSERT(m_state != Terminated); | 408 ASSERT(m_state != Terminated); |
| 418 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse || m_con
nectionState == ConnectionStateReceivingData); | 409 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse || m_con
nectionState == ConnectionStateReceivingData); |
| 419 m_connectionState = ConnectionStateReceivingData; | 410 m_connectionState = ConnectionStateReceivingData; |
| 420 | 411 |
| 421 // It is possible to receive data on uninitialized resources if it had an er
ror status code, and we are running a nested message | 412 // It is possible to receive data on uninitialized resources if it had an er
ror status code, and we are running a nested message |
| 422 // loop. When this occurs, ignoring the data is the correct action. | 413 // loop. When this occurs, ignoring the data is the correct action. |
| 423 if (m_resource->response().httpStatusCode() >= 400 && !m_resource->shouldIgn
oreHTTPStatusCodeErrors()) | 414 if (m_resource->response().httpStatusCode() >= 400 && !m_resource->shouldIgn
oreHTTPStatusCodeErrors()) |
| 424 return; | 415 return; |
| 425 ASSERT(m_state == Initialized); | 416 ASSERT(m_state == Initialized); |
| 426 | 417 |
| 427 // Reference the object in this method since the additional processing can d
o | |
| 428 // anything including removing the last reference to this object. | |
| 429 RefPtrWillBeRawPtr<ResourceLoader> protect(this); | |
| 430 | |
| 431 // FIXME: If we get a resource with more than 2B bytes, this code won't do t
he right thing. | 418 // FIXME: If we get a resource with more than 2B bytes, this code won't do t
he right thing. |
| 432 // However, with today's computers and networking speeds, this won't happen
in practice. | 419 // However, with today's computers and networking speeds, this won't happen
in practice. |
| 433 // Could be an issue with a giant local file. | 420 // Could be an issue with a giant local file. |
| 434 m_fetcher->didReceiveData(m_resource, data, length, encodedDataLength); | 421 m_fetcher->didReceiveData(m_resource, data, length, encodedDataLength); |
| 435 if (m_state == Terminated) | 422 if (m_state == Terminated) |
| 436 return; | 423 return; |
| 437 RELEASE_ASSERT(length >= 0); | 424 RELEASE_ASSERT(length >= 0); |
| 438 m_resource->appendData(data, length); | 425 m_resource->appendData(data, length); |
| 439 } | 426 } |
| 440 | 427 |
| 441 void ResourceLoader::didFinishLoading(WebURLLoader*, double finishTime, int64_t
encodedDataLength) | 428 void ResourceLoader::didFinishLoading(WebURLLoader*, double finishTime, int64_t
encodedDataLength) |
| 442 { | 429 { |
| 443 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse || m_con
nectionState == ConnectionStateReceivingData); | 430 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse || m_con
nectionState == ConnectionStateReceivingData); |
| 444 m_connectionState = ConnectionStateFinishedLoading; | 431 m_connectionState = ConnectionStateFinishedLoading; |
| 445 if (m_state != Initialized) | 432 if (m_state != Initialized) |
| 446 return; | 433 return; |
| 447 ASSERT(m_state != Terminated); | 434 ASSERT(m_state != Terminated); |
| 448 WTF_LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1
().data()); | 435 WTF_LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1
().data()); |
| 449 | 436 |
| 450 RefPtrWillBeRawPtr<ResourceLoader> protect(this); | |
| 451 ResourcePtr<Resource> protectResource(m_resource); | 437 ResourcePtr<Resource> protectResource(m_resource); |
| 452 m_state = Finishing; | 438 m_state = Finishing; |
| 453 m_resource->setLoadFinishTime(finishTime); | 439 m_resource->setLoadFinishTime(finishTime); |
| 454 didFinishLoadingOnePart(finishTime, encodedDataLength); | 440 didFinishLoadingOnePart(finishTime, encodedDataLength); |
| 455 if (m_state == Terminated) | 441 if (m_state == Terminated) |
| 456 return; | 442 return; |
| 457 m_resource->finish(); | 443 m_resource->finish(); |
| 458 | 444 |
| 459 // If the load has been cancelled by a delegate in response to didFinishLoad
(), do not release | 445 // If the load has been cancelled by a delegate in response to didFinishLoad
(), do not release |
| 460 // the resources a second time, they have been released by cancel. | 446 // the resources a second time, they have been released by cancel. |
| 461 if (m_state == Terminated) | 447 if (m_state == Terminated) |
| 462 return; | 448 return; |
| 463 releaseResources(); | 449 releaseResources(); |
| 464 } | 450 } |
| 465 | 451 |
| 466 void ResourceLoader::didFail(WebURLLoader*, const WebURLError& error) | 452 void ResourceLoader::didFail(WebURLLoader*, const WebURLError& error) |
| 467 { | 453 { |
| 468 m_connectionState = ConnectionStateFailed; | 454 m_connectionState = ConnectionStateFailed; |
| 469 ASSERT(m_state != Terminated); | 455 ASSERT(m_state != Terminated); |
| 470 WTF_LOG(ResourceLoading, "Failed to load '%s'.\n", m_resource->url().string(
).latin1().data()); | 456 WTF_LOG(ResourceLoading, "Failed to load '%s'.\n", m_resource->url().string(
).latin1().data()); |
| 471 | 457 |
| 472 RefPtrWillBeRawPtr<ResourceLoader> protect(this); | |
| 473 RefPtrWillBeRawPtr<ResourceFetcher> protectFetcher(m_fetcher.get()); | |
| 474 ResourcePtr<Resource> protectResource(m_resource); | 458 ResourcePtr<Resource> protectResource(m_resource); |
| 475 m_state = Finishing; | 459 m_state = Finishing; |
| 476 m_resource->setResourceError(error); | 460 m_resource->setResourceError(error); |
| 477 | 461 |
| 478 if (!m_notifiedLoadComplete) { | 462 if (!m_notifiedLoadComplete) { |
| 479 m_notifiedLoadComplete = true; | 463 m_notifiedLoadComplete = true; |
| 480 m_fetcher->didFailLoading(m_resource, error); | 464 m_fetcher->didFailLoading(m_resource, error); |
| 481 } | 465 } |
| 482 if (m_state == Terminated) | 466 if (m_state == Terminated) |
| 483 return; | 467 return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 496 } | 480 } |
| 497 | 481 |
| 498 void ResourceLoader::requestSynchronously() | 482 void ResourceLoader::requestSynchronously() |
| 499 { | 483 { |
| 500 OwnPtr<WebURLLoader> loader = adoptPtr(Platform::current()->createURLLoader(
)); | 484 OwnPtr<WebURLLoader> loader = adoptPtr(Platform::current()->createURLLoader(
)); |
| 501 ASSERT(loader); | 485 ASSERT(loader); |
| 502 | 486 |
| 503 // downloadToFile is not supported for synchronous requests. | 487 // downloadToFile is not supported for synchronous requests. |
| 504 ASSERT(!m_request.downloadToFile()); | 488 ASSERT(!m_request.downloadToFile()); |
| 505 | 489 |
| 506 RefPtrWillBeRawPtr<ResourceLoader> protect(this); | |
| 507 RefPtrWillBeRawPtr<ResourceFetcher> protectFetcher(m_fetcher.get()); | |
| 508 ResourcePtr<Resource> protectResource(m_resource); | 490 ResourcePtr<Resource> protectResource(m_resource); |
| 509 | 491 |
| 510 RELEASE_ASSERT(m_connectionState == ConnectionStateNew); | 492 RELEASE_ASSERT(m_connectionState == ConnectionStateNew); |
| 511 m_connectionState = ConnectionStateStarted; | 493 m_connectionState = ConnectionStateStarted; |
| 512 | 494 |
| 513 WrappedResourceRequest requestIn(m_request); | 495 WrappedResourceRequest requestIn(m_request); |
| 514 WebURLResponse responseOut; | 496 WebURLResponse responseOut; |
| 515 responseOut.initialize(); | 497 responseOut.initialize(); |
| 516 WebURLError errorOut; | 498 WebURLError errorOut; |
| 517 WebData dataOut; | 499 WebData dataOut; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 536 didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); | 518 didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); |
| 537 } | 519 } |
| 538 | 520 |
| 539 ResourceRequest& ResourceLoader::applyOptions(ResourceRequest& request) const | 521 ResourceRequest& ResourceLoader::applyOptions(ResourceRequest& request) const |
| 540 { | 522 { |
| 541 request.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredC
redentials); | 523 request.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredC
redentials); |
| 542 return request; | 524 return request; |
| 543 } | 525 } |
| 544 | 526 |
| 545 } | 527 } |
| OLD | NEW |