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/fileapi/file_system_url_request_job.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_util_proxy.h" 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/file_stream.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/mime_util.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_info.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/file_stream_reader.h" 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h" 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h" 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h" 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::NetworkDelegate; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::URLRequest; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::URLRequestJob; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::URLRequestStatus; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static net::HttpResponseHeaders* CreateHttpResponseHeaders() { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HttpResponseHeaders expects its input string to be terminated by two NULs. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kStatus[] = "HTTP/1.1 200 OK\0"; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kStatusLen = arraysize(kStatus); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpResponseHeaders* headers = 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new net::HttpResponseHeaders(std::string(kStatus, kStatusLen)); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell WebKit never to cache this content. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string cache_control(net::HttpRequestHeaders::kCacheControl); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_control.append(": no-cache"); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers->AddHeader(cache_control); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return headers; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemURLRequestJob::FileSystemURLRequestJob( 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequest* request, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkDelegate* network_delegate, 5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const std::string& storage_domain, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : URLRequestJob(request, network_delegate), 6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) storage_domain_(storage_domain), 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_context_(file_system_context), 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_directory_(false), 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) remaining_bytes_(0), 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_(this) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemURLRequestJob::~FileSystemURLRequestJob() {} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemURLRequestJob::Start() { 72b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&FileSystemURLRequestJob::StartAsync, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemURLRequestJob::Kill() { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_.reset(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestJob::Kill(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool FileSystemURLRequestJob::ReadRawData(net::IOBuffer* dest, 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int dest_size, 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int* bytes_read) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(dest_size, 0); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(remaining_bytes_, 0); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reader_.get() == NULL) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remaining_bytes_ < dest_size) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_size = static_cast<int>(remaining_bytes_); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dest_size) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes_read = 0; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int rv = reader_->Read(dest, dest_size, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&FileSystemURLRequestJob::DidRead, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv >= 0) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Data is immediately available. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes_read = rv; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_bytes_ -= rv; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(remaining_bytes_, 0); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == net::ERR_IO_PENDING) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailed(rv); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileSystemURLRequestJob::GetMimeType(std::string* mime_type) const { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(url_.is_valid()); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::StringType extension = url_.path().Extension(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension.empty()) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension = extension.substr(1); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::GetWellKnownMimeTypeFromExtension(extension, mime_type); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemURLRequestJob::SetExtraRequestHeaders( 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpRequestHeaders& headers) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string range_header; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<net::HttpByteRange> ranges; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ranges.size() == 1) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) byte_range_ = ranges[0]; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't support multiple range requests in one single URL request. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(adamk): decide whether we want to support multiple range 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requests. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailed(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { 147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (response_info_) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *info = *response_info_; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FileSystemURLRequestJob::GetResponseCode() const { 152b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (response_info_) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 200; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return URLRequestJob::GetResponseCode(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemURLRequestJob::StartAsync() { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!reader_.get()); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_ = file_system_context_->CrackURL(request_->url()); 16223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!url_.is_valid()) { 16323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) file_system_context_->AttemptAutoMountForURLRequest( 16423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) request_, 16523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) storage_domain_, 16623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&FileSystemURLRequestJob::DidAttemptAutoMount, 16723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) weak_factory_.GetWeakPtr())); 16823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 16923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!file_system_context_->CanServeURLRequest(url_)) { 17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // In incognito mode the API is not usable and there should be no data. 17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) NotifyFailed(net::ERR_FILE_NOT_FOUND); 17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->GetMetadata( 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&FileSystemURLRequestJob::DidGetMetadata, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void FileSystemURLRequestJob::DidAttemptAutoMount(base::File::Error result) { 18223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (result >= 0 && 18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) file_system_context_->CrackURL(request_->url()).is_valid()) { 18423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) StartAsync(); 18523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else { 18623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NotifyFailed(net::ERR_FILE_NOT_FOUND); 18723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 18823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 18923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemURLRequestJob::DidGetMetadata( 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error_code, 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info) { 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error_code != base::File::FILE_OK) { 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NotifyFailed(error_code == base::File::FILE_ERROR_INVALID_URL ? 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::ERR_INVALID_URL : net::ERR_FILE_NOT_FOUND); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may have been orphaned... 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_directory_ = file_info.is_directory; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!byte_range_.ComputeBounds(file_info.size)) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailed(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_directory_) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_bytes_ = byte_range_.last_byte_position() - 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) byte_range_.first_byte_position() + 1; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(remaining_bytes_, 0); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!reader_.get()); 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reader_ = file_system_context_->CreateFileStreamReader( 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url_, byte_range_.first_byte_position(), remaining_bytes_, base::Time()); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_expected_content_size(remaining_bytes_); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_.reset(new net::HttpResponseInfo()); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_info_->headers = CreateHttpResponseHeaders(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemURLRequestJob::DidRead(int result) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result > 0) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(URLRequestStatus()); // Clear the IO_PENDING status 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (result == 0) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus()); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyFailed(result); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_bytes_ -= result; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(remaining_bytes_, 0); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyReadComplete(result); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileSystemURLRequestJob::IsRedirectResponse(GURL* location, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* http_status_code) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_directory_) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This happens when we discovered the file is a directory, so needs a 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // slash at the end of the path. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string new_path = request_->url().path(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_path.push_back('/'); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL::Replacements replacements; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) replacements.SetPathStr(new_path); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *location = request_->url().ReplaceComponents(replacements); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *http_status_code = 301; // simulate a permanent redirect 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSystemURLRequestJob::NotifyFailed(int rv) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace storage 265