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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 return loader; | 65 return loader; |
| 66 } | 66 } |
| 67 | 67 |
| 68 ResourceLoader::ResourceLoader(ResourceFetcher* fetcher, Resource* resource, con st ResourceLoaderOptions& options) | 68 ResourceLoader::ResourceLoader(ResourceFetcher* fetcher, Resource* resource, con st ResourceLoaderOptions& options) |
| 69 : m_fetcher(fetcher) | 69 : m_fetcher(fetcher) |
| 70 , m_notifiedLoadComplete(false) | 70 , m_notifiedLoadComplete(false) |
| 71 , m_defersLoading(fetcher->defersLoading()) | 71 , m_defersLoading(fetcher->defersLoading()) |
| 72 , m_loadingMultipartContent(false) | 72 , m_loadingMultipartContent(false) |
| 73 , m_options(options) | 73 , m_options(options) |
| 74 , m_resource(resource) | 74 , m_resource(resource) |
| 75 , m_state(Initialized) | 75 , m_state(ConnectionStateNew) |
| 76 , m_connectionState(ConnectionStateNew) | |
| 77 { | 76 { |
| 78 ASSERT(m_resource); | 77 ASSERT(m_resource); |
| 79 ASSERT(m_fetcher); | 78 ASSERT(m_fetcher); |
| 80 } | 79 } |
| 81 | 80 |
| 82 ResourceLoader::~ResourceLoader() | 81 ResourceLoader::~ResourceLoader() |
| 83 { | 82 { |
| 84 ASSERT(m_state == Terminated); | 83 ASSERT(m_state == ConnectionStateReleased); |
| 85 } | 84 } |
| 86 | 85 |
| 87 DEFINE_TRACE(ResourceLoader) | 86 DEFINE_TRACE(ResourceLoader) |
| 88 { | 87 { |
| 89 visitor->trace(m_fetcher); | 88 visitor->trace(m_fetcher); |
| 90 visitor->trace(m_resource); | 89 visitor->trace(m_resource); |
| 91 } | 90 } |
| 92 | 91 |
| 93 void ResourceLoader::releaseResources() | 92 void ResourceLoader::releaseResources() |
| 94 { | 93 { |
| 95 ASSERT(m_state != Terminated); | 94 ASSERT(m_state != ConnectionStateReleased); |
| 96 ASSERT(m_notifiedLoadComplete); | 95 ASSERT(m_notifiedLoadComplete); |
| 97 m_fetcher->didLoadResource(m_resource.get()); | 96 m_fetcher->didLoadResource(m_resource.get()); |
| 98 if (m_state == Terminated) | 97 if (m_state == ConnectionStateReleased) |
| 99 return; | 98 return; |
| 100 m_resource->clearLoader(); | 99 m_resource->clearLoader(); |
| 101 m_resource = nullptr; | 100 m_resource = nullptr; |
| 102 | 101 |
| 103 ASSERT(m_state != Terminated); | 102 ASSERT(m_state != ConnectionStateReleased); |
| 104 | 103 m_state = ConnectionStateReleased; |
| 105 m_state = Terminated; | |
| 106 if (m_loader) { | 104 if (m_loader) { |
| 107 m_loader->cancel(); | 105 m_loader->cancel(); |
| 108 m_loader.clear(); | 106 m_loader.clear(); |
| 109 } | 107 } |
| 110 m_deferredRequest = ResourceRequest(); | 108 m_deferredRequest = ResourceRequest(); |
| 111 m_fetcher.clear(); | 109 m_fetcher.clear(); |
| 112 } | 110 } |
| 113 | 111 |
| 114 void ResourceLoader::init(const ResourceRequest& passedRequest) | 112 void ResourceLoader::init(const ResourceRequest& passedRequest) |
| 115 { | 113 { |
| 116 ASSERT(m_state != Terminated); | |
| 117 ResourceRequest request(passedRequest); | 114 ResourceRequest request(passedRequest); |
| 118 m_fetcher->willSendRequest(m_resource->identifier(), request, ResourceRespon se(), m_options.initiatorInfo); | 115 m_fetcher->willSendRequest(m_resource->identifier(), request, ResourceRespon se(), m_options.initiatorInfo); |
| 119 ASSERT(m_state != Terminated); | |
| 120 ASSERT(!request.isNull()); | |
| 121 m_originalRequest = m_request = applyOptions(request); | 116 m_originalRequest = m_request = applyOptions(request); |
| 122 m_resource->updateRequest(request); | 117 m_resource->updateRequest(request); |
| 123 ASSERT(m_state != Terminated); | |
| 124 m_fetcher->didInitializeResourceLoader(this); | 118 m_fetcher->didInitializeResourceLoader(this); |
| 125 } | 119 } |
| 126 | 120 |
| 127 void ResourceLoader::start() | 121 void ResourceLoader::start() |
| 128 { | 122 { |
| 129 ASSERT(!m_loader); | 123 ASSERT(!m_loader); |
| 130 ASSERT(!m_request.isNull()); | 124 ASSERT(!m_request.isNull()); |
| 131 ASSERT(m_deferredRequest.isNull()); | 125 ASSERT(m_deferredRequest.isNull()); |
| 132 | 126 |
| 133 m_fetcher->willStartLoadingResource(m_resource.get(), m_request); | 127 m_fetcher->willStartLoadingResource(m_resource.get(), m_request); |
| 134 | 128 |
| 129 if (m_defersLoading) { | |
| 130 m_deferredRequest = m_request; | |
| 131 return; | |
| 132 } | |
| 133 | |
| 135 if (m_options.synchronousPolicy == RequestSynchronously) { | 134 if (m_options.synchronousPolicy == RequestSynchronously) { |
| 136 requestSynchronously(); | 135 requestSynchronously(); |
| 137 return; | 136 return; |
| 138 } | 137 } |
| 139 | 138 |
| 140 if (m_defersLoading) { | 139 RELEASE_ASSERT(m_state == ConnectionStateNew); |
| 141 m_deferredRequest = m_request; | 140 m_state = ConnectionStateStarted; |
| 142 return; | |
| 143 } | |
| 144 | |
| 145 if (m_state == Terminated) | |
| 146 return; | |
| 147 | |
| 148 RELEASE_ASSERT(m_connectionState == ConnectionStateNew); | |
| 149 m_connectionState = ConnectionStateStarted; | |
| 150 | 141 |
| 151 m_loader = adoptPtr(Platform::current()->createURLLoader()); | 142 m_loader = adoptPtr(Platform::current()->createURLLoader()); |
| 152 ASSERT(m_loader); | 143 ASSERT(m_loader); |
| 153 m_loader->setLoadingTaskRunner(m_fetcher->loadingTaskRunner()); | 144 m_loader->setLoadingTaskRunner(m_fetcher->loadingTaskRunner()); |
| 154 WrappedResourceRequest wrappedRequest(m_request); | 145 WrappedResourceRequest wrappedRequest(m_request); |
| 155 m_loader->loadAsynchronously(wrappedRequest, this); | 146 m_loader->loadAsynchronously(wrappedRequest, this); |
| 156 } | 147 } |
| 157 | 148 |
| 158 void ResourceLoader::changeToSynchronous() | 149 void ResourceLoader::changeToSynchronous() |
| 159 { | 150 { |
| 160 ASSERT(m_options.synchronousPolicy == RequestAsynchronously); | 151 ASSERT(m_options.synchronousPolicy == RequestAsynchronously); |
| 161 ASSERT(m_loader); | 152 ASSERT(m_loader); |
| 162 m_loader->cancel(); | 153 m_loader->cancel(); |
| 163 m_loader.clear(); | 154 m_loader.clear(); |
| 164 m_request.setPriority(ResourceLoadPriorityHighest); | 155 m_request.setPriority(ResourceLoadPriorityHighest); |
| 165 m_connectionState = ConnectionStateNew; | 156 m_state = ConnectionStateNew; |
| 166 requestSynchronously(); | 157 requestSynchronously(); |
| 167 } | 158 } |
| 168 | 159 |
| 169 void ResourceLoader::setDefersLoading(bool defers) | 160 void ResourceLoader::setDefersLoading(bool defers) |
| 170 { | 161 { |
| 171 m_defersLoading = defers; | 162 m_defersLoading = defers; |
| 172 if (m_loader) | 163 if (m_loader) |
| 173 m_loader->setDefersLoading(defers); | 164 m_loader->setDefersLoading(defers); |
| 174 if (!defers && !m_deferredRequest.isNull()) { | 165 if (!defers && !m_deferredRequest.isNull()) { |
| 175 m_request = applyOptions(m_deferredRequest); | 166 m_request = applyOptions(m_deferredRequest); |
| 176 m_deferredRequest = ResourceRequest(); | 167 m_deferredRequest = ResourceRequest(); |
| 177 start(); | 168 start(); |
| 178 } | 169 } |
| 179 } | 170 } |
| 180 | 171 |
| 181 void ResourceLoader::attachThreadedDataReceiver(PassRefPtrWillBeRawPtr<ThreadedD ataReceiver> threadedDataReceiver) | 172 void ResourceLoader::attachThreadedDataReceiver(PassRefPtrWillBeRawPtr<ThreadedD ataReceiver> threadedDataReceiver) |
| 182 { | 173 { |
| 183 if (m_loader) { | 174 if (m_loader) { |
| 184 // The implementor of the WebURLLoader assumes ownership of the | 175 // The implementor of the WebURLLoader assumes ownership of the |
| 185 // threaded data receiver if it signals that it got successfully | 176 // threaded data receiver if it signals that it got successfully |
| 186 // attached. | 177 // attached. |
| 187 WebThreadedDataReceiver* webDataReceiver = new WebThreadedDataReceiver(t hreadedDataReceiver); | 178 WebThreadedDataReceiver* webDataReceiver = new WebThreadedDataReceiver(t hreadedDataReceiver); |
| 188 if (!m_loader->attachThreadedDataReceiver(webDataReceiver)) | 179 if (!m_loader->attachThreadedDataReceiver(webDataReceiver)) |
| 189 delete webDataReceiver; | 180 delete webDataReceiver; |
| 190 } | 181 } |
| 191 } | 182 } |
| 192 | 183 |
| 193 void ResourceLoader::didDownloadData(WebURLLoader*, int length, int encodedDataL ength) | 184 void ResourceLoader::didDownloadData(WebURLLoader*, int length, int encodedDataL ength) |
| 194 { | 185 { |
| 195 ASSERT(m_state != Terminated); | 186 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse); |
| 196 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse); | |
| 197 m_fetcher->didDownloadData(m_resource.get(), length, encodedDataLength); | 187 m_fetcher->didDownloadData(m_resource.get(), length, encodedDataLength); |
| 198 if (m_state == Terminated) | 188 if (m_state == ConnectionStateReleased) |
| 199 return; | 189 return; |
| 200 m_resource->didDownloadData(length); | 190 m_resource->didDownloadData(length); |
| 201 } | 191 } |
| 202 | 192 |
| 203 void ResourceLoader::didFinishLoadingOnePart(double finishTime, int64_t encodedD ataLength) | 193 void ResourceLoader::didFinishLoadingOnePart(double finishTime, int64_t encodedD ataLength) |
| 204 { | 194 { |
| 205 // If load has been cancelled after finishing (which could happen with a | 195 // If load has been cancelled after finishing (which could happen with a |
| 206 // JavaScript that changes the window location), do nothing. | 196 // JavaScript that changes the window location), do nothing. |
| 207 if (m_state == Terminated) | 197 if (m_state == ConnectionStateReleased) |
| 208 return; | 198 return; |
| 209 | 199 |
| 210 if (m_notifiedLoadComplete) | 200 if (m_notifiedLoadComplete) |
| 211 return; | 201 return; |
| 212 m_notifiedLoadComplete = true; | 202 m_notifiedLoadComplete = true; |
| 213 m_fetcher->didFinishLoading(m_resource.get(), finishTime, encodedDataLength) ; | 203 m_fetcher->didFinishLoading(m_resource.get(), finishTime, encodedDataLength) ; |
| 214 } | 204 } |
| 215 | 205 |
| 216 void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority, int in traPriorityValue) | 206 void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority, int in traPriorityValue) |
| 217 { | 207 { |
| 218 ASSERT(m_state != Terminated); | 208 ASSERT(m_state != ConnectionStateReleased); |
| 219 if (m_loader) | 209 if (m_loader) |
| 220 m_loader->didChangePriority(static_cast<WebURLRequest::Priority>(loadPri ority), intraPriorityValue); | 210 m_loader->didChangePriority(static_cast<WebURLRequest::Priority>(loadPri ority), intraPriorityValue); |
| 221 } | 211 } |
| 222 | 212 |
| 223 void ResourceLoader::cancelIfNotFinishing() | 213 void ResourceLoader::cancelIfNotFinishing() |
| 224 { | 214 { |
| 225 if (m_state != Initialized) | 215 if (m_state > ConnectionStateReceivingData) |
| 226 return; | 216 return; |
| 227 cancel(); | 217 cancel(); |
| 228 } | 218 } |
| 229 | 219 |
| 230 void ResourceLoader::cancel() | 220 void ResourceLoader::cancel() |
| 231 { | 221 { |
| 232 cancel(ResourceError()); | 222 cancel(ResourceError()); |
| 233 } | 223 } |
| 234 | 224 |
| 235 void ResourceLoader::cancel(const ResourceError& error) | 225 void ResourceLoader::cancel(const ResourceError& error) |
| 236 { | 226 { |
| 237 // If the load has already completed - succeeded, failed, or previously canc elled - do nothing. | 227 // If the load has already completed - succeeded, failed, or previously canc elled - do nothing. |
| 238 if (m_state == Terminated) | 228 if (m_state == ConnectionStateReleased) |
| 239 return; | 229 return; |
| 240 if (m_state == Finishing) { | 230 if (m_state >= ConnectionStateFinishedLoading) { |
|
yhirano
2016/03/02 20:37:32
How about having |isFinishing| predicate?
Nate Chapin
2016/03/02 23:08:07
Done.
| |
| 241 releaseResources(); | 231 releaseResources(); |
| 242 return; | 232 return; |
| 243 } | 233 } |
| 244 | 234 |
| 245 ResourceError nonNullError = error.isNull() ? ResourceError::cancelledError( m_request.url()) : error; | 235 ResourceError nonNullError = error.isNull() ? ResourceError::cancelledError( m_request.url()) : error; |
| 246 | 236 |
| 247 WTF_LOG(ResourceLoading, "Cancelled load of '%s'.\n", m_resource->url().stri ng().latin1().data()); | 237 WTF_LOG(ResourceLoading, "Cancelled load of '%s'.\n", m_resource->url().stri ng().latin1().data()); |
| 248 if (m_state == Initialized) | 238 m_state = ConnectionStateCanceled; |
| 249 m_state = Finishing; | |
| 250 m_resource->setResourceError(nonNullError); | 239 m_resource->setResourceError(nonNullError); |
| 251 | 240 |
| 252 if (m_loader) { | |
| 253 m_connectionState = ConnectionStateCanceled; | |
| 254 m_loader->cancel(); | |
| 255 m_loader.clear(); | |
| 256 } | |
| 257 | |
| 258 if (!m_notifiedLoadComplete) { | 241 if (!m_notifiedLoadComplete) { |
| 259 m_notifiedLoadComplete = true; | 242 m_notifiedLoadComplete = true; |
| 260 m_fetcher->didFailLoading(m_resource.get(), nonNullError); | 243 m_fetcher->didFailLoading(m_resource.get(), nonNullError); |
| 261 } | 244 } |
| 262 | 245 |
| 263 if (m_state == Finishing) | 246 if (m_state != ConnectionStateReleased) |
| 264 m_resource->error(Resource::LoadError); | 247 m_resource->error(Resource::LoadError); |
| 265 if (m_state != Terminated) | 248 if (m_state != ConnectionStateReleased) |
| 266 releaseResources(); | 249 releaseResources(); |
| 267 } | 250 } |
| 268 | 251 |
| 269 void ResourceLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewR equest, const WebURLResponse& passedRedirectResponse) | 252 void ResourceLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewR equest, const WebURLResponse& passedRedirectResponse) |
| 270 { | 253 { |
| 271 ASSERT(m_state != Terminated); | 254 ASSERT(m_state != ConnectionStateReleased); |
| 272 | 255 |
| 273 ResourceRequest& newRequest(applyOptions(passedNewRequest.toMutableResourceR equest())); | 256 ResourceRequest& newRequest(applyOptions(passedNewRequest.toMutableResourceR equest())); |
| 274 | 257 |
| 275 ASSERT(!newRequest.isNull()); | 258 ASSERT(!newRequest.isNull()); |
| 276 const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceRe sponse()); | 259 const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceRe sponse()); |
| 277 ASSERT(!redirectResponse.isNull()); | 260 ASSERT(!redirectResponse.isNull()); |
| 278 newRequest.setFollowedRedirect(true); | 261 newRequest.setFollowedRedirect(true); |
| 279 if (!isManualRedirectFetchRequest(m_resource->resourceRequest()) && !m_fetch er->canAccessRedirect(m_resource.get(), newRequest, redirectResponse, m_options) ) { | 262 if (!isManualRedirectFetchRequest(m_resource->resourceRequest()) && !m_fetch er->canAccessRedirect(m_resource.get(), newRequest, redirectResponse, m_options) ) { |
| 280 cancel(ResourceError::cancelledDueToAccessCheckError(newRequest.url())); | 263 cancel(ResourceError::cancelledDueToAccessCheckError(newRequest.url())); |
| 281 return; | 264 return; |
| 282 } | 265 } |
| 283 ASSERT(m_state != Terminated); | 266 ASSERT(m_state != ConnectionStateReleased); |
| 284 | 267 |
| 285 applyOptions(newRequest); // canAccessRedirect() can modify m_options so we should re-apply it. | 268 applyOptions(newRequest); // canAccessRedirect() can modify m_options so we should re-apply it. |
| 286 m_fetcher->redirectReceived(m_resource.get(), redirectResponse); | 269 m_fetcher->redirectReceived(m_resource.get(), redirectResponse); |
| 287 ASSERT(m_state != Terminated); | 270 ASSERT(m_state != ConnectionStateReleased); |
| 288 m_resource->willFollowRedirect(newRequest, redirectResponse); | 271 m_resource->willFollowRedirect(newRequest, redirectResponse); |
| 289 if (newRequest.isNull() || m_state == Terminated) | 272 if (newRequest.isNull() || m_state == ConnectionStateReleased) |
| 290 return; | 273 return; |
| 291 | 274 |
| 292 m_fetcher->willSendRequest(m_resource->identifier(), newRequest, redirectRes ponse, m_options.initiatorInfo); | 275 m_fetcher->willSendRequest(m_resource->identifier(), newRequest, redirectRes ponse, m_options.initiatorInfo); |
| 293 ASSERT(m_state != Terminated); | 276 ASSERT(m_state != ConnectionStateReleased); |
| 294 ASSERT(!newRequest.isNull()); | 277 ASSERT(!newRequest.isNull()); |
| 295 m_resource->updateRequest(newRequest); | 278 m_resource->updateRequest(newRequest); |
| 296 m_request = newRequest; | 279 m_request = newRequest; |
| 297 } | 280 } |
| 298 | 281 |
| 299 void ResourceLoader::didReceiveCachedMetadata(WebURLLoader*, const char* data, i nt length) | 282 void ResourceLoader::didReceiveCachedMetadata(WebURLLoader*, const char* data, i nt length) |
| 300 { | 283 { |
| 301 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse || m_con nectionState == ConnectionStateReceivingData); | 284 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse || m_state == Conn ectionStateReceivingData); |
| 302 ASSERT(m_state == Initialized); | |
| 303 m_resource->setSerializedCachedMetadata(data, length); | 285 m_resource->setSerializedCachedMetadata(data, length); |
| 304 } | 286 } |
| 305 | 287 |
| 306 void ResourceLoader::didSendData(WebURLLoader*, unsigned long long bytesSent, un signed long long totalBytesToBeSent) | 288 void ResourceLoader::didSendData(WebURLLoader*, unsigned long long bytesSent, un signed long long totalBytesToBeSent) |
| 307 { | 289 { |
| 308 ASSERT(m_state == Initialized); | |
| 309 m_resource->didSendData(bytesSent, totalBytesToBeSent); | 290 m_resource->didSendData(bytesSent, totalBytesToBeSent); |
| 310 } | 291 } |
| 311 | 292 |
| 312 bool ResourceLoader::responseNeedsAccessControlCheck() const | 293 bool ResourceLoader::responseNeedsAccessControlCheck() const |
| 313 { | 294 { |
| 314 // If the fetch was (potentially) CORS enabled, an access control check of t he response is required. | 295 // If the fetch was (potentially) CORS enabled, an access control check of t he response is required. |
| 315 return m_options.corsEnabled == IsCORSEnabled; | 296 return m_options.corsEnabled == IsCORSEnabled; |
| 316 } | 297 } |
| 317 | 298 |
| 318 void ResourceLoader::didReceiveResponse(WebURLLoader*, const WebURLResponse& res ponse, WebDataConsumerHandle* rawHandle) | 299 void ResourceLoader::didReceiveResponse(WebURLLoader*, const WebURLResponse& res ponse, WebDataConsumerHandle* rawHandle) |
| 319 { | 300 { |
| 320 ASSERT(!response.isNull()); | 301 ASSERT(!response.isNull()); |
| 321 ASSERT(m_state == Initialized); | |
| 322 // |rawHandle|'s ownership is transferred to the callee. | 302 // |rawHandle|'s ownership is transferred to the callee. |
| 323 OwnPtr<WebDataConsumerHandle> handle = adoptPtr(rawHandle); | 303 OwnPtr<WebDataConsumerHandle> handle = adoptPtr(rawHandle); |
| 324 | 304 |
| 325 bool isMultipartPayload = response.isMultipartPayload(); | 305 bool isMultipartPayload = response.isMultipartPayload(); |
| 326 bool isValidStateTransition = (m_connectionState == ConnectionStateStarted | | m_connectionState == ConnectionStateReceivedResponse); | 306 bool isValidStateTransition = (m_state == ConnectionStateStarted || m_state == ConnectionStateReceivedResponse); |
| 327 // In the case of multipart loads, calls to didReceiveData & didReceiveRespo nse can be interleaved. | 307 // In the case of multipart loads, calls to didReceiveData & didReceiveRespo nse can be interleaved. |
| 328 RELEASE_ASSERT(isMultipartPayload || isValidStateTransition); | 308 RELEASE_ASSERT(isMultipartPayload || isValidStateTransition); |
| 329 m_connectionState = ConnectionStateReceivedResponse; | 309 m_state = ConnectionStateReceivedResponse; |
| 330 | 310 |
| 331 const ResourceResponse& resourceResponse = response.toResourceResponse(); | 311 const ResourceResponse& resourceResponse = response.toResourceResponse(); |
| 332 | 312 |
| 333 if (responseNeedsAccessControlCheck()) { | 313 if (responseNeedsAccessControlCheck()) { |
| 334 if (response.wasFetchedViaServiceWorker()) { | 314 if (response.wasFetchedViaServiceWorker()) { |
| 335 if (response.wasFallbackRequiredByServiceWorker()) { | 315 if (response.wasFallbackRequiredByServiceWorker()) { |
| 336 m_loader->cancel(); | 316 m_loader->cancel(); |
| 337 m_loader.clear(); | 317 m_loader.clear(); |
| 338 m_connectionState = ConnectionStateStarted; | 318 m_state = ConnectionStateStarted; |
| 339 m_loader = adoptPtr(Platform::current()->createURLLoader()); | 319 m_loader = adoptPtr(Platform::current()->createURLLoader()); |
| 340 ASSERT(m_loader); | 320 ASSERT(m_loader); |
| 341 ASSERT(!m_request.skipServiceWorker()); | 321 ASSERT(!m_request.skipServiceWorker()); |
| 342 m_request.setSkipServiceWorker(true); | 322 m_request.setSkipServiceWorker(true); |
| 343 WrappedResourceRequest wrappedRequest(m_request); | 323 WrappedResourceRequest wrappedRequest(m_request); |
| 344 m_loader->loadAsynchronously(wrappedRequest, this); | 324 m_loader->loadAsynchronously(wrappedRequest, this); |
| 345 return; | 325 return; |
| 346 } | 326 } |
| 347 } else { | 327 } else { |
| 348 if (!m_resource->isCacheValidator() || resourceResponse.httpStatusCo de() != 304) | 328 if (!m_resource->isCacheValidator() || resourceResponse.httpStatusCo de() != 304) |
| 349 m_resource->setResponse(resourceResponse); | 329 m_resource->setResponse(resourceResponse); |
| 350 if (!m_fetcher->canAccessResource(m_resource.get(), m_options.securi tyOrigin.get(), response.url(), ResourceFetcher::ShouldLogAccessControlErrors)) { | 330 if (!m_fetcher->canAccessResource(m_resource.get(), m_options.securi tyOrigin.get(), response.url(), ResourceFetcher::ShouldLogAccessControlErrors)) { |
| 351 m_fetcher->didReceiveResponse(m_resource.get(), resourceResponse ); | 331 m_fetcher->didReceiveResponse(m_resource.get(), resourceResponse ); |
| 352 cancel(ResourceError::cancelledDueToAccessCheckError(KURL(respon se.url()))); | 332 cancel(ResourceError::cancelledDueToAccessCheckError(KURL(respon se.url()))); |
| 353 return; | 333 return; |
| 354 } | 334 } |
| 355 } | 335 } |
| 356 } | 336 } |
| 357 | 337 |
| 358 m_resource->responseReceived(resourceResponse, handle.release()); | 338 m_resource->responseReceived(resourceResponse, handle.release()); |
| 359 if (m_state == Terminated) | 339 if (m_state == ConnectionStateReleased) |
| 360 return; | 340 return; |
| 361 | 341 |
| 362 m_fetcher->didReceiveResponse(m_resource.get(), resourceResponse); | 342 m_fetcher->didReceiveResponse(m_resource.get(), resourceResponse); |
| 363 if (m_state == Terminated) | 343 if (m_state == ConnectionStateReleased) |
| 364 return; | 344 return; |
| 365 | 345 |
| 366 if (response.toResourceResponse().isMultipart()) { | 346 if (response.toResourceResponse().isMultipart()) { |
| 367 // We only support multipart for images, though the image may be loaded | 347 // We only support multipart for images, though the image may be loaded |
| 368 // as a main resource that we end up displaying through an ImageDocument . | 348 // as a main resource that we end up displaying through an ImageDocument . |
| 369 if (!m_resource->isImage() && m_resource->getType() != Resource::MainRes ource) { | 349 if (!m_resource->isImage() && m_resource->getType() != Resource::MainRes ource) { |
| 370 cancel(); | 350 cancel(); |
| 371 return; | 351 return; |
| 372 } | 352 } |
| 373 m_loadingMultipartContent = true; | 353 m_loadingMultipartContent = true; |
| 374 } else if (isMultipartPayload) { | 354 } else if (isMultipartPayload) { |
| 375 // Since a subresource loader does not load multipart sections progressi vely, data was delivered to the loader all at once. | 355 // Since a subresource loader does not load multipart sections progressi vely, data was delivered to the loader all at once. |
| 376 // After the first multipart section is complete, signal to delegates th at this load is "finished" | 356 // After the first multipart section is complete, signal to delegates th at this load is "finished" |
| 377 m_fetcher->subresourceLoaderFinishedLoadingOnePart(this); | 357 m_fetcher->subresourceLoaderFinishedLoadingOnePart(this); |
| 378 didFinishLoadingOnePart(0, WebURLLoaderClient::kUnknownEncodedDataLength ); | 358 didFinishLoadingOnePart(0, WebURLLoaderClient::kUnknownEncodedDataLength ); |
| 379 } | 359 } |
| 380 if (m_state == Terminated) | 360 if (m_state == ConnectionStateReleased) |
| 381 return; | 361 return; |
| 382 | 362 |
| 383 if (m_resource->response().httpStatusCode() < 400 || m_resource->shouldIgnor eHTTPStatusCodeErrors()) | 363 if (m_resource->response().httpStatusCode() < 400 || m_resource->shouldIgnor eHTTPStatusCodeErrors()) |
| 384 return; | 364 return; |
| 385 m_state = Finishing; | |
| 386 | 365 |
| 387 if (!m_notifiedLoadComplete) { | 366 if (!m_notifiedLoadComplete) { |
| 388 m_notifiedLoadComplete = true; | 367 m_notifiedLoadComplete = true; |
| 389 m_fetcher->didFailLoading(m_resource.get(), ResourceError::cancelledErro r(m_request.url())); | 368 m_fetcher->didFailLoading(m_resource.get(), ResourceError::cancelledErro r(m_request.url())); |
| 390 } | 369 } |
| 391 | 370 |
| 392 ASSERT(m_state != Terminated); | 371 ASSERT(m_state != ConnectionStateReleased); |
| 393 m_resource->error(Resource::LoadError); | 372 m_resource->error(Resource::LoadError); |
| 394 cancel(); | 373 cancel(); |
| 395 } | 374 } |
| 396 | 375 |
| 397 void ResourceLoader::didReceiveResponse(WebURLLoader* loader, const WebURLRespon se& response) | 376 void ResourceLoader::didReceiveResponse(WebURLLoader* loader, const WebURLRespon se& response) |
| 398 { | 377 { |
| 399 didReceiveResponse(loader, response, nullptr); | 378 didReceiveResponse(loader, response, nullptr); |
| 400 } | 379 } |
| 401 | 380 |
| 402 void ResourceLoader::didReceiveData(WebURLLoader*, const char* data, int length, int encodedDataLength) | 381 void ResourceLoader::didReceiveData(WebURLLoader*, const char* data, int length, int encodedDataLength) |
| 403 { | 382 { |
| 404 ASSERT(m_state != Terminated); | 383 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse || m_state == Conn ectionStateReceivingData); |
| 405 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse || m_con nectionState == ConnectionStateReceivingData); | 384 m_state = ConnectionStateReceivingData; |
| 406 m_connectionState = ConnectionStateReceivingData; | |
| 407 | 385 |
| 408 // It is possible to receive data on uninitialized resources if it had an er ror status code, and we are running a nested message | 386 // It is possible to receive data on uninitialized resources if it had an er ror status code, and we are running a nested message |
| 409 // loop. When this occurs, ignoring the data is the correct action. | 387 // loop. When this occurs, ignoring the data is the correct action. |
| 410 if (m_resource->response().httpStatusCode() >= 400 && !m_resource->shouldIgn oreHTTPStatusCodeErrors()) | 388 if (m_resource->response().httpStatusCode() >= 400 && !m_resource->shouldIgn oreHTTPStatusCodeErrors()) |
| 411 return; | 389 return; |
| 412 ASSERT(m_state == Initialized); | |
| 413 | 390 |
| 414 // FIXME: If we get a resource with more than 2B bytes, this code won't do t he right thing. | 391 // FIXME: If we get a resource with more than 2B bytes, this code won't do t he right thing. |
| 415 // However, with today's computers and networking speeds, this won't happen in practice. | 392 // However, with today's computers and networking speeds, this won't happen in practice. |
| 416 // Could be an issue with a giant local file. | 393 // Could be an issue with a giant local file. |
| 417 m_fetcher->didReceiveData(m_resource.get(), data, length, encodedDataLength) ; | 394 m_fetcher->didReceiveData(m_resource.get(), data, length, encodedDataLength) ; |
| 418 if (m_state == Terminated) | 395 if (m_state == ConnectionStateReleased) |
| 419 return; | 396 return; |
| 420 RELEASE_ASSERT(length >= 0); | 397 RELEASE_ASSERT(length >= 0); |
| 421 m_resource->appendData(data, length); | 398 m_resource->appendData(data, length); |
| 422 } | 399 } |
| 423 | 400 |
| 424 void ResourceLoader::didFinishLoading(WebURLLoader*, double finishTime, int64_t encodedDataLength) | 401 void ResourceLoader::didFinishLoading(WebURLLoader*, double finishTime, int64_t encodedDataLength) |
| 425 { | 402 { |
| 426 RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse || m_con nectionState == ConnectionStateReceivingData); | 403 RELEASE_ASSERT(m_state == ConnectionStateReceivedResponse || m_state == Conn ectionStateReceivingData); |
| 427 m_connectionState = ConnectionStateFinishedLoading; | 404 m_state = ConnectionStateFinishedLoading; |
| 428 if (m_state != Initialized) | |
| 429 return; | |
| 430 ASSERT(m_state != Terminated); | |
| 431 WTF_LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1 ().data()); | 405 WTF_LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1 ().data()); |
| 432 | 406 |
| 433 RefPtrWillBeRawPtr<Resource> protectResource(m_resource.get()); | 407 RefPtrWillBeRawPtr<Resource> protectResource(m_resource.get()); |
| 434 m_state = Finishing; | |
| 435 m_resource->setLoadFinishTime(finishTime); | 408 m_resource->setLoadFinishTime(finishTime); |
| 436 didFinishLoadingOnePart(finishTime, encodedDataLength); | 409 didFinishLoadingOnePart(finishTime, encodedDataLength); |
| 437 if (m_state == Terminated) | 410 if (m_state == ConnectionStateReleased) |
| 438 return; | 411 return; |
| 439 m_resource->finish(); | 412 m_resource->finish(); |
| 440 | 413 |
| 441 // If the load has been cancelled by a delegate in response to didFinishLoad (), do not release | 414 // If the load has been cancelled by a delegate in response to didFinishLoad (), do not release |
| 442 // the resources a second time, they have been released by cancel. | 415 // the resources a second time, they have been released by cancel. |
| 443 if (m_state == Terminated) | 416 if (m_state == ConnectionStateReleased) |
| 444 return; | 417 return; |
| 445 releaseResources(); | 418 releaseResources(); |
| 446 } | 419 } |
| 447 | 420 |
| 448 void ResourceLoader::didFail(WebURLLoader*, const WebURLError& error) | 421 void ResourceLoader::didFail(WebURLLoader*, const WebURLError& error) |
| 449 { | 422 { |
| 450 m_connectionState = ConnectionStateFailed; | 423 ASSERT(m_state != ConnectionStateReleased); |
| 451 ASSERT(m_state != Terminated); | 424 m_state = ConnectionStateFailed; |
| 452 WTF_LOG(ResourceLoading, "Failed to load '%s'.\n", m_resource->url().string( ).latin1().data()); | 425 WTF_LOG(ResourceLoading, "Failed to load '%s'.\n", m_resource->url().string( ).latin1().data()); |
| 453 | 426 |
| 454 RefPtrWillBeRawPtr<Resource> protectResource(m_resource.get()); | 427 RefPtrWillBeRawPtr<Resource> protectResource(m_resource.get()); |
| 455 m_state = Finishing; | |
| 456 m_resource->setResourceError(error); | 428 m_resource->setResourceError(error); |
| 457 | 429 |
| 458 if (!m_notifiedLoadComplete) { | 430 if (!m_notifiedLoadComplete) { |
| 459 m_notifiedLoadComplete = true; | 431 m_notifiedLoadComplete = true; |
| 460 m_fetcher->didFailLoading(m_resource.get(), error); | 432 m_fetcher->didFailLoading(m_resource.get(), error); |
| 461 } | 433 } |
| 462 if (m_state == Terminated) | 434 if (m_state == ConnectionStateReleased) |
| 463 return; | 435 return; |
| 464 | 436 |
| 465 m_resource->error(Resource::LoadError); | 437 m_resource->error(Resource::LoadError); |
| 466 | 438 |
| 467 if (m_state == Terminated) | 439 if (m_state == ConnectionStateReleased) |
| 468 return; | 440 return; |
| 469 | 441 |
| 470 releaseResources(); | 442 releaseResources(); |
| 471 } | 443 } |
| 472 | 444 |
| 473 bool ResourceLoader::isLoadedBy(ResourceFetcher* loader) const | 445 bool ResourceLoader::isLoadedBy(ResourceFetcher* loader) const |
| 474 { | 446 { |
| 475 return m_fetcher->isLoadedBy(loader); | 447 return m_fetcher->isLoadedBy(loader); |
| 476 } | 448 } |
| 477 | 449 |
| 478 void ResourceLoader::requestSynchronously() | 450 void ResourceLoader::requestSynchronously() |
| 479 { | 451 { |
| 480 OwnPtr<WebURLLoader> loader = adoptPtr(Platform::current()->createURLLoader( )); | 452 OwnPtr<WebURLLoader> loader = adoptPtr(Platform::current()->createURLLoader( )); |
| 481 ASSERT(loader); | 453 ASSERT(loader); |
| 482 | 454 |
| 483 // downloadToFile is not supported for synchronous requests. | 455 // downloadToFile is not supported for synchronous requests. |
| 484 ASSERT(!m_request.downloadToFile()); | 456 ASSERT(!m_request.downloadToFile()); |
| 485 | 457 |
| 486 RefPtrWillBeRawPtr<Resource> protectResource(m_resource.get()); | 458 RefPtrWillBeRawPtr<Resource> protectResource(m_resource.get()); |
| 487 | 459 |
| 488 RELEASE_ASSERT(m_connectionState == ConnectionStateNew); | 460 RELEASE_ASSERT(m_state == ConnectionStateNew); |
| 489 m_connectionState = ConnectionStateStarted; | 461 m_state = ConnectionStateStarted; |
| 490 | 462 |
| 491 WrappedResourceRequest requestIn(m_request); | 463 WrappedResourceRequest requestIn(m_request); |
| 492 WebURLResponse responseOut; | 464 WebURLResponse responseOut; |
| 493 responseOut.initialize(); | 465 responseOut.initialize(); |
| 494 WebURLError errorOut; | 466 WebURLError errorOut; |
| 495 WebData dataOut; | 467 WebData dataOut; |
| 496 loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut); | 468 loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut); |
| 497 if (errorOut.reason) { | 469 if (errorOut.reason) { |
| 498 if (m_state == Terminated) { | 470 if (m_state == ConnectionStateReleased) { |
| 499 // A message dispatched while synchronously fetching the resource | 471 // A message dispatched while synchronously fetching the resource |
| 500 // can bring about the cancellation of this load. | 472 // can bring about the cancellation of this load. |
| 501 ASSERT(!m_resource); | 473 ASSERT(!m_resource); |
| 502 return; | 474 return; |
| 503 } | 475 } |
| 504 didFail(0, errorOut); | 476 didFail(0, errorOut); |
| 505 return; | 477 return; |
| 506 } | 478 } |
| 507 didReceiveResponse(0, responseOut); | 479 didReceiveResponse(0, responseOut); |
| 508 if (m_state == Terminated) | 480 if (m_state == ConnectionStateReleased) |
| 509 return; | 481 return; |
| 510 RefPtr<ResourceLoadInfo> resourceLoadInfo = responseOut.toResourceResponse() .resourceLoadInfo(); | 482 RefPtr<ResourceLoadInfo> resourceLoadInfo = responseOut.toResourceResponse() .resourceLoadInfo(); |
| 511 int64_t encodedDataLength = resourceLoadInfo ? resourceLoadInfo->encodedData Length : WebURLLoaderClient::kUnknownEncodedDataLength; | 483 int64_t encodedDataLength = resourceLoadInfo ? resourceLoadInfo->encodedData Length : WebURLLoaderClient::kUnknownEncodedDataLength; |
| 512 | 484 |
| 513 // Follow the async case convention of not calling didReceiveData or | 485 // Follow the async case convention of not calling didReceiveData or |
| 514 // appending data to m_resource if the response body is empty. Copying the | 486 // appending data to m_resource if the response body is empty. Copying the |
| 515 // empty buffer is a noop in most cases, but is destructive in the case of | 487 // empty buffer is a noop in most cases, but is destructive in the case of |
| 516 // a 304, where it will overwrite the cached data we should be reusing. | 488 // a 304, where it will overwrite the cached data we should be reusing. |
| 517 if (dataOut.size()) { | 489 if (dataOut.size()) { |
| 518 m_fetcher->didReceiveData(m_resource.get(), dataOut.data(), dataOut.size (), encodedDataLength); | 490 m_fetcher->didReceiveData(m_resource.get(), dataOut.data(), dataOut.size (), encodedDataLength); |
| 519 m_resource->setResourceBuffer(dataOut); | 491 m_resource->setResourceBuffer(dataOut); |
| 520 } | 492 } |
| 521 didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); | 493 didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength); |
| 522 } | 494 } |
| 523 | 495 |
| 524 ResourceRequest& ResourceLoader::applyOptions(ResourceRequest& request) const | 496 ResourceRequest& ResourceLoader::applyOptions(ResourceRequest& request) const |
| 525 { | 497 { |
| 526 request.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredC redentials); | 498 request.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredC redentials); |
| 527 return request; | 499 return request; |
| 528 } | 500 } |
| 529 | 501 |
| 530 } // namespace blink | 502 } // namespace blink |
| OLD | NEW |