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