Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/glue/media/buffered_resource_loader.h" | 5 #include "webkit/glue/media/buffered_resource_loader.h" |
| 6 | 6 |
| 7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
| 10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" | 10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 | 46 |
| 47 BufferedResourceLoader::BufferedResourceLoader( | 47 BufferedResourceLoader::BufferedResourceLoader( |
| 48 const GURL& url, | 48 const GURL& url, |
| 49 int64 first_byte_position, | 49 int64 first_byte_position, |
| 50 int64 last_byte_position) | 50 int64 last_byte_position) |
| 51 : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)), | 51 : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)), |
| 52 deferred_(false), | 52 deferred_(false), |
| 53 defer_strategy_(kReadThenDefer), | 53 defer_strategy_(kReadThenDefer), |
| 54 completed_(false), | 54 completed_(false), |
| 55 range_requested_(false), | 55 range_requested_(false), |
| 56 partial_response_(false), | 56 range_supported_(false), |
| 57 url_(url), | 57 url_(url), |
| 58 first_byte_position_(first_byte_position), | 58 first_byte_position_(first_byte_position), |
| 59 last_byte_position_(last_byte_position), | 59 last_byte_position_(last_byte_position), |
| 60 single_origin_(true), | 60 single_origin_(true), |
| 61 start_callback_(NULL), | 61 start_callback_(NULL), |
| 62 offset_(0), | 62 offset_(0), |
| 63 content_length_(kPositionNotSpecified), | 63 content_length_(kPositionNotSpecified), |
| 64 instance_size_(kPositionNotSpecified), | 64 instance_size_(kPositionNotSpecified), |
| 65 read_callback_(NULL), | 65 read_callback_(NULL), |
| 66 read_position_(0), | 66 read_position_(0), |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 83 DCHECK(!start_callback_.get()); | 83 DCHECK(!start_callback_.get()); |
| 84 DCHECK(!event_callback_.get()); | 84 DCHECK(!event_callback_.get()); |
| 85 DCHECK(start_callback); | 85 DCHECK(start_callback); |
| 86 DCHECK(event_callback); | 86 DCHECK(event_callback); |
| 87 CHECK(frame); | 87 CHECK(frame); |
| 88 | 88 |
| 89 start_callback_.reset(start_callback); | 89 start_callback_.reset(start_callback); |
| 90 event_callback_.reset(event_callback); | 90 event_callback_.reset(event_callback); |
| 91 | 91 |
| 92 if (first_byte_position_ != kPositionNotSpecified) { | 92 if (first_byte_position_ != kPositionNotSpecified) { |
| 93 range_requested_ = true; | |
| 94 // TODO(hclam): server may not support range request so |offset_| may not | 93 // TODO(hclam): server may not support range request so |offset_| may not |
| 95 // equal to |first_byte_position_|. | 94 // equal to |first_byte_position_|. |
| 96 offset_ = first_byte_position_; | 95 offset_ = first_byte_position_; |
| 97 } | 96 } |
| 98 | 97 |
| 99 // Increment the reference count right before we start the request. This | 98 // Increment the reference count right before we start the request. This |
| 100 // reference will be release when this request has ended. | 99 // reference will be release when this request has ended. |
| 101 AddRef(); | 100 AddRef(); |
| 102 | 101 |
| 103 // Prepare the request. | 102 // Prepare the request. |
| 104 WebURLRequest request(url_); | 103 WebURLRequest request(url_); |
| 105 request.setTargetType(WebURLRequest::TargetIsMedia); | 104 request.setTargetType(WebURLRequest::TargetIsMedia); |
| 106 request.setHTTPHeaderField(WebString::fromUTF8("Range"), | 105 |
| 107 WebString::fromUTF8(GenerateHeaders( | 106 if (!IsWholeFileRange()) { |
| 108 first_byte_position_, | 107 range_requested_ = true; |
| 109 last_byte_position_))); | 108 request.setHTTPHeaderField(WebString::fromUTF8("Range"), |
| 109 WebString::fromUTF8(GenerateHeaders( | |
| 110 first_byte_position_, | |
| 111 last_byte_position_))); | |
| 112 } | |
| 110 frame->setReferrerForRequest(request, WebKit::WebURL()); | 113 frame->setReferrerForRequest(request, WebKit::WebURL()); |
| 111 | 114 |
| 112 // This flag is for unittests as we don't want to reset |url_loader| | 115 // This flag is for unittests as we don't want to reset |url_loader| |
| 113 if (!keep_test_loader_) | 116 if (!keep_test_loader_) |
| 114 url_loader_.reset(frame->createAssociatedURLLoader()); | 117 url_loader_.reset(frame->createAssociatedURLLoader()); |
| 115 | 118 |
| 116 // Start the resource loading. | 119 // Start the resource loading. |
| 117 url_loader_->loadAsynchronously(request, this); | 120 url_loader_->loadAsynchronously(request, this); |
| 118 } | 121 } |
| 119 | 122 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 205 } | 208 } |
| 206 | 209 |
| 207 int64 BufferedResourceLoader::content_length() { | 210 int64 BufferedResourceLoader::content_length() { |
| 208 return content_length_; | 211 return content_length_; |
| 209 } | 212 } |
| 210 | 213 |
| 211 int64 BufferedResourceLoader::instance_size() { | 214 int64 BufferedResourceLoader::instance_size() { |
| 212 return instance_size_; | 215 return instance_size_; |
| 213 } | 216 } |
| 214 | 217 |
| 215 bool BufferedResourceLoader::partial_response() { | 218 bool BufferedResourceLoader::range_supported() { |
| 216 return partial_response_; | 219 return range_supported_; |
| 217 } | 220 } |
| 218 | 221 |
| 219 bool BufferedResourceLoader::network_activity() { | 222 bool BufferedResourceLoader::network_activity() { |
| 220 return !completed_ && !deferred_; | 223 return !completed_ && !deferred_; |
| 221 } | 224 } |
| 222 | 225 |
| 223 const GURL& BufferedResourceLoader::url() { | 226 const GURL& BufferedResourceLoader::url() { |
| 224 return url_; | 227 return url_; |
| 225 } | 228 } |
| 226 | 229 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 267 | 270 |
| 268 void BufferedResourceLoader::didReceiveResponse( | 271 void BufferedResourceLoader::didReceiveResponse( |
| 269 WebURLLoader* loader, | 272 WebURLLoader* loader, |
| 270 const WebURLResponse& response) { | 273 const WebURLResponse& response) { |
| 271 | 274 |
| 272 // The loader may have been stopped and |start_callback| is destroyed. | 275 // The loader may have been stopped and |start_callback| is destroyed. |
| 273 // In this case we shouldn't do anything. | 276 // In this case we shouldn't do anything. |
| 274 if (!start_callback_.get()) | 277 if (!start_callback_.get()) |
| 275 return; | 278 return; |
| 276 | 279 |
| 280 bool partial_response = false; | |
| 281 | |
| 277 // We make a strong assumption that when we reach here we have either | 282 // We make a strong assumption that when we reach here we have either |
| 278 // received a response from HTTP/HTTPS protocol or the request was | 283 // received a response from HTTP/HTTPS protocol or the request was |
| 279 // successful (in particular range request). So we only verify the partial | 284 // successful (in particular range request). So we only verify the partial |
| 280 // response for HTTP and HTTPS protocol. | 285 // response for HTTP and HTTPS protocol. |
| 281 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { | 286 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { |
| 282 int error = net::OK; | 287 int error = net::OK; |
| 283 | 288 |
| 284 if (response.httpStatusCode() == kHttpPartialContent) | 289 // Check to see whether the server supports byte ranges. |
| 285 partial_response_ = true; | 290 std::string accept_ranges = |
| 291 response.httpHeaderField("Accept-Ranges").utf8(); | |
| 292 range_supported_ = (accept_ranges.find("bytes") != std::string::npos); | |
| 286 | 293 |
| 287 if (range_requested_ && partial_response_) { | 294 partial_response = (response.httpStatusCode() == kHttpPartialContent); |
| 295 | |
| 296 if (range_requested_) { | |
| 288 // If we have verified the partial response and it is correct, we will | 297 // If we have verified the partial response and it is correct, we will |
| 289 // return net::OK. | 298 // return net::OK. |
| 290 if (!VerifyPartialResponse(response)) | 299 if (!partial_response || !VerifyPartialResponse(response)) |
| 291 error = net::ERR_INVALID_RESPONSE; | 300 error = net::ERR_INVALID_RESPONSE; |
| 292 } else if (response.httpStatusCode() != kHttpOK) { | 301 } else if (response.httpStatusCode() != kHttpOK) { |
| 293 // We didn't request a range but server didn't reply with "200 OK". | 302 // We didn't request a range but server didn't reply with "200 OK". |
| 294 error = net::ERR_FAILED; | 303 error = net::ERR_FAILED; |
| 295 } | 304 } |
| 296 | 305 |
| 297 if (error != net::OK) { | 306 if (error != net::OK) { |
| 298 DoneStart(error); | 307 DoneStart(error); |
| 299 Stop(); | 308 Stop(); |
| 300 return; | 309 return; |
| 301 } | 310 } |
| 302 } else { | 311 } else { |
| 303 // For any protocol other than HTTP and HTTPS, assume range request is | 312 // For any protocol other than HTTP and HTTPS, assume range request is |
| 304 // always fulfilled. | 313 // always fulfilled. |
| 305 partial_response_ = range_requested_; | 314 partial_response = range_requested_; |
| 306 } | 315 } |
| 307 | 316 |
| 308 // Expected content length can be |kPositionNotSpecified|, in that case | 317 // Expected content length can be |kPositionNotSpecified|, in that case |
| 309 // |content_length_| is not specified and this is a streaming response. | 318 // |content_length_| is not specified and this is a streaming response. |
| 310 content_length_ = response.expectedContentLength(); | 319 content_length_ = response.expectedContentLength(); |
| 311 | 320 |
| 312 // If we have not requested a range, then the size of the instance is equal | 321 // If we have not requested a range, then the size of the instance is equal |
| 313 // to the content length. | 322 // to the content length. |
| 314 if (!partial_response_) | 323 if (!partial_response) |
| 315 instance_size_ = content_length_; | 324 instance_size_ = content_length_; |
| 316 | 325 |
| 317 // Calls with a successful response. | 326 // Calls with a successful response. |
| 318 DoneStart(net::OK); | 327 DoneStart(net::OK); |
| 319 } | 328 } |
| 320 | 329 |
| 321 void BufferedResourceLoader::didReceiveData( | 330 void BufferedResourceLoader::didReceiveData( |
| 322 WebURLLoader* loader, | 331 WebURLLoader* loader, |
| 323 const char* data, | 332 const char* data, |
| 324 int data_length, | 333 int data_length, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 int data_length) { | 374 int data_length) { |
| 366 NOTIMPLEMENTED(); | 375 NOTIMPLEMENTED(); |
| 367 } | 376 } |
| 368 | 377 |
| 369 void BufferedResourceLoader::didFinishLoading( | 378 void BufferedResourceLoader::didFinishLoading( |
| 370 WebURLLoader* loader, | 379 WebURLLoader* loader, |
| 371 double finishTime) { | 380 double finishTime) { |
| 372 DCHECK(!completed_); | 381 DCHECK(!completed_); |
| 373 completed_ = true; | 382 completed_ = true; |
| 374 | 383 |
| 384 if (instance_size_ == kPositionNotSpecified) { | |
| 385 // If we didn't know the |instance_size_| we do now. | |
|
scherkus (not reviewing)
2011/04/11 17:41:55
pedantic nit: the rest of this file seems to put i
acolwell GONE FROM CHROMIUM
2011/04/18 22:09:56
Done.
| |
| 386 instance_size_ = offset_ + buffer_->forward_bytes(); | |
| 387 } | |
| 388 | |
| 375 // If there is a start callback, calls it. | 389 // If there is a start callback, calls it. |
| 376 if (start_callback_.get()) { | 390 if (start_callback_.get()) { |
| 377 DoneStart(net::OK); | 391 DoneStart(net::OK); |
| 378 } | 392 } |
| 379 | 393 |
| 380 // If there is a pending read but the request has ended, returns with what | 394 // If there is a pending read but the request has ended, returns with what |
| 381 // we have. | 395 // we have. |
| 382 if (HasPendingRead()) { | 396 if (HasPendingRead()) { |
| 383 // Make sure we have a valid buffer before we satisfy a read request. | 397 // Make sure we have a valid buffer before we satisfy a read request. |
| 384 DCHECK(buffer_.get()); | 398 DCHECK(buffer_.get()); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 622 void BufferedResourceLoader::DoneStart(int error) { | 636 void BufferedResourceLoader::DoneStart(int error) { |
| 623 start_callback_->RunWithParams(Tuple1<int>(error)); | 637 start_callback_->RunWithParams(Tuple1<int>(error)); |
| 624 start_callback_.reset(); | 638 start_callback_.reset(); |
| 625 } | 639 } |
| 626 | 640 |
| 627 void BufferedResourceLoader::NotifyNetworkEvent() { | 641 void BufferedResourceLoader::NotifyNetworkEvent() { |
| 628 if (event_callback_.get()) | 642 if (event_callback_.get()) |
| 629 event_callback_->Run(); | 643 event_callback_->Run(); |
| 630 } | 644 } |
| 631 | 645 |
| 646 bool BufferedResourceLoader::IsWholeFileRange() const { | |
| 647 return ((first_byte_position_ == kPositionNotSpecified || | |
| 648 first_byte_position_ == 0) && | |
| 649 last_byte_position_ == kPositionNotSpecified); | |
|
scherkus (not reviewing)
2011/04/11 17:41:55
is it worth checking last_byte_position_ == conten
acolwell GONE FROM CHROMIUM
2011/04/18 22:09:56
I don't think this is worth checking. It would cau
| |
| 650 } | |
| 651 | |
| 632 } // namespace webkit_glue | 652 } // namespace webkit_glue |
| OLD | NEW |