| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "media/blink/resource_multibuffer_data_provider.h" | 5 #include "media/blink/resource_multibuffer_data_provider.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 return; | 165 return; |
| 166 active_loader_->SetDeferred(deferred); | 166 active_loader_->SetDeferred(deferred); |
| 167 } | 167 } |
| 168 | 168 |
| 169 ///////////////////////////////////////////////////////////////////////////// | 169 ///////////////////////////////////////////////////////////////////////////// |
| 170 // WebAssociatedURLLoaderClient implementation. | 170 // WebAssociatedURLLoaderClient implementation. |
| 171 | 171 |
| 172 bool ResourceMultiBufferDataProvider::willFollowRedirect( | 172 bool ResourceMultiBufferDataProvider::willFollowRedirect( |
| 173 const WebURLRequest& newRequest, | 173 const WebURLRequest& newRequest, |
| 174 const WebURLResponse& redirectResponse) { | 174 const WebURLResponse& redirectResponse) { |
| 175 DVLOG(1) << "willFollowRedirect"; |
| 175 redirects_to_ = newRequest.url(); | 176 redirects_to_ = newRequest.url(); |
| 176 url_data_->set_valid_until(base::Time::Now() + | 177 url_data_->set_valid_until(base::Time::Now() + |
| 177 GetCacheValidUntil(redirectResponse)); | 178 GetCacheValidUntil(redirectResponse)); |
| 178 | 179 |
| 179 // This test is vital for security! | 180 // This test is vital for security! |
| 180 if (cors_mode_ == UrlData::CORS_UNSPECIFIED) { | 181 if (cors_mode_ == UrlData::CORS_UNSPECIFIED) { |
| 181 // We allow the redirect if the origin is the same. | 182 // We allow the redirect if the origin is the same. |
| 182 if (origin_ != redirects_to_.GetOrigin()) { | 183 if (origin_ != redirects_to_.GetOrigin()) { |
| 183 // We also allow the redirect if we don't have any data in the | 184 // We also allow the redirect if we don't have any data in the |
| 184 // cache, as that means that no dangerous data mixing can occur. | 185 // cache, as that means that no dangerous data mixing can occur. |
| 185 if (url_data_->multibuffer()->map().empty() && fifo_.empty()) | 186 if (url_data_->multibuffer()->map().empty() && fifo_.empty()) |
| 186 return true; | 187 return true; |
| 187 | 188 |
| 188 active_loader_ = nullptr; | 189 active_loader_ = nullptr; |
| 189 url_data_->Fail(); | 190 url_data_->Fail(); |
| 190 return false; // "this" may be deleted now. | 191 return false; // "this" may be deleted now. |
| 191 } | 192 } |
| 192 } | 193 } |
| 193 return true; | 194 return true; |
| 194 } | 195 } |
| 195 | 196 |
| 196 void ResourceMultiBufferDataProvider::didSendData( | 197 void ResourceMultiBufferDataProvider::didSendData( |
| 197 unsigned long long bytes_sent, | 198 unsigned long long bytes_sent, |
| 198 unsigned long long total_bytes_to_be_sent) { | 199 unsigned long long total_bytes_to_be_sent) { |
| 199 NOTIMPLEMENTED(); | 200 NOTIMPLEMENTED(); |
| 200 } | 201 } |
| 201 | 202 |
| 202 void ResourceMultiBufferDataProvider::didReceiveResponse( | 203 void ResourceMultiBufferDataProvider::didReceiveResponse( |
| 203 const WebURLResponse& response) { | 204 const WebURLResponse& response) { |
| 204 #if ENABLE_DLOG | 205 #if DCHECK_IS_ON() |
| 205 string version; | 206 std::string version; |
| 206 switch (response.httpVersion()) { | 207 switch (response.httpVersion()) { |
| 207 case WebURLResponse::HTTPVersion_0_9: | 208 case WebURLResponse::HTTPVersion_0_9: |
| 208 version = "0.9"; | 209 version = "0.9"; |
| 209 break; | 210 break; |
| 210 case WebURLResponse::HTTPVersion_1_0: | 211 case WebURLResponse::HTTPVersion_1_0: |
| 211 version = "1.0"; | 212 version = "1.0"; |
| 212 break; | 213 break; |
| 213 case WebURLResponse::HTTPVersion_1_1: | 214 case WebURLResponse::HTTPVersion_1_1: |
| 214 version = "1.1"; | 215 version = "1.1"; |
| 215 break; | 216 break; |
| 216 case WebURLResponse::HTTPVersion_2_0: | 217 case WebURLResponse::HTTPVersion_2_0: |
| 217 version = "2.1"; | 218 version = "2.1"; |
| 218 break; | 219 break; |
| 220 case WebURLResponse::HTTPVersionUnknown: |
| 221 version = "unknown"; |
| 222 break; |
| 219 } | 223 } |
| 220 DVLOG(1) << "didReceiveResponse: HTTP/" << version << " " | 224 DVLOG(1) << "didReceiveResponse: HTTP/" << version << " " |
| 221 << response.httpStatusCode(); | 225 << response.httpStatusCode(); |
| 222 #endif | 226 #endif |
| 223 DCHECK(active_loader_); | 227 DCHECK(active_loader_); |
| 224 | 228 |
| 225 scoped_refptr<UrlData> destination_url_data(url_data_); | 229 scoped_refptr<UrlData> destination_url_data(url_data_); |
| 226 | 230 |
| 227 UrlIndex* url_index = url_data_->url_index(); | 231 UrlIndex* url_index = url_data_->url_index(); |
| 228 | 232 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 } | 267 } |
| 264 | 268 |
| 265 reasons >>= 1; | 269 reasons >>= 1; |
| 266 ++shift; | 270 ++shift; |
| 267 } | 271 } |
| 268 | 272 |
| 269 // Expected content length can be |kPositionNotSpecified|, in that case | 273 // Expected content length can be |kPositionNotSpecified|, in that case |
| 270 // |content_length_| is not specified and this is a streaming response. | 274 // |content_length_| is not specified and this is a streaming response. |
| 271 int64_t content_length = response.expectedContentLength(); | 275 int64_t content_length = response.expectedContentLength(); |
| 272 bool end_of_file = false; | 276 bool end_of_file = false; |
| 277 bool do_fail = false; |
| 273 | 278 |
| 274 // We make a strong assumption that when we reach here we have either | 279 // We make a strong assumption that when we reach here we have either |
| 275 // received a response from HTTP/HTTPS protocol or the request was | 280 // received a response from HTTP/HTTPS protocol or the request was |
| 276 // successful (in particular range request). So we only verify the partial | 281 // successful (in particular range request). So we only verify the partial |
| 277 // response for HTTP and HTTPS protocol. | 282 // response for HTTP and HTTPS protocol. |
| 278 if (destination_url_data->url().SchemeIsHTTPOrHTTPS()) { | 283 if (destination_url_data->url().SchemeIsHTTPOrHTTPS()) { |
| 279 bool partial_response = (response.httpStatusCode() == kHttpPartialContent); | 284 bool partial_response = (response.httpStatusCode() == kHttpPartialContent); |
| 280 bool ok_response = (response.httpStatusCode() == kHttpOK); | 285 bool ok_response = (response.httpStatusCode() == kHttpOK); |
| 281 | 286 |
| 282 // Check to see whether the server supports byte ranges. | 287 // Check to see whether the server supports byte ranges. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 298 destination_url_data->set_length(content_length); | 303 destination_url_data->set_length(content_length); |
| 299 } else if (response.httpStatusCode() == kHttpRangeNotSatisfiable) { | 304 } else if (response.httpStatusCode() == kHttpRangeNotSatisfiable) { |
| 300 // Unsatisfiable range | 305 // Unsatisfiable range |
| 301 // Really, we should never request a range that doesn't exist, but | 306 // Really, we should never request a range that doesn't exist, but |
| 302 // if we do, let's handle it in a sane way. | 307 // if we do, let's handle it in a sane way. |
| 303 // Note, we can't just call OnDataProviderEvent() here, because | 308 // Note, we can't just call OnDataProviderEvent() here, because |
| 304 // url_data_ hasn't been updated to the final destination yet. | 309 // url_data_ hasn't been updated to the final destination yet. |
| 305 end_of_file = true; | 310 end_of_file = true; |
| 306 } else { | 311 } else { |
| 307 active_loader_ = nullptr; | 312 active_loader_ = nullptr; |
| 308 destination_url_data->Fail(); | 313 // Can't call fail until readers have been migrated to the new |
| 309 return; // "this" may be deleted now. | 314 // url data below. |
| 315 do_fail = true; |
| 310 } | 316 } |
| 311 } else { | 317 } else { |
| 312 destination_url_data->set_range_supported(); | 318 destination_url_data->set_range_supported(); |
| 313 if (content_length != kPositionNotSpecified) { | 319 if (content_length != kPositionNotSpecified) { |
| 314 destination_url_data->set_length(content_length + byte_pos()); | 320 destination_url_data->set_length(content_length + byte_pos()); |
| 315 } | 321 } |
| 316 } | 322 } |
| 317 | 323 |
| 318 if (url_index) { | 324 if (url_index && !do_fail) { |
| 319 destination_url_data = url_index->TryInsert(destination_url_data); | 325 destination_url_data = url_index->TryInsert(destination_url_data); |
| 320 } | 326 } |
| 321 | 327 |
| 322 if (destination_url_data != url_data_) { | 328 if (destination_url_data != url_data_) { |
| 323 // At this point, we've encountered a redirect, or found a better url data | 329 // At this point, we've encountered a redirect, or found a better url data |
| 324 // instance for the data that we're about to download. | 330 // instance for the data that we're about to download. |
| 325 | 331 |
| 326 // First, let's take a ref on the current url data. | 332 // First, let's take a ref on the current url data. |
| 327 scoped_refptr<UrlData> old_url_data(url_data_); | 333 scoped_refptr<UrlData> old_url_data(url_data_); |
| 328 destination_url_data->Use(); | 334 destination_url_data->Use(); |
| 329 | 335 |
| 330 // Take ownership of ourselves. (From the multibuffer) | 336 // Take ownership of ourselves. (From the multibuffer) |
| 331 std::unique_ptr<DataProvider> self( | 337 std::unique_ptr<DataProvider> self( |
| 332 url_data_->multibuffer()->RemoveProvider(this)); | 338 url_data_->multibuffer()->RemoveProvider(this)); |
| 333 url_data_ = destination_url_data.get(); | 339 url_data_ = destination_url_data.get(); |
| 334 // Give the ownership to our new owner. | 340 // Give the ownership to our new owner. |
| 335 url_data_->multibuffer()->AddProvider(std::move(self)); | 341 url_data_->multibuffer()->AddProvider(std::move(self)); |
| 336 | 342 |
| 337 // Call callback to let upstream users know about the transfer. | 343 // Call callback to let upstream users know about the transfer. |
| 338 // This will merge the data from the two multibuffers and | 344 // This will merge the data from the two multibuffers and |
| 339 // cause clients to start using the new UrlData. | 345 // cause clients to start using the new UrlData. |
| 340 old_url_data->RedirectTo(destination_url_data); | 346 old_url_data->RedirectTo(destination_url_data); |
| 341 } | 347 } |
| 342 | 348 |
| 349 if (do_fail) { |
| 350 destination_url_data->Fail(); |
| 351 return; // "this" may be deleted now. |
| 352 } |
| 353 |
| 343 // This test is vital for security! | 354 // This test is vital for security! |
| 344 const GURL& original_url = response.wasFetchedViaServiceWorker() | 355 const GURL& original_url = response.wasFetchedViaServiceWorker() |
| 345 ? response.originalURLViaServiceWorker() | 356 ? response.originalURLViaServiceWorker() |
| 346 : response.url(); | 357 : response.url(); |
| 347 if (!url_data_->ValidateDataOrigin(original_url.GetOrigin())) { | 358 if (!url_data_->ValidateDataOrigin(original_url.GetOrigin())) { |
| 348 active_loader_ = nullptr; | 359 active_loader_ = nullptr; |
| 349 url_data_->Fail(); | 360 url_data_->Fail(); |
| 350 return; // "this" may be deleted now. | 361 return; // "this" may be deleted now. |
| 351 } | 362 } |
| 352 | 363 |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 } | 546 } |
| 536 | 547 |
| 537 if (byte_pos() != first_byte_position) { | 548 if (byte_pos() != first_byte_position) { |
| 538 return false; | 549 return false; |
| 539 } | 550 } |
| 540 | 551 |
| 541 return true; | 552 return true; |
| 542 } | 553 } |
| 543 | 554 |
| 544 } // namespace media | 555 } // namespace media |
| OLD | NEW |