summaryrefslogtreecommitdiffstats
path: root/mojo/fetcher/data_fetcher.cc
blob: e785be7be9d074f41d927114d831e8e3abf199e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/fetcher/data_fetcher.h"

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/thread_task_runner_handle.h"
#include "net/base/data_url.h"
#include "third_party/mojo/src/mojo/public/cpp/system/data_pipe.h"

namespace mojo {
namespace fetcher {

ScopedDataPipeConsumerHandle CreateConsumerHandleForString(
    const std::string& data) {
  uint32_t num_bytes = static_cast<uint32_t>(data.size());
  MojoCreateDataPipeOptions options;
  options.struct_size = sizeof(MojoCreateDataPipeOptions);
  options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
  options.element_num_bytes = 1;
  options.capacity_num_bytes = num_bytes;
  mojo::DataPipe data_pipe(options);
  MojoResult result =
      WriteDataRaw(data_pipe.producer_handle.get(), data.data(), &num_bytes,
                   MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
  CHECK_EQ(MOJO_RESULT_OK, result);
  return data_pipe.consumer_handle.Pass();
}

// static
void DataFetcher::Start(const GURL& url, const FetchCallback& loader_callback) {
  // The object manages its own lifespan.
  new DataFetcher(url, loader_callback);
}

DataFetcher::DataFetcher(const GURL& url, const FetchCallback& loader_callback)
    : Fetcher(loader_callback), url_(url) {
  BuildAndDispatchResponse();
}

DataFetcher::~DataFetcher() {}

void DataFetcher::BuildAndDispatchResponse() {
  response_ = URLResponse::New();
  response_->url = url_.spec();

  response_->status_code = 400;  // Bad request
  if (url_.SchemeIs(url::kDataScheme)) {
    std::string mime_type, charset, data;
    if (net::DataURL::Parse(url_, &mime_type, &charset, &data)) {
      response_->status_code = 200;
      response_->mime_type = mime_type;
      response_->charset = charset;
      if (!data.empty())
        response_->body = CreateConsumerHandleForString(data);
    }
  }

  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::Bind(loader_callback_,
                            base::Passed(make_scoped_ptr<Fetcher>(this))));
}

const GURL& DataFetcher::GetURL() const {
  return url_;
}

GURL DataFetcher::GetRedirectURL() const {
  return GURL::EmptyGURL();
}

GURL DataFetcher::GetRedirectReferer() const {
  return GURL::EmptyGURL();
}

URLResponsePtr DataFetcher::AsURLResponse(base::TaskRunner* task_runner,
                                          uint32_t skip) {
  DCHECK(response_);
  return response_.Pass();
}

void DataFetcher::AsPath(
    base::TaskRunner* task_runner,
    base::Callback<void(const base::FilePath&, bool)> callback) {
  NOTIMPLEMENTED();
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::Bind(callback, base::FilePath(), false));
}

std::string DataFetcher::MimeType() {
  DCHECK(response_);
  return response_->mime_type;
}

bool DataFetcher::HasMojoMagic() {
  return false;
}

bool DataFetcher::PeekFirstLine(std::string* line) {
  // This is only called for 'mojo magic' (i.e. detecting shebang'ed
  // content-handler. Since HasMojoMagic() returns false above, this should
  // never be reached.
  NOTREACHED();
  return false;
}

}  // namespace fetcher
}  // namespace mojo