15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_url_request_job.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <algorithm> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <limits> 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <string> 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <vector> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_util_proxy.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/format_macros.h" 17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/numerics/safe_conversions.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/stringprintf.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_headers.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_info.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_error_job.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h" 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/file_stream_reader.h" 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h" 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsFileType(BlobData::Item::Type type) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BlobData::Item::TYPE_FILE: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BlobData::Item::TYPE_FILE_FILESYSTEM: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BlobURLRequestJob::BlobURLRequestJob( 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate* network_delegate, 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<BlobData>& blob_data, 5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemContext* file_system_context, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessageLoopProxy* file_thread_proxy) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : net::URLRequestJob(request, network_delegate), 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blob_data_(blob_data), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_context_(file_system_context), 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_thread_proxy_(file_thread_proxy), 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_size_(0), 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_bytes_(0), 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_get_file_info_count_(0), 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_item_index_(0), 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_item_offset_(0), 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_(false), 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) byte_range_set_(false), 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_(this) { 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(file_thread_proxy_.get()); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::Start() { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Continue asynchronously. 76b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BlobURLRequestJob::DidStart, weak_factory_.GetWeakPtr())); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::Kill() { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteCurrentFileReader(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestJob::Kill(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BlobURLRequestJob::ReadRawData(net::IOBuffer* dest, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dest_size, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* bytes_read) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(dest_size, 0); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(remaining_bytes_, 0); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bail out immediately if we encounter an error. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes_read = 0; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remaining_bytes_ < dest_size) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_size = static_cast<int>(remaining_bytes_); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we should copy zero bytes because |remaining_bytes_| is zero, short 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // circuit here. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dest_size) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes_read = 0; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keep track of the buffer. 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!read_buf_.get()); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_buf_ = new net::DrainableIOBuffer(dest, dest_size); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadLoop(bytes_read); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BlobURLRequestJob::GetMimeType(std::string* mime_type) const { 119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!response_info_) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return response_info_->headers->GetMimeType(mime_type); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { 126b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (response_info_) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *info = *response_info_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BlobURLRequestJob::GetResponseCode() const { 131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!response_info_) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return response_info_->headers->response_code(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::SetExtraRequestHeaders( 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpRequestHeaders& headers) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string range_header; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care about "Range" header here. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<net::HttpByteRange> ranges; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ranges.size() == 1) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) byte_range_set_ = true; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) byte_range_ = ranges[0]; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't support multiple range requests in one single URL request, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because we need to do multipart encoding here. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jianli): Support multipart byte range requests. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailure(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BlobURLRequestJob::~BlobURLRequestJob() { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteValues(&index_to_reader_); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::DidStart() { 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_ = false; 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only support GET request per the spec. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request()->method() != "GET") { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailure(net::ERR_METHOD_NOT_SUPPORTED); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the blob data is not present, bail out. 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!blob_data_.get()) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailure(net::ERR_FILE_NOT_FOUND); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CountSize(); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BlobURLRequestJob::AddItemLength(size_t index, int64 item_length) { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (item_length > kint64max - total_size_) { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyFailure(net::ERR_FAILED); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Cache the size and add it to the total size. 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LT(index, item_length_list_.size()); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) item_length_list_[index] = item_length; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total_size_ += item_length; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::CountSize() { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_get_file_info_count_ = 0; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_size_ = 0; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_length_list_.resize(blob_data_->items().size()); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < blob_data_->items().size(); ++i) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BlobData::Item& item = blob_data_->items().at(i); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsFileType(item.type())) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++pending_get_file_info_count_; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetFileStreamReader(i)->GetLength( 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BlobURLRequestJob::DidGetFileItemLength, 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), i)); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!AddItemLength(i, item.length())) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_get_file_info_count_ == 0) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidCountSize(net::OK); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::DidCountSize(int error) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!error_); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If an error occured, bail out. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error != net::OK) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailure(error); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Apply the range requirement. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!byte_range_.ComputeBounds(total_size_)) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailure(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci remaining_bytes_ = base::checked_cast<int64>( 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci byte_range_.last_byte_position() - byte_range_.first_byte_position() + 1); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(remaining_bytes_, 0); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do the seek at the beginning of the request. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (byte_range_.first_byte_position()) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Seek(byte_range_.first_byte_position()); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifySuccess(); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::DidGetFileItemLength(size_t index, int64 result) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do nothing if we have encountered an error. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == net::ERR_UPLOAD_FILE_CHANGED) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailure(net::ERR_FILE_NOT_FOUND); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (result < 0) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailure(result); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LT(index, blob_data_->items().size()); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BlobData::Item& item = blob_data_->items().at(index); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsFileType(item.type())); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 file_length = result; 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 item_offset = item.offset(); 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 item_length = item.length(); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (item_offset > file_length) { 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyFailure(net::ERR_FILE_NOT_FOUND); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 max_length = file_length - item_offset; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If item length is undefined, then we need to use the file size being 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // resolved in the real time. 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (item_length == std::numeric_limits<uint64>::max()) { 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) item_length = max_length; 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (item_length > max_length) { 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyFailure(net::ERR_FILE_NOT_FOUND); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!AddItemLength(index, item_length)) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (--pending_get_file_info_count_ == 0) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidCountSize(net::OK); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::Seek(int64 offset) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip the initial items that are not in the range. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (current_item_index_ = 0; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_item_index_ < blob_data_->items().size() && 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset >= item_length_list_[current_item_index_]; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++current_item_index_) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset -= item_length_list_[current_item_index_]; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the offset that need to jump to for the first item in the range. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_item_offset_ = offset; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (offset == 0) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adjust the offset of the first stream if it is of file type. 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BlobData::Item& item = blob_data_->items().at(current_item_index_); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsFileType(item.type())) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteCurrentFileReader(); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateFileStreamReader(current_item_index_, offset); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BlobURLRequestJob::ReadItem() { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Are we done with reading all the blob data? 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remaining_bytes_ == 0) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we get to the last item but still expect something to read, bail out 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since something is wrong. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_item_index_ >= blob_data_->items().size()) { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailure(net::ERR_FAILED); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute the bytes to read for current item. 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_to_read = ComputeBytesToRead(); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If nothing to read for current item, advance to next item. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes_to_read == 0) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdvanceItem(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadItem(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do the reading. 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BlobData::Item& item = blob_data_->items().at(current_item_index_); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item.type() == BlobData::Item::TYPE_BYTES) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBytesItem(item, bytes_to_read); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsFileType(item.type())) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadFileItem(GetFileStreamReader(current_item_index_), 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_to_read); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::AdvanceItem() { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the file if the current item is a file. 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteCurrentFileReader(); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Advance to the next item. 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_item_index_++; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_item_offset_ = 0; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::AdvanceBytesRead(int result) { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(result, 0); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do we finish reading the current item? 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_item_offset_ += result; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_item_offset_ == item_length_list_[current_item_index_]) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdvanceItem(); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subtract the remaining bytes. 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_bytes_ -= result; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(remaining_bytes_, 0); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adjust the read buffer. 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_buf_->DidConsume(result); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(read_buf_->BytesRemaining(), 0); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BlobURLRequestJob::ReadBytesItem(const BlobData::Item& item, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_to_read) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(read_buf_->BytesRemaining(), bytes_to_read); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(read_buf_->data(), 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item.bytes() + item.offset() + current_item_offset_, 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_to_read); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdvanceBytesRead(bytes_to_read); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BlobURLRequestJob::ReadFileItem(FileStreamReader* reader, 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_to_read) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(read_buf_->BytesRemaining(), bytes_to_read); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(reader); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int result = reader->Read( 384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) read_buf_.get(), 385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bytes_to_read, 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&BlobURLRequestJob::DidReadFile, base::Unretained(this))); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result >= 0) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Data is immediately available. 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetStatus().is_io_pending()) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidReadFile(result); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdvanceBytesRead(result); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == net::ERR_IO_PENDING) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailure(result); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::DidReadFile(int result) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result <= 0) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailure(net::ERR_FAILED); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdvanceBytesRead(result); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the read buffer is completely filled, we're done. 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_buf_->BytesRemaining()) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read = BytesReadCompleted(); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyReadComplete(bytes_read); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, continue the reading. 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read = 0; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ReadLoop(&bytes_read)) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyReadComplete(bytes_read); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::DeleteCurrentFileReader() { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IndexToReaderMap::iterator found = index_to_reader_.find(current_item_index_); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found != index_to_reader_.end() && found->second) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete found->second; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index_to_reader_.erase(found); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BlobURLRequestJob::BytesReadCompleted() { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read = read_buf_->BytesConsumed(); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_buf_ = NULL; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes_read; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BlobURLRequestJob::ComputeBytesToRead() const { 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 current_item_length = item_length_list_[current_item_index_]; 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 item_remaining = current_item_length - current_item_offset_; 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 buf_remaining = read_buf_->BytesRemaining(); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 max_remaining = std::numeric_limits<int>::max(); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 min = std::min(std::min(std::min(item_remaining, 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buf_remaining), 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remaining_bytes_), 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_remaining); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return static_cast<int>(min); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BlobURLRequestJob::ReadLoop(int* bytes_read) { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read until we encounter an error or could not get the data immediately. 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (remaining_bytes_ > 0 && read_buf_->BytesRemaining() > 0) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadItem()) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes_read = BytesReadCompleted(); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::NotifySuccess() { 465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::HttpStatusCode status_code = net::HTTP_OK; 466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (byte_range_set_ && byte_range_.IsValid()) 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) status_code = net::HTTP_PARTIAL_CONTENT; 468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HeadersCompleted(status_code); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::NotifyFailure(int error_code) { 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = true; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we already return the headers on success, we can't change the headers 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // now. Instead, we just error out. 476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (response_info_) { 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_code)); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::HttpStatusCode status_code = net::HTTP_INTERNAL_SERVER_ERROR; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (error_code) { 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case net::ERR_ACCESS_DENIED: 485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) status_code = net::HTTP_FORBIDDEN; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case net::ERR_FILE_NOT_FOUND: 488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) status_code = net::HTTP_NOT_FOUND; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case net::ERR_METHOD_NOT_SUPPORTED: 491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) status_code = net::HTTP_METHOD_NOT_ALLOWED; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case net::ERR_REQUEST_RANGE_NOT_SATISFIABLE: 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) status_code = net::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case net::ERR_FAILED: 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(false); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) HeadersCompleted(status_code); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void BlobURLRequestJob::HeadersCompleted(net::HttpStatusCode status_code) { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string status("HTTP/1.1 "); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status.append(base::IntToString(status_code)); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status.append(" "); 509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) status.append(net::GetHttpReasonPhrase(status_code)); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status.append("\0\0", 2); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (status_code == net::HTTP_OK || status_code == net::HTTP_PARTIAL_CONTENT) { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string content_length_header(net::HttpRequestHeaders::kContentLength); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_header.append(": "); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_length_header.append(base::Int64ToString(remaining_bytes_)); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->AddHeader(content_length_header); 5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (status_code == net::HTTP_PARTIAL_CONTENT) { 5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(byte_range_set_); 5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(byte_range_.IsValid()); 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string content_range_header(net::HttpResponseHeaders::kContentRange); 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content_range_header.append(": bytes "); 5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content_range_header.append(base::StringPrintf( 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "%" PRId64 "-%" PRId64, 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) byte_range_.first_byte_position(), byte_range_.last_byte_position())); 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content_range_header.append("/"); 5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content_range_header.append(base::StringPrintf("%" PRId64, total_size_)); 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers->AddHeader(content_range_header); 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!blob_data_->content_type().empty()) { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string content_type_header(net::HttpRequestHeaders::kContentType); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_type_header.append(": "); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_type_header.append(blob_data_->content_type()); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->AddHeader(content_type_header); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!blob_data_->content_disposition().empty()) { 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string content_disposition_header("Content-Disposition: "); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_disposition_header.append(blob_data_->content_disposition()); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->AddHeader(content_disposition_header); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_.reset(new net::HttpResponseInfo()); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_->headers = headers; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_expected_content_size(remaining_bytes_); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileStreamReader* BlobURLRequestJob::GetFileStreamReader(size_t index) { 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LT(index, blob_data_->items().size()); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BlobData::Item& item = blob_data_->items().at(index); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsFileType(item.type())) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index_to_reader_.find(index) == index_to_reader_.end()) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateFileStreamReader(index, 0); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(index_to_reader_[index]); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return index_to_reader_[index]; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BlobURLRequestJob::CreateFileStreamReader(size_t index, 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 additional_offset) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LT(index, blob_data_->items().size()); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BlobData::Item& item = blob_data_->items().at(index); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsFileType(item.type())); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0U, index_to_reader_.count(index)); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileStreamReader* reader = NULL; 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (item.type()) { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BlobData::Item::TYPE_FILE: 572d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) reader = FileStreamReader::CreateForLocalFile( 573d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_thread_proxy_.get(), 574d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.path(), 575d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.offset() + additional_offset, 576d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.expected_modification_time()); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BlobData::Item::TYPE_FILE_FILESYSTEM: 5791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci reader = file_system_context_ 5801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ->CreateFileStreamReader( 5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci storage::FileSystemURL(file_system_context_->CrackURL( 5821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci item.filesystem_url())), 5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci item.offset() + additional_offset, 5841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci item.length() == std::numeric_limits<uint64>::max() 5851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ? storage::kMaximumLength 5861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : item.length() - additional_offset, 5871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci item.expected_modification_time()) 58803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .release(); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(reader); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index_to_reader_[index] = reader; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace storage 598