Chromium Code Reviews| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 visitor->trace(m_resource); | 73 visitor->trace(m_resource); |
| 74 } | 74 } |
| 75 | 75 |
| 76 void ResourceLoader::releaseResources() | 76 void ResourceLoader::releaseResources() |
| 77 { | 77 { |
| 78 ASSERT(m_state != ConnectionStateReleased); | 78 ASSERT(m_state != ConnectionStateReleased); |
| 79 ASSERT(m_notifiedLoadComplete); | 79 ASSERT(m_notifiedLoadComplete); |
| 80 m_fetcher->didLoadResource(m_resource.get()); | 80 m_fetcher->didLoadResource(m_resource.get()); |
| 81 if (m_state == ConnectionStateReleased) | 81 if (m_state == ConnectionStateReleased) |
| 82 return; | 82 return; |
| 83 m_resource->clearLoader(); | |
| 84 m_resource = nullptr; | 83 m_resource = nullptr; |
| 85 | 84 |
| 86 ASSERT(m_state != ConnectionStateReleased); | 85 ASSERT(m_state != ConnectionStateReleased); |
| 87 m_state = ConnectionStateReleased; | 86 m_state = ConnectionStateReleased; |
| 88 if (m_loader) { | 87 if (m_loader) { |
| 89 m_loader->cancel(); | 88 m_loader->cancel(); |
| 90 m_loader.clear(); | 89 m_loader.clear(); |
| 91 } | 90 } |
| 92 m_fetcher.clear(); | 91 m_fetcher.clear(); |
| 93 } | 92 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 122 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse); | 121 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse); |
| 123 m_fetcher->didDownloadData(m_resource.get(), length, encodedDataLength); | 122 m_fetcher->didDownloadData(m_resource.get(), length, encodedDataLength); |
| 124 if (m_state == ConnectionStateReleased) | 123 if (m_state == ConnectionStateReleased) |
| 125 return; | 124 return; |
| 126 m_resource->didDownloadData(length); | 125 m_resource->didDownloadData(length); |
| 127 } | 126 } |
| 128 | 127 |
| 129 void ResourceLoader::didFinishLoadingOnePart(double finishTime, int64_t encodedD ataLength) | 128 void ResourceLoader::didFinishLoadingOnePart(double finishTime, int64_t encodedD ataLength) |
| 130 { | 129 { |
| 131 ASSERT(m_state != ConnectionStateReleased); | 130 ASSERT(m_state != ConnectionStateReleased); |
| 132 if (isFinishing()) { | 131 if (m_state == ConnectionStateFinishedLoading) { |
| 133 m_fetcher->removeResourceLoader(this); | 132 m_fetcher->removeResourceLoader(this); |
| 134 } else { | 133 } else { |
| 135 // When loading a multipart resource, make the loader non-block when | 134 // When loading a multipart resource, make the loader non-block when |
| 136 // finishing loading the first part. | 135 // finishing loading the first part. |
| 137 m_fetcher->moveResourceLoaderToNonBlocking(this); | 136 m_fetcher->moveResourceLoaderToNonBlocking(this); |
| 138 | 137 |
| 139 m_fetcher->didLoadResource(m_resource.get()); | 138 m_fetcher->didLoadResource(m_resource.get()); |
| 140 if (m_state == ConnectionStateReleased) | 139 if (m_state == ConnectionStateReleased) |
| 141 return; | 140 return; |
| 142 } | 141 } |
| 143 | 142 |
| 144 if (m_notifiedLoadComplete) | 143 if (m_notifiedLoadComplete) |
| 145 return; | 144 return; |
| 146 m_notifiedLoadComplete = true; | 145 m_notifiedLoadComplete = true; |
| 147 m_fetcher->didFinishLoading(m_resource.get(), finishTime, encodedDataLength) ; | 146 m_fetcher->didFinishLoading(m_resource.get(), finishTime, encodedDataLength) ; |
| 148 } | 147 } |
| 149 | 148 |
| 150 void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority, int in traPriorityValue) | 149 void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority, int in traPriorityValue) |
| 151 { | 150 { |
| 152 ASSERT(m_state != ConnectionStateReleased); | 151 ASSERT(m_state != ConnectionStateReleased); |
| 153 if (m_loader) | 152 if (m_loader) |
| 154 m_loader->didChangePriority(static_cast<WebURLRequest::Priority>(loadPri ority), intraPriorityValue); | 153 m_loader->didChangePriority(static_cast<WebURLRequest::Priority>(loadPri ority), intraPriorityValue); |
| 155 } | 154 } |
| 156 | 155 |
| 157 void ResourceLoader::cancelIfNotFinishing() | |
| 158 { | |
| 159 if (isFinishing()) | |
| 160 return; | |
| 161 cancel(); | |
| 162 } | |
| 163 | |
| 164 void ResourceLoader::cancel() | 156 void ResourceLoader::cancel() |
| 165 { | 157 { |
| 166 cancel(ResourceError()); | 158 cancel(ResourceError()); |
| 167 } | 159 } |
| 168 | 160 |
| 169 void ResourceLoader::cancel(const ResourceError& error) | 161 void ResourceLoader::cancel(const ResourceError& error) |
| 170 { | 162 { |
| 171 // If the load has already completed - succeeded, failed, or previously canc elled - do nothing. | 163 ASSERT(m_state != ConnectionStateFinishedLoading); |
| 172 if (m_state == ConnectionStateReleased) | 164 ASSERT(m_state != ConnectionStateReleased); |
| 173 return; | |
| 174 if (isFinishing()) { | |
| 175 releaseResources(); | |
| 176 return; | |
| 177 } | |
| 178 | |
| 179 ResourceError nonNullError = error.isNull() ? ResourceError::cancelledError( m_resource->lastResourceRequest().url()) : error; | |
| 180 | |
| 181 WTF_LOG(ResourceLoading, "Cancelled load of '%s'.\n", m_resource->url().getS tring().latin1().data()); | |
| 182 m_state = ConnectionStateCanceled; | |
| 183 m_resource->setResourceError(nonNullError); | |
| 184 | 165 |
| 185 // If we don't immediately clear m_loader when cancelling, we might get | 166 // If we don't immediately clear m_loader when cancelling, we might get |
| 186 // unexpected reentrancy. m_resource->error() can trigger JS events, which | 167 // unexpected reentrancy. m_resource->error() can trigger JS events, which |
| 187 // could start a modal dialog. Normally, a modal dialog would defer loading | 168 // could start a modal dialog. Normally, a modal dialog would defer loading |
| 188 // and prevent receiving messages for a cancelled ResourceLoader, but | 169 // and prevent receiving messages for a cancelled ResourceLoader, but |
| 189 // m_fetcher->didFailLoading() severs the connection by which all of a | 170 // m_fetcher->didFailLoading() severs the connection by which all of a |
| 190 // page's loads are deferred. A response can then arrive, see m_state | 171 // page's loads are deferred. A response can then arrive, see m_state |
| 191 // is ConnectionStateCanceled, and ASSERT or break in other ways. | 172 // is ConnectionStateFinishedLoading, and ASSERT or break in other ways. |
| 192 if (m_loader) { | 173 if (m_loader) { |
| 193 m_loader->cancel(); | 174 m_loader->cancel(); |
| 194 m_loader.clear(); | 175 m_loader.clear(); |
| 195 } | 176 } |
| 196 | 177 didFail(nullptr, error.isNull() ? ResourceError::cancelledError(m_resource-> lastResourceRequest().url()) : error); |
| 197 if (!m_notifiedLoadComplete) { | |
| 198 m_notifiedLoadComplete = true; | |
| 199 m_fetcher->didFailLoading(m_resource.get(), nonNullError); | |
| 200 } | |
| 201 | |
| 202 if (m_state != ConnectionStateReleased) | |
| 203 m_resource->error(Resource::LoadError); | |
| 204 if (m_state != ConnectionStateReleased) | |
| 205 releaseResources(); | |
| 206 } | 178 } |
| 207 | 179 |
| 208 void ResourceLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewR equest, const WebURLResponse& passedRedirectResponse) | 180 void ResourceLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewR equest, const WebURLResponse& passedRedirectResponse) |
| 209 { | 181 { |
| 210 ASSERT(m_state != ConnectionStateReleased); | 182 ASSERT(m_state != ConnectionStateReleased); |
| 211 ASSERT(!passedNewRequest.isNull()); | 183 ASSERT(!passedNewRequest.isNull()); |
| 212 ASSERT(!passedRedirectResponse.isNull()); | 184 ASSERT(!passedRedirectResponse.isNull()); |
| 213 | 185 |
| 214 ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest()); | 186 ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest()); |
| 215 const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceRe sponse()); | 187 const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceRe sponse()); |
| 216 newRequest.setFollowedRedirect(true); | 188 newRequest.setFollowedRedirect(true); |
| 217 | 189 |
| 218 if (m_fetcher->willFollowRedirect(m_resource.get(), newRequest, redirectResp onse)) { | 190 if (m_fetcher->willFollowRedirect(m_resource.get(), newRequest, redirectResp onse)) { |
| 219 m_resource->willFollowRedirect(newRequest, redirectResponse); | 191 m_resource->willFollowRedirect(newRequest, redirectResponse); |
| 220 } else { | 192 } else { |
| 221 m_resource->willNotFollowRedirect(); | 193 m_resource->willNotFollowRedirect(); |
| 222 cancel(ResourceError::cancelledDueToAccessCheckError(newRequest.url())); | 194 if (m_state != ConnectionStateReleased) |
| 195 cancel(ResourceError::cancelledDueToAccessCheckError(newRequest.url( ))); | |
| 223 } | 196 } |
| 224 } | 197 } |
| 225 | 198 |
| 226 void ResourceLoader::didReceiveCachedMetadata(WebURLLoader*, const char* data, i nt length) | 199 void ResourceLoader::didReceiveCachedMetadata(WebURLLoader*, const char* data, i nt length) |
| 227 { | 200 { |
| 228 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse || m_state == Conn ectionStateReceivingData); | 201 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse || m_state == Conn ectionStateReceivingData); |
| 229 m_resource->setSerializedCachedMetadata(data, length); | 202 m_resource->setSerializedCachedMetadata(data, length); |
| 230 } | 203 } |
| 231 | 204 |
| 232 void ResourceLoader::didSendData(WebURLLoader*, unsigned long long bytesSent, un signed long long totalBytesToBeSent) | 205 void ResourceLoader::didSendData(WebURLLoader*, unsigned long long bytesSent, un signed long long totalBytesToBeSent) |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 263 ResourceRequest request = m_resource->lastResourceRequest(); | 236 ResourceRequest request = m_resource->lastResourceRequest(); |
| 264 ASSERT(!request.skipServiceWorker()); | 237 ASSERT(!request.skipServiceWorker()); |
| 265 request.setSkipServiceWorker(true); | 238 request.setSkipServiceWorker(true); |
| 266 m_loader->loadAsynchronously(WrappedResourceRequest(request), th is); | 239 m_loader->loadAsynchronously(WrappedResourceRequest(request), th is); |
| 267 return; | 240 return; |
| 268 } | 241 } |
| 269 } else { | 242 } else { |
| 270 if (!m_resource->isCacheValidator() || resourceResponse.httpStatusCo de() != 304) | 243 if (!m_resource->isCacheValidator() || resourceResponse.httpStatusCo de() != 304) |
| 271 m_resource->setResponse(resourceResponse); | 244 m_resource->setResponse(resourceResponse); |
| 272 if (!m_fetcher->canAccessResource(m_resource.get(), m_resource->opti ons().securityOrigin.get(), response.url(), ResourceFetcher::ShouldLogAccessCont rolErrors)) { | 245 if (!m_fetcher->canAccessResource(m_resource.get(), m_resource->opti ons().securityOrigin.get(), response.url(), ResourceFetcher::ShouldLogAccessCont rolErrors)) { |
| 273 m_fetcher->didReceiveResponse(m_resource.get(), resourceResponse ); | 246 m_fetcher->didReceiveResponse(m_resource.get(), resourceResponse ); |
|
yhirano
2016/05/02 12:38:45
Do we need |if (m_state != Released) | here?
Nate Chapin
2016/05/02 20:07:37
canAccessResource() doesn't cancel() the ResourceL
| |
| 274 cancel(ResourceError::cancelledDueToAccessCheckError(KURL(respon se.url()))); | 247 cancel(ResourceError::cancelledDueToAccessCheckError(KURL(respon se.url()))); |
| 275 return; | 248 return; |
| 276 } | 249 } |
| 277 } | 250 } |
| 278 } | 251 } |
| 279 | 252 |
| 280 m_resource->responseReceived(resourceResponse, handle.release()); | 253 m_resource->responseReceived(resourceResponse, handle.release()); |
| 281 if (m_state == ConnectionStateReleased) | 254 if (m_state == ConnectionStateReleased) |
| 282 return; | 255 return; |
| 283 | 256 |
| 284 m_fetcher->didReceiveResponse(m_resource.get(), resourceResponse); | 257 m_fetcher->didReceiveResponse(m_resource.get(), resourceResponse); |
| 285 if (m_state == ConnectionStateReleased) | 258 if (m_state == ConnectionStateReleased) |
| 286 return; | 259 return; |
| 287 | 260 |
| 288 if (m_resource->response().httpStatusCode() < 400 || m_resource->shouldIgnor eHTTPStatusCodeErrors()) | 261 if (m_resource->response().httpStatusCode() < 400 || m_resource->shouldIgnor eHTTPStatusCodeErrors()) |
| 289 return; | 262 return; |
| 290 | |
| 291 if (!m_notifiedLoadComplete) { | |
| 292 m_notifiedLoadComplete = true; | |
| 293 m_fetcher->didFailLoading(m_resource.get(), ResourceError::cancelledErro r(resourceResponse.url())); | |
| 294 } | |
| 295 | |
| 296 ASSERT(m_state != ConnectionStateReleased); | |
| 297 m_resource->error(Resource::LoadError); | |
| 298 cancel(ResourceError::cancelledError(resourceResponse.url())); | 263 cancel(ResourceError::cancelledError(resourceResponse.url())); |
| 299 } | 264 } |
| 300 | 265 |
| 301 void ResourceLoader::didReceiveResponse(WebURLLoader* loader, const WebURLRespon se& response) | 266 void ResourceLoader::didReceiveResponse(WebURLLoader* loader, const WebURLRespon se& response) |
| 302 { | 267 { |
| 303 didReceiveResponse(loader, response, nullptr); | 268 didReceiveResponse(loader, response, nullptr); |
| 304 } | 269 } |
| 305 | 270 |
| 306 void ResourceLoader::didReceiveData(WebURLLoader*, const char* data, int length, int encodedDataLength) | 271 void ResourceLoader::didReceiveData(WebURLLoader*, const char* data, int length, int encodedDataLength) |
| 307 { | 272 { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 318 // Could be an issue with a giant local file. | 283 // Could be an issue with a giant local file. |
| 319 m_fetcher->didReceiveData(m_resource.get(), data, length, encodedDataLength) ; | 284 m_fetcher->didReceiveData(m_resource.get(), data, length, encodedDataLength) ; |
| 320 if (m_state == ConnectionStateReleased) | 285 if (m_state == ConnectionStateReleased) |
| 321 return; | 286 return; |
| 322 RELEASE_ASSERT(length >= 0); | 287 RELEASE_ASSERT(length >= 0); |
| 323 m_resource->appendData(data, length); | 288 m_resource->appendData(data, length); |
| 324 } | 289 } |
| 325 | 290 |
| 326 void ResourceLoader::didFinishLoading(WebURLLoader*, double finishTime, int64_t encodedDataLength) | 291 void ResourceLoader::didFinishLoading(WebURLLoader*, double finishTime, int64_t encodedDataLength) |
| 327 { | 292 { |
| 328 | |
| 329 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse || m_state == Conn ectionStateReceivingData); | 293 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse || m_state == Conn ectionStateReceivingData); |
| 330 m_state = ConnectionStateFinishedLoading; | 294 m_state = ConnectionStateFinishedLoading; |
| 331 WTF_LOG(ResourceLoading, "Received '%s'.", m_resource->url().getString().lat in1().data()); | |
| 332 | |
| 333 m_resource->setLoadFinishTime(finishTime); | 295 m_resource->setLoadFinishTime(finishTime); |
| 334 didFinishLoadingOnePart(finishTime, encodedDataLength); | 296 didFinishLoadingOnePart(finishTime, encodedDataLength); |
| 335 if (m_state == ConnectionStateReleased) | |
| 336 return; | |
| 337 m_resource->finish(); | 297 m_resource->finish(); |
|
hiroshige
2016/05/02 06:39:27
How about adding ASSERT(m_state != ConnectionState
Nate Chapin
2016/05/02 20:07:37
Done.
hiroshige
2016/05/10 10:22:48
Ack. (memo: ASSERT() after this line is not needed
| |
| 338 | |
| 339 // If the load has been cancelled by a delegate in response to didFinishLoad (), do not release | |
| 340 // the resources a second time, they have been released by cancel. | |
| 341 if (m_state == ConnectionStateReleased) | |
| 342 return; | |
| 343 releaseResources(); | 298 releaseResources(); |
| 344 } | 299 } |
| 345 | 300 |
| 346 void ResourceLoader::didFail(WebURLLoader*, const WebURLError& error) | 301 void ResourceLoader::didFail(WebURLLoader*, const WebURLError& error) |
| 347 { | 302 { |
| 348 | 303 ASSERT(m_state != ConnectionStateFinishedLoading); |
| 349 ASSERT(m_state != ConnectionStateReleased); | 304 ASSERT(m_state != ConnectionStateReleased); |
| 350 m_state = ConnectionStateFailed; | 305 m_state = ConnectionStateFinishedLoading; |
| 351 WTF_LOG(ResourceLoading, "Failed to load '%s'.\n", m_resource->url().getStri ng().latin1().data()); | |
| 352 | |
| 353 m_resource->setResourceError(error); | 306 m_resource->setResourceError(error); |
| 354 | 307 m_notifiedLoadComplete = true; |
|
hiroshige
2016/05/02 06:39:27
How about adding ASSERT(!m_notifiedLoadComplete) b
Nate Chapin
2016/05/02 20:07:37
This isn't always the case as-is. It can be true h
hiroshige
2016/05/10 10:22:48
Hmm, so this CL adds ResourceFetcher::didFailLoadi
Nate Chapin
2016/05/10 18:26:17
The only non-test difference I see will be that th
hiroshige
2016/05/11 09:28:38
Sounds reasonable.
Please mention briefly about th
Nate Chapin
2016/05/11 18:49:53
Done.
| |
| 355 if (!m_notifiedLoadComplete) { | 308 m_fetcher->didFailLoading(m_resource.get(), error); |
| 356 m_notifiedLoadComplete = true; | |
| 357 m_fetcher->didFailLoading(m_resource.get(), error); | |
| 358 } | |
| 359 if (m_state == ConnectionStateReleased) | |
| 360 return; | |
| 361 | |
| 362 m_resource->error(Resource::LoadError); | 309 m_resource->error(Resource::LoadError); |
|
hiroshige
2016/05/02 06:39:27
How about adding ASSERT(m_state != ConnectionState
Nate Chapin
2016/05/02 20:07:37
Done.
| |
| 363 | |
| 364 if (m_state == ConnectionStateReleased) | |
| 365 return; | |
| 366 | |
| 367 releaseResources(); | 310 releaseResources(); |
| 368 } | 311 } |
| 369 | 312 |
| 370 void ResourceLoader::requestSynchronously(ResourceRequest& request) | 313 void ResourceLoader::requestSynchronously(ResourceRequest& request) |
| 371 { | 314 { |
| 372 // downloadToFile is not supported for synchronous requests. | 315 // downloadToFile is not supported for synchronous requests. |
| 373 ASSERT(!request.downloadToFile()); | 316 ASSERT(!request.downloadToFile()); |
| 374 ASSERT(m_loader); | 317 ASSERT(m_loader); |
| 375 | 318 |
| 376 // Synchronous requests should always be max priority, lest they hang the re nderer. | 319 // Synchronous requests should always be max priority, lest they hang the re nderer. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 // empty buffer is a noop in most cases, but is destructive in the case of | 351 // empty buffer is a noop in most cases, but is destructive in the case of |
| 409 // a 304, where it will overwrite the cached data we should be reusing. | 352 // a 304, where it will overwrite the cached data we should be reusing. |
| 410 if (dataOut.size()) { | 353 if (dataOut.size()) { |
| 411 m_fetcher->didReceiveData(m_resource.get(), dataOut.data(), dataOut.size (), encodedDataLength); | 354 m_fetcher->didReceiveData(m_resource.get(), dataOut.data(), dataOut.size (), encodedDataLength); |
| 412 m_resource->setResourceBuffer(dataOut); | 355 m_resource->setResourceBuffer(dataOut); |
| 413 } | 356 } |
| 414 didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); | 357 didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); |
| 415 } | 358 } |
| 416 | 359 |
| 417 } // namespace blink | 360 } // namespace blink |
| OLD | NEW |