Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: webkit/glue/media/buffered_resource_loader.cc

Issue 6815012: Only make Range requests when the desired range doesn't cover the whole file. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix unit tests Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698