1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "mojo/shell/application_manager/local_fetcher.h"
8 #include "base/files/file_util.h"
9 #include "base/format_macros.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/trace_event/trace_event.h"
14 #include "mojo/common/common_type_converters.h"
15 #include "mojo/common/data_pipe_utils.h"
16 #include "mojo/common/url_type_converters.h"
17 #include "url/url_util.h"
24 void IgnoreResult(bool result
) {
29 // A loader for local files.
30 LocalFetcher::LocalFetcher(const GURL
& url
,
31 const GURL
& url_without_query
,
32 const FetchCallback
& loader_callback
)
33 : Fetcher(loader_callback
), url_(url
), path_(UrlToFile(url_without_query
)) {
34 TRACE_EVENT1("mojo_shell", "LocalFetcher::LocalFetcher", "url", url
.spec());
35 loader_callback_
.Run(make_scoped_ptr(this));
38 base::FilePath
LocalFetcher::UrlToFile(const GURL
& url
) {
39 DCHECK(url
.SchemeIsFile());
40 url::RawCanonOutputW
<1024> output
;
41 url::DecodeURLEscapeSequences(url
.path().data(),
42 static_cast<int>(url
.path().length()), &output
);
43 base::string16 decoded_path
= base::string16(output
.data(), output
.length());
45 base::TrimString(decoded_path
, L
"/", &decoded_path
);
46 base::FilePath
path(decoded_path
);
48 base::FilePath
path(base::UTF16ToUTF8(decoded_path
));
53 const GURL
& LocalFetcher::GetURL() const {
57 GURL
LocalFetcher::GetRedirectURL() const {
58 return GURL::EmptyGURL();
61 URLResponsePtr
LocalFetcher::AsURLResponse(base::TaskRunner
* task_runner
,
63 URLResponsePtr
response(URLResponse::New());
64 response
->url
= String::From(url_
);
66 response
->body
= data_pipe
.consumer_handle
.Pass();
68 if (base::GetFileSize(path_
, &file_size
)) {
69 response
->headers
= Array
<String
>(1);
70 response
->headers
[0] =
71 base::StringPrintf("Content-Length: %" PRId64
, file_size
);
73 common::CopyFromFile(path_
, data_pipe
.producer_handle
.Pass(), skip
,
74 task_runner
, base::Bind(&IgnoreResult
));
75 return response
.Pass();
78 void LocalFetcher::AsPath(
79 base::TaskRunner
* task_runner
,
80 base::Callback
<void(const base::FilePath
&, bool)> callback
) {
81 // Async for consistency with network case.
82 base::MessageLoop::current()->PostTask(
83 FROM_HERE
, base::Bind(callback
, path_
, base::PathExists(path_
)));
86 std::string
LocalFetcher::MimeType() {
90 bool LocalFetcher::HasMojoMagic() {
92 ReadFileToString(path_
, &magic
, strlen(kMojoMagic
));
93 return magic
== kMojoMagic
;
96 bool LocalFetcher::PeekFirstLine(std::string
* line
) {
97 std::string start_of_file
;
98 ReadFileToString(path_
, &start_of_file
, kMaxShebangLength
);
99 size_t return_position
= start_of_file
.find('\n');
100 if (return_position
== std::string::npos
)
102 *line
= start_of_file
.substr(0, return_position
+ 1);