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/fetcher/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/string_util.h"
12 #include "base/strings/stringprintf.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 "mojo/services/network/public/interfaces/network_service.mojom.h"
18 #include "mojo/util/filename_util.h"
19 #include "url/url_util.h"
25 void IgnoreResult(bool result
) {
30 // A loader for local files.
31 LocalFetcher::LocalFetcher(NetworkService
* network_service
,
33 const GURL
& url_without_query
,
34 const FetchCallback
& loader_callback
)
35 : Fetcher(loader_callback
),
37 path_(util::UrlToFilePath(url_without_query
)) {
38 TRACE_EVENT1("mojo_shell", "LocalFetcher::LocalFetcher", "url", url
.spec());
39 const std::string
ext(base::FilePath(path_
.Extension()).AsUTF8Unsafe());
40 if (network_service
&& !base::EqualsCaseInsensitiveASCII(ext
, ".mojo")) {
41 network_service
->GetMimeTypeFromFile(
43 base::Bind(&LocalFetcher::GetMimeTypeFromFileCallback
,
44 base::Unretained(this)));
46 loader_callback_
.Run(make_scoped_ptr(this));
50 void LocalFetcher::GetMimeTypeFromFileCallback(const mojo::String
& mime_type
) {
51 mime_type_
= mime_type
.To
<std::string
>();
52 loader_callback_
.Run(make_scoped_ptr(this));
55 const GURL
& LocalFetcher::GetURL() const {
59 GURL
LocalFetcher::GetRedirectURL() const {
60 return GURL::EmptyGURL();
63 GURL
LocalFetcher::GetRedirectReferer() const {
64 return GURL::EmptyGURL();
67 URLResponsePtr
LocalFetcher::AsURLResponse(base::TaskRunner
* task_runner
,
69 URLResponsePtr
response(URLResponse::New());
70 response
->url
= String::From(url_
);
72 response
->body
= data_pipe
.consumer_handle
.Pass();
74 if (base::GetFileSize(path_
, &file_size
)) {
75 response
->headers
= Array
<HttpHeaderPtr
>(1);
76 HttpHeaderPtr header
= HttpHeader::New();
77 header
->name
= "Content-Length";
78 header
->value
= base::StringPrintf("%" PRId64
, file_size
);
79 response
->headers
[0] = header
.Pass();
81 response
->mime_type
= String::From(MimeType());
82 common::CopyFromFile(path_
, data_pipe
.producer_handle
.Pass(), skip
,
83 task_runner
, base::Bind(&IgnoreResult
));
84 return response
.Pass();
87 void LocalFetcher::AsPath(
88 base::TaskRunner
* task_runner
,
89 base::Callback
<void(const base::FilePath
&, bool)> callback
) {
90 // Async for consistency with network case.
91 base::MessageLoop::current()->PostTask(
92 FROM_HERE
, base::Bind(callback
, path_
, base::PathExists(path_
)));
95 std::string
LocalFetcher::MimeType() {
99 bool LocalFetcher::HasMojoMagic() {
101 ReadFileToString(path_
, &magic
, strlen(kMojoMagic
));
102 return magic
== kMojoMagic
;
105 bool LocalFetcher::PeekFirstLine(std::string
* line
) {
106 std::string start_of_file
;
107 ReadFileToString(path_
, &start_of_file
, kMaxShebangLength
);
108 size_t return_position
= start_of_file
.find('\n');
109 if (return_position
== std::string::npos
)
111 *line
= start_of_file
.substr(0, return_position
+ 1);
115 } // namespace fetcher