| 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 { | 71 { |
| 72 visitor->trace(m_fetcher); | 72 visitor->trace(m_fetcher); |
| 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 ASSERT(m_state != ConnectionStateReleased); |
| 82 return; | |
| 83 m_resource->clearLoader(); | |
| 84 m_resource = nullptr; | 82 m_resource = nullptr; |
| 85 | |
| 86 ASSERT(m_state != ConnectionStateReleased); | |
| 87 m_state = ConnectionStateReleased; | 83 m_state = ConnectionStateReleased; |
| 88 if (m_loader) { | 84 if (m_loader) { |
| 89 m_loader->cancel(); | 85 m_loader->cancel(); |
| 90 m_loader.clear(); | 86 m_loader.clear(); |
| 91 } | 87 } |
| 92 m_fetcher.clear(); | 88 m_fetcher.clear(); |
| 93 } | 89 } |
| 94 | 90 |
| 95 void ResourceLoader::start(ResourceRequest& request) | 91 void ResourceLoader::start(ResourceRequest& request) |
| 96 { | 92 { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 122 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse); | 118 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse); |
| 123 m_fetcher->didDownloadData(m_resource.get(), length, encodedDataLength); | 119 m_fetcher->didDownloadData(m_resource.get(), length, encodedDataLength); |
| 124 if (m_state == ConnectionStateReleased) | 120 if (m_state == ConnectionStateReleased) |
| 125 return; | 121 return; |
| 126 m_resource->didDownloadData(length); | 122 m_resource->didDownloadData(length); |
| 127 } | 123 } |
| 128 | 124 |
| 129 void ResourceLoader::didFinishLoadingOnePart(double finishTime, int64_t encodedD
ataLength) | 125 void ResourceLoader::didFinishLoadingOnePart(double finishTime, int64_t encodedD
ataLength) |
| 130 { | 126 { |
| 131 ASSERT(m_state != ConnectionStateReleased); | 127 ASSERT(m_state != ConnectionStateReleased); |
| 132 if (isFinishing()) { | 128 if (m_state == ConnectionStateFinishedLoading) { |
| 133 m_fetcher->removeResourceLoader(this); | 129 m_fetcher->removeResourceLoader(this); |
| 134 } else { | 130 } else { |
| 135 // When loading a multipart resource, make the loader non-block when | 131 // When loading a multipart resource, make the loader non-block when |
| 136 // finishing loading the first part. | 132 // finishing loading the first part. |
| 137 m_fetcher->moveResourceLoaderToNonBlocking(this); | 133 m_fetcher->moveResourceLoaderToNonBlocking(this); |
| 138 | 134 |
| 139 m_fetcher->didLoadResource(m_resource.get()); | 135 m_fetcher->didLoadResource(m_resource.get()); |
| 140 if (m_state == ConnectionStateReleased) | 136 if (m_state == ConnectionStateReleased) |
| 141 return; | 137 return; |
| 142 } | 138 } |
| 143 | 139 |
| 144 if (m_notifiedLoadComplete) | 140 if (m_notifiedLoadComplete) |
| 145 return; | 141 return; |
| 146 m_notifiedLoadComplete = true; | 142 m_notifiedLoadComplete = true; |
| 147 m_fetcher->didFinishLoading(m_resource.get(), finishTime, encodedDataLength)
; | 143 m_fetcher->didFinishLoading(m_resource.get(), finishTime, encodedDataLength)
; |
| 148 } | 144 } |
| 149 | 145 |
| 150 void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority, int in
traPriorityValue) | 146 void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority, int in
traPriorityValue) |
| 151 { | 147 { |
| 152 ASSERT(m_state != ConnectionStateReleased); | 148 ASSERT(m_state != ConnectionStateReleased); |
| 153 if (m_loader) | 149 if (m_loader) |
| 154 m_loader->didChangePriority(static_cast<WebURLRequest::Priority>(loadPri
ority), intraPriorityValue); | 150 m_loader->didChangePriority(static_cast<WebURLRequest::Priority>(loadPri
ority), intraPriorityValue); |
| 155 } | 151 } |
| 156 | 152 |
| 157 void ResourceLoader::cancelIfNotFinishing() | |
| 158 { | |
| 159 if (isFinishing()) | |
| 160 return; | |
| 161 cancel(); | |
| 162 } | |
| 163 | |
| 164 void ResourceLoader::cancel() | 153 void ResourceLoader::cancel() |
| 165 { | 154 { |
| 166 cancel(ResourceError()); | 155 cancel(ResourceError()); |
| 167 } | 156 } |
| 168 | 157 |
| 169 void ResourceLoader::cancel(const ResourceError& error) | 158 void ResourceLoader::cancel(const ResourceError& error) |
| 170 { | 159 { |
| 171 // If the load has already completed - succeeded, failed, or previously canc
elled - do nothing. | 160 ASSERT(m_state != ConnectionStateFinishedLoading); |
| 172 if (m_state == ConnectionStateReleased) | 161 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 | 162 |
| 184 // If we don't immediately clear m_loader when cancelling, we might get | 163 // If we don't immediately clear m_loader when cancelling, we might get |
| 185 // unexpected reentrancy. m_resource->error() can trigger JS events, which | 164 // unexpected reentrancy. m_resource->error() can trigger JS events, which |
| 186 // could start a modal dialog. Normally, a modal dialog would defer loading | 165 // could start a modal dialog. Normally, a modal dialog would defer loading |
| 187 // and prevent receiving messages for a cancelled ResourceLoader, but | 166 // and prevent receiving messages for a cancelled ResourceLoader, but |
| 188 // m_fetcher->didFailLoading() severs the connection by which all of a | 167 // m_fetcher->didFailLoading() severs the connection by which all of a |
| 189 // page's loads are deferred. A response can then arrive, see m_state | 168 // page's loads are deferred. A response can then arrive, see m_state |
| 190 // is ConnectionStateCanceled, and ASSERT or break in other ways. | 169 // is ConnectionStateFinishedLoading, and ASSERT or break in other ways. |
| 191 if (m_loader) { | 170 if (m_loader) { |
| 192 m_loader->cancel(); | 171 m_loader->cancel(); |
| 193 m_loader.clear(); | 172 m_loader.clear(); |
| 194 } | 173 } |
| 195 | 174 didFail(nullptr, error.isNull() ? ResourceError::cancelledError(m_resource->
lastResourceRequest().url()) : error); |
| 196 if (!m_notifiedLoadComplete) { | |
| 197 m_notifiedLoadComplete = true; | |
| 198 m_fetcher->didFailLoading(m_resource.get(), nonNullError); | |
| 199 } | |
| 200 | |
| 201 if (m_state != ConnectionStateReleased) | |
| 202 m_resource->error(nonNullError); | |
| 203 if (m_state != ConnectionStateReleased) | |
| 204 releaseResources(); | |
| 205 } | 175 } |
| 206 | 176 |
| 207 void ResourceLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewR
equest, const WebURLResponse& passedRedirectResponse) | 177 void ResourceLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewR
equest, const WebURLResponse& passedRedirectResponse) |
| 208 { | 178 { |
| 209 ASSERT(m_state != ConnectionStateReleased); | 179 ASSERT(m_state != ConnectionStateReleased); |
| 210 ASSERT(!passedNewRequest.isNull()); | 180 ASSERT(!passedNewRequest.isNull()); |
| 211 ASSERT(!passedRedirectResponse.isNull()); | 181 ASSERT(!passedRedirectResponse.isNull()); |
| 212 | 182 |
| 213 ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest()); | 183 ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest()); |
| 214 const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceRe
sponse()); | 184 const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceRe
sponse()); |
| 215 newRequest.setFollowedRedirect(true); | 185 newRequest.setFollowedRedirect(true); |
| 216 | 186 |
| 217 if (m_fetcher->willFollowRedirect(m_resource.get(), newRequest, redirectResp
onse)) { | 187 if (m_fetcher->willFollowRedirect(m_resource.get(), newRequest, redirectResp
onse)) { |
| 218 m_resource->willFollowRedirect(newRequest, redirectResponse); | 188 m_resource->willFollowRedirect(newRequest, redirectResponse); |
| 219 } else { | 189 } else { |
| 220 m_resource->willNotFollowRedirect(); | 190 m_resource->willNotFollowRedirect(); |
| 221 cancel(ResourceError::cancelledDueToAccessCheckError(newRequest.url())); | 191 if (m_state != ConnectionStateReleased) |
| 192 cancel(ResourceError::cancelledDueToAccessCheckError(newRequest.url(
))); |
| 222 } | 193 } |
| 223 } | 194 } |
| 224 | 195 |
| 225 void ResourceLoader::didReceiveCachedMetadata(WebURLLoader*, const char* data, i
nt length) | 196 void ResourceLoader::didReceiveCachedMetadata(WebURLLoader*, const char* data, i
nt length) |
| 226 { | 197 { |
| 227 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse || m_state == Conn
ectionStateReceivingData); | 198 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse || m_state == Conn
ectionStateReceivingData); |
| 228 m_resource->setSerializedCachedMetadata(data, length); | 199 m_resource->setSerializedCachedMetadata(data, length); |
| 229 } | 200 } |
| 230 | 201 |
| 231 void ResourceLoader::didSendData(WebURLLoader*, unsigned long long bytesSent, un
signed long long totalBytesToBeSent) | 202 void ResourceLoader::didSendData(WebURLLoader*, unsigned long long bytesSent, un
signed long long totalBytesToBeSent) |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 // Could be an issue with a giant local file. | 280 // Could be an issue with a giant local file. |
| 310 m_fetcher->didReceiveData(m_resource.get(), data, length, encodedDataLength)
; | 281 m_fetcher->didReceiveData(m_resource.get(), data, length, encodedDataLength)
; |
| 311 if (m_state == ConnectionStateReleased) | 282 if (m_state == ConnectionStateReleased) |
| 312 return; | 283 return; |
| 313 RELEASE_ASSERT(length >= 0); | 284 RELEASE_ASSERT(length >= 0); |
| 314 m_resource->appendData(data, length); | 285 m_resource->appendData(data, length); |
| 315 } | 286 } |
| 316 | 287 |
| 317 void ResourceLoader::didFinishLoading(WebURLLoader*, double finishTime, int64_t
encodedDataLength) | 288 void ResourceLoader::didFinishLoading(WebURLLoader*, double finishTime, int64_t
encodedDataLength) |
| 318 { | 289 { |
| 319 | |
| 320 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse || m_state == Conn
ectionStateReceivingData); | 290 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse || m_state == Conn
ectionStateReceivingData); |
| 321 m_state = ConnectionStateFinishedLoading; | 291 m_state = ConnectionStateFinishedLoading; |
| 322 WTF_LOG(ResourceLoading, "Received '%s'.", m_resource->url().getString().lat
in1().data()); | |
| 323 didFinishLoadingOnePart(finishTime, encodedDataLength); | 292 didFinishLoadingOnePart(finishTime, encodedDataLength); |
| 324 if (m_state == ConnectionStateReleased) | 293 ASSERT(m_state != ConnectionStateReleased); |
| 325 return; | |
| 326 m_resource->finish(finishTime); | 294 m_resource->finish(finishTime); |
| 327 | |
| 328 // If the load has been cancelled by a delegate in response to didFinishLoad
(), do not release | |
| 329 // the resources a second time, they have been released by cancel. | |
| 330 if (m_state == ConnectionStateReleased) | |
| 331 return; | |
| 332 releaseResources(); | 295 releaseResources(); |
| 333 } | 296 } |
| 334 | 297 |
| 335 void ResourceLoader::didFail(WebURLLoader*, const WebURLError& error) | 298 void ResourceLoader::didFail(WebURLLoader*, const WebURLError& error) |
| 336 { | 299 { |
| 337 | 300 ASSERT(m_state != ConnectionStateFinishedLoading); |
| 338 ASSERT(m_state != ConnectionStateReleased); | 301 ASSERT(m_state != ConnectionStateReleased); |
| 339 m_state = ConnectionStateFailed; | 302 m_state = ConnectionStateFinishedLoading; |
| 340 WTF_LOG(ResourceLoading, "Failed to load '%s'.\n", m_resource->url().getStri
ng().latin1().data()); | 303 m_notifiedLoadComplete = true; |
| 341 if (!m_notifiedLoadComplete) { | 304 m_fetcher->didFailLoading(m_resource.get(), error); |
| 342 m_notifiedLoadComplete = true; | 305 ASSERT(m_state != ConnectionStateReleased); |
| 343 m_fetcher->didFailLoading(m_resource.get(), error); | |
| 344 } | |
| 345 if (m_state == ConnectionStateReleased) | |
| 346 return; | |
| 347 | |
| 348 m_resource->error(error); | 306 m_resource->error(error); |
| 349 | |
| 350 if (m_state == ConnectionStateReleased) | |
| 351 return; | |
| 352 | |
| 353 releaseResources(); | 307 releaseResources(); |
| 354 } | 308 } |
| 355 | 309 |
| 356 void ResourceLoader::requestSynchronously(ResourceRequest& request) | 310 void ResourceLoader::requestSynchronously(ResourceRequest& request) |
| 357 { | 311 { |
| 358 // downloadToFile is not supported for synchronous requests. | 312 // downloadToFile is not supported for synchronous requests. |
| 359 ASSERT(!request.downloadToFile()); | 313 ASSERT(!request.downloadToFile()); |
| 360 ASSERT(m_loader); | 314 ASSERT(m_loader); |
| 361 | 315 |
| 362 // Synchronous requests should always be max priority, lest they hang the re
nderer. | 316 // 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... |
| 394 // empty buffer is a noop in most cases, but is destructive in the case of | 348 // empty buffer is a noop in most cases, but is destructive in the case of |
| 395 // a 304, where it will overwrite the cached data we should be reusing. | 349 // a 304, where it will overwrite the cached data we should be reusing. |
| 396 if (dataOut.size()) { | 350 if (dataOut.size()) { |
| 397 m_fetcher->didReceiveData(m_resource.get(), dataOut.data(), dataOut.size
(), encodedDataLength); | 351 m_fetcher->didReceiveData(m_resource.get(), dataOut.data(), dataOut.size
(), encodedDataLength); |
| 398 m_resource->setResourceBuffer(dataOut); | 352 m_resource->setResourceBuffer(dataOut); |
| 399 } | 353 } |
| 400 didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); | 354 didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); |
| 401 } | 355 } |
| 402 | 356 |
| 403 } // namespace blink | 357 } // namespace blink |
| OLD | NEW |