| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. | 3 // LICENSE file. |
| 4 | 4 |
| 5 #include "base/compiler_specific.h" | 5 #include "base/compiler_specific.h" |
| 6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
| 7 #include "base/process_util.h" | 7 #include "base/process_util.h" |
| 8 #include "base/stl_util-inl.h" | 8 #include "base/stl_util-inl.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "chrome/common/extensions/url_pattern.h" | 10 #include "chrome/common/extensions/url_pattern.h" |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 offset_ = first_byte_position_; | 115 offset_ = first_byte_position_; |
| 116 } | 116 } |
| 117 | 117 |
| 118 // Creates the bridge on render thread since we can only access | 118 // Creates the bridge on render thread since we can only access |
| 119 // ResourceDispatcher on this thread. | 119 // ResourceDispatcher on this thread. |
| 120 bridge_.reset(bridge_factory_->CreateBridge(url_, | 120 bridge_.reset(bridge_factory_->CreateBridge(url_, |
| 121 net::LOAD_BYPASS_CACHE, | 121 net::LOAD_BYPASS_CACHE, |
| 122 first_byte_position_, | 122 first_byte_position_, |
| 123 last_byte_position_)); | 123 last_byte_position_)); |
| 124 | 124 |
| 125 // Increment the reference count right before we start the request. This |
| 126 // reference will be release when this request has ended. |
| 127 AddRef(); |
| 128 |
| 125 // And start the resource loading. | 129 // And start the resource loading. |
| 126 bridge_->Start(this); | 130 bridge_->Start(this); |
| 127 } | 131 } |
| 128 | 132 |
| 129 void BufferedResourceLoader::Stop() { | 133 void BufferedResourceLoader::Stop() { |
| 130 // Reset callbacks. | 134 // Reset callbacks. |
| 131 start_callback_.reset(); | 135 start_callback_.reset(); |
| 132 read_callback_.reset(); | 136 read_callback_.reset(); |
| 133 | 137 |
| 134 // Destroy internal buffer. | 138 // Destroy internal buffer. |
| 135 buffer_.reset(); | 139 buffer_.reset(); |
| 136 | 140 |
| 137 if (bridge_.get()) { | 141 if (bridge_.get()) { |
| 138 // Cancel the resource request. | 142 // Cancel the request. This method call will cancel the request |
| 143 // asynchronously. We may still get data or messages until we receive |
| 144 // a response completed message. |
| 145 if (deferred_) |
| 146 bridge_->SetDefersLoading(false); |
| 147 deferred_ = false; |
| 139 bridge_->Cancel(); | 148 bridge_->Cancel(); |
| 140 bridge_.reset(); | |
| 141 } | 149 } |
| 142 } | 150 } |
| 143 | 151 |
| 144 void BufferedResourceLoader::Read(int64 position, | 152 void BufferedResourceLoader::Read(int64 position, |
| 145 int read_size, | 153 int read_size, |
| 146 uint8* buffer, | 154 uint8* buffer, |
| 147 net::CompletionCallback* read_callback) { | 155 net::CompletionCallback* read_callback) { |
| 148 DCHECK(!read_callback_.get()); | 156 DCHECK(!read_callback_.get()); |
| 149 DCHECK(buffer_.get()); | 157 DCHECK(buffer_.get()); |
| 150 DCHECK(read_callback); | 158 DCHECK(read_callback); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 DoneRead(net::ERR_CACHE_MISS); | 199 DoneRead(net::ERR_CACHE_MISS); |
| 192 } | 200 } |
| 193 | 201 |
| 194 ///////////////////////////////////////////////////////////////////////////// | 202 ///////////////////////////////////////////////////////////////////////////// |
| 195 // BufferedResourceLoader, | 203 // BufferedResourceLoader, |
| 196 // webkit_glue::ResourceLoaderBridge::Peer implementations | 204 // webkit_glue::ResourceLoaderBridge::Peer implementations |
| 197 bool BufferedResourceLoader::OnReceivedRedirect( | 205 bool BufferedResourceLoader::OnReceivedRedirect( |
| 198 const GURL& new_url, | 206 const GURL& new_url, |
| 199 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info) { | 207 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info) { |
| 200 DCHECK(bridge_.get()); | 208 DCHECK(bridge_.get()); |
| 201 DCHECK(start_callback_.get()); | |
| 202 | 209 |
| 203 // Saves the new URL. | 210 // Saves the new URL. |
| 204 url_ = new_url; | 211 url_ = new_url; |
| 205 | 212 |
| 213 // The load may have been stopped and |start_callback| is destroyed. |
| 214 // In this case we shouldn't do anything. |
| 215 if (!start_callback_.get()) |
| 216 return true; |
| 217 |
| 206 // If we got redirected to an unsupported protocol then stop. | 218 // If we got redirected to an unsupported protocol then stop. |
| 207 if (!IsSchemeSupported(new_url)) { | 219 if (!IsSchemeSupported(new_url)) { |
| 208 DoneStart(net::ERR_ADDRESS_INVALID); | 220 DoneStart(net::ERR_ADDRESS_INVALID); |
| 209 Stop(); | 221 Stop(); |
| 210 } | 222 } |
| 211 | 223 |
| 212 return true; | 224 return true; |
| 213 } | 225 } |
| 214 | 226 |
| 215 void BufferedResourceLoader::OnReceivedResponse( | 227 void BufferedResourceLoader::OnReceivedResponse( |
| 216 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, | 228 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, |
| 217 bool content_filtered) { | 229 bool content_filtered) { |
| 218 DCHECK(bridge_.get()); | 230 DCHECK(bridge_.get()); |
| 219 DCHECK(start_callback_.get()); | 231 |
| 232 // The loader may have been stopped and |start_callback| is destroyed. |
| 233 // In this case we shouldn't do anything. |
| 234 if (!start_callback_.get()) |
| 235 return; |
| 220 | 236 |
| 221 int64 first_byte_position = -1; | 237 int64 first_byte_position = -1; |
| 222 int64 last_byte_position = -1; | 238 int64 last_byte_position = -1; |
| 223 int64 instance_size = -1; | 239 int64 instance_size = -1; |
| 224 | 240 |
| 225 // The file:// protocol should be able to serve any request we want, so we | 241 // The file:// protocol should be able to serve any request we want, so we |
| 226 // take an exception for file protocol. | 242 // take an exception for file protocol. |
| 227 if (!url_.SchemeIsFile()) { | 243 if (!url_.SchemeIsFile()) { |
| 228 int error = net::OK; | 244 int error = net::OK; |
| 229 if (!info.headers) { | 245 if (!info.headers) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 // here. | 277 // here. |
| 262 if (first_byte_position != kPositionNotSpecified) | 278 if (first_byte_position != kPositionNotSpecified) |
| 263 offset_ = first_byte_position; | 279 offset_ = first_byte_position; |
| 264 | 280 |
| 265 // Calls with a successful response. | 281 // Calls with a successful response. |
| 266 DoneStart(net::OK); | 282 DoneStart(net::OK); |
| 267 } | 283 } |
| 268 | 284 |
| 269 void BufferedResourceLoader::OnReceivedData(const char* data, int len) { | 285 void BufferedResourceLoader::OnReceivedData(const char* data, int len) { |
| 270 DCHECK(bridge_.get()); | 286 DCHECK(bridge_.get()); |
| 271 DCHECK(buffer_.get()); | 287 |
| 288 // If this loader has been stopped, |buffer_| would be destroyed. |
| 289 // In this case we shouldn't do anything. |
| 290 if (!buffer_.get()) |
| 291 return; |
| 272 | 292 |
| 273 // Writes more data to |buffer_|. | 293 // Writes more data to |buffer_|. |
| 274 buffer_->Append(len, reinterpret_cast<const uint8*>(data)); | 294 buffer_->Append(len, reinterpret_cast<const uint8*>(data)); |
| 275 | 295 |
| 276 // If there is an active read request, try to fulfill the request. | 296 // If there is an active read request, try to fulfill the request. |
| 277 if (HasPendingRead() && CanFulfillRead()) { | 297 if (HasPendingRead() && CanFulfillRead()) { |
| 278 ReadInternal(); | 298 ReadInternal(); |
| 279 } | 299 } |
| 280 | 300 |
| 281 // At last see if the buffer is full and we need to defer the downloading. | 301 // At last see if the buffer is full and we need to defer the downloading. |
| 282 EnableDeferIfNeeded(); | 302 EnableDeferIfNeeded(); |
| 283 } | 303 } |
| 284 | 304 |
| 285 void BufferedResourceLoader::OnCompletedRequest( | 305 void BufferedResourceLoader::OnCompletedRequest( |
| 286 const URLRequestStatus& status, const std::string& security_info) { | 306 const URLRequestStatus& status, const std::string& security_info) { |
| 287 DCHECK(bridge_.get()); | 307 DCHECK(bridge_.get()); |
| 288 DCHECK(buffer_.get()); | |
| 289 | 308 |
| 290 // Saves the information that the request has completed. | 309 // Saves the information that the request has completed. |
| 291 completed_ = true; | 310 completed_ = true; |
| 292 | 311 |
| 293 // After the response has completed, we don't need the bridge any more. | |
| 294 bridge_.reset(); | |
| 295 | |
| 296 // If there is a start callback, calls it. | 312 // If there is a start callback, calls it. |
| 297 if (start_callback_.get()) { | 313 if (start_callback_.get()) { |
| 298 DoneStart(status.os_error()); | 314 DoneStart(status.os_error()); |
| 299 } | 315 } |
| 300 | 316 |
| 301 // If there is a pending read but the request has ended, returns with what we | 317 // If there is a pending read but the request has ended, returns with what |
| 302 // have. | 318 // we have. |
| 303 if (HasPendingRead()) { | 319 if (HasPendingRead()) { |
| 304 // If the request has failed, then fail the read. | 320 // Make sure we have a valid buffer before we satisfy a read request. |
| 305 if (!status.is_success()) { | 321 DCHECK(buffer_.get()); |
| 322 |
| 323 if (status.is_success()) { |
| 324 // Try to fulfill with what is in the buffer. |
| 325 if (CanFulfillRead()) |
| 326 ReadInternal(); |
| 327 else |
| 328 DoneRead(net::ERR_CACHE_MISS); |
| 329 } else { |
| 330 // If the request has failed, then fail the read. |
| 306 DoneRead(net::ERR_FAILED); | 331 DoneRead(net::ERR_FAILED); |
| 307 return; | |
| 308 } | 332 } |
| 309 | |
| 310 // Otherwise try to fulfill with what is in the buffer. | |
| 311 if (CanFulfillRead()) | |
| 312 ReadInternal(); | |
| 313 else | |
| 314 DoneRead(net::ERR_CACHE_MISS); | |
| 315 } | 333 } |
| 316 | 334 |
| 317 // There must not be any outstanding read request. | 335 // There must not be any outstanding read request. |
| 318 DCHECK(!read_callback_.get()); | 336 DCHECK(!HasPendingRead()); |
| 337 |
| 338 // We incremented the reference count when the loader was started. We balance |
| 339 // that reference here so that we get destroyed. This is also the only safe |
| 340 // place to destroy the ResourceLoaderBridge. |
| 341 bridge_.reset(); |
| 342 Release(); |
| 319 } | 343 } |
| 320 | 344 |
| 321 ///////////////////////////////////////////////////////////////////////////// | 345 ///////////////////////////////////////////////////////////////////////////// |
| 322 // BufferedResourceLoader, private | 346 // BufferedResourceLoader, private |
| 323 void BufferedResourceLoader::EnableDeferIfNeeded() { | 347 void BufferedResourceLoader::EnableDeferIfNeeded() { |
| 324 if (!deferred_ && | 348 if (!deferred_ && |
| 325 buffer_->forward_bytes() >= buffer_->forward_capacity()) { | 349 buffer_->forward_bytes() >= buffer_->forward_capacity()) { |
| 326 deferred_ = true; | 350 deferred_ = true; |
| 327 | 351 |
| 328 if (bridge_.get()) | 352 if (bridge_.get()) |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 GetTimeoutMilliseconds() / 2, | 574 GetTimeoutMilliseconds() / 2, |
| 551 this, | 575 this, |
| 552 &BufferedDataSource::WatchDogTask); | 576 &BufferedDataSource::WatchDogTask); |
| 553 | 577 |
| 554 // Creates a new resource loader with the full range and a probe resource | 578 // Creates a new resource loader with the full range and a probe resource |
| 555 // loader. Creates a probe resource loader to make sure the server supports | 579 // loader. Creates a probe resource loader to make sure the server supports |
| 556 // partial range request. | 580 // partial range request. |
| 557 // TODO(hclam): Only request 1 byte for this probe request, it may be useful | 581 // TODO(hclam): Only request 1 byte for this probe request, it may be useful |
| 558 // that we perform a suffix range request and fetch the index. That way we | 582 // that we perform a suffix range request and fetch the index. That way we |
| 559 // can minimize the number of requests made. | 583 // can minimize the number of requests made. |
| 560 loader_.reset(CreateLoader(-1, -1)); | 584 loader_ = CreateLoader(-1, -1); |
| 561 probe_loader_.reset(CreateLoader(1, 1)); | 585 probe_loader_ = CreateLoader(1, 1); |
| 562 | 586 |
| 563 loader_->Start(NewCallback(this, &BufferedDataSource::InitialStartCallback)); | 587 loader_->Start(NewCallback(this, &BufferedDataSource::InitialStartCallback)); |
| 564 probe_loader_->Start( | 588 probe_loader_->Start( |
| 565 NewCallback(this, &BufferedDataSource::ProbeStartCallback)); | 589 NewCallback(this, &BufferedDataSource::ProbeStartCallback)); |
| 566 } | 590 } |
| 567 | 591 |
| 568 void BufferedDataSource::ReadTask( | 592 void BufferedDataSource::ReadTask( |
| 569 int64 position, int read_size, uint8* buffer, | 593 int64 position, int read_size, uint8* buffer, |
| 570 media::DataSource::ReadCallback* read_callback) { | 594 media::DataSource::ReadCallback* read_callback) { |
| 571 DCHECK(MessageLoop::current() == render_loop_); | 595 DCHECK(MessageLoop::current() == render_loop_); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 read_position_ = 0; | 635 read_position_ = 0; |
| 612 read_size_ = 0; | 636 read_size_ = 0; |
| 613 read_buffer_ = 0; | 637 read_buffer_ = 0; |
| 614 read_submitted_time_ = base::Time(); | 638 read_submitted_time_ = base::Time(); |
| 615 read_attempts_ = 0; | 639 read_attempts_ = 0; |
| 616 | 640 |
| 617 // Signal that stop task has finished execution. | 641 // Signal that stop task has finished execution. |
| 618 stop_task_finished_ = true; | 642 stop_task_finished_ = true; |
| 619 } | 643 } |
| 620 | 644 |
| 621 void BufferedDataSource::SwapLoaderTask(BufferedResourceLoader* loader) { | 645 void BufferedDataSource::SwapLoaderTask( |
| 646 scoped_refptr<BufferedResourceLoader> loader) { |
| 622 DCHECK(MessageLoop::current() == render_loop_); | 647 DCHECK(MessageLoop::current() == render_loop_); |
| 623 DCHECK(loader); | 648 DCHECK(loader); |
| 624 | 649 |
| 625 loader_.reset(loader); | 650 loader_ = loader; |
| 626 loader_->Start(NewCallback(this, | 651 loader_->Start(NewCallback(this, |
| 627 &BufferedDataSource::PartialReadStartCallback)); | 652 &BufferedDataSource::PartialReadStartCallback)); |
| 628 } | 653 } |
| 629 | 654 |
| 630 void BufferedDataSource::WatchDogTask() { | 655 void BufferedDataSource::WatchDogTask() { |
| 631 DCHECK(MessageLoop::current() == render_loop_); | 656 DCHECK(MessageLoop::current() == render_loop_); |
| 632 | 657 |
| 633 // We only care if there is an active read request. | 658 // We only care if there is an active read request. |
| 634 if (!read_callback_.get()) | 659 if (!read_callback_.get()) |
| 635 return; | 660 return; |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 render_loop_->PostTask(FROM_HERE, | 861 render_loop_->PostTask(FROM_HERE, |
| 837 NewRunnableMethod(this, &BufferedDataSource::SwapLoaderTask, | 862 NewRunnableMethod(this, &BufferedDataSource::SwapLoaderTask, |
| 838 CreateLoader(read_position_, -1))); | 863 CreateLoader(read_position_, -1))); |
| 839 } else { | 864 } else { |
| 840 loader_->Stop(); | 865 loader_->Stop(); |
| 841 DoneRead(error); | 866 DoneRead(error); |
| 842 } | 867 } |
| 843 } | 868 } |
| 844 | 869 |
| 845 } // namespace webkit_glue | 870 } // namespace webkit_glue |
| OLD | NEW |