1// Copyright 2014 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.
4
5#include "mojo/shell/mojo_url_resolver.h"
6
7#include "base/base_paths.h"
8#include "base/files/file_path.h"
9#include "base/logging.h"
10#include "base/path_service.h"
11#include "net/base/filename_util.h"
12#include "url/url_util.h"
13
14namespace mojo {
15namespace shell {
16namespace {
17
18std::string MakeSharedLibraryName(const std::string& host_name) {
19#if defined(OS_WIN)
20  return host_name + ".dll";
21#elif defined(OS_LINUX) || defined(OS_ANDROID)
22  return "lib" + host_name + ".so";
23#elif defined(OS_MACOSX)
24  return host_name + ".so";
25#else
26  NOTREACHED() << "dynamic loading of services not supported";
27  return std::string();
28#endif
29}
30
31GURL AddTrailingSlashIfNeeded(const GURL& url) {
32  if (!url.has_path() || *url.path().rbegin() == '/')
33    return url;
34
35  std::string path(url.path() + '/');
36  GURL::Replacements replacements;
37  replacements.SetPathStr(path);
38  return url.ReplaceComponents(replacements);
39}
40
41}  // namespace
42
43MojoURLResolver::MojoURLResolver() {
44  // Needed to treat first component of mojo URLs as host, not path.
45  url::AddStandardScheme("mojo");
46
47  // By default, resolve mojo URLs to files living alongside the shell.
48  base::FilePath path;
49  PathService::Get(base::DIR_MODULE, &path);
50  default_base_url_ = AddTrailingSlashIfNeeded(net::FilePathToFileURL(path));
51}
52
53MojoURLResolver::~MojoURLResolver() {
54}
55
56void MojoURLResolver::SetBaseURL(const GURL& base_url) {
57  DCHECK(base_url.is_valid());
58  // Force a trailing slash on the base_url to simplify resolving
59  // relative files and URLs below.
60  base_url_ = AddTrailingSlashIfNeeded(base_url);
61}
62
63void MojoURLResolver::AddCustomMapping(const GURL& mojo_url,
64                                       const GURL& resolved_url) {
65  url_map_[mojo_url] = resolved_url;
66}
67
68void MojoURLResolver::AddLocalFileMapping(const GURL& mojo_url) {
69  local_file_set_.insert(mojo_url);
70}
71
72GURL MojoURLResolver::Resolve(const GURL& mojo_url) const {
73  std::map<GURL, GURL>::const_iterator it = url_map_.find(mojo_url);
74  if (it != url_map_.end())
75    return it->second;
76
77  std::string lib = MakeSharedLibraryName(mojo_url.host());
78
79  if (!base_url_.is_valid() ||
80      local_file_set_.find(mojo_url) != local_file_set_.end()) {
81    // Resolve to a local file URL.
82    return default_base_url_.Resolve(lib);
83  }
84
85  // Otherwise, resolve to an URL relative to base_url_.
86  return base_url_.Resolve(lib);
87}
88
89}  // namespace shell
90}  // namespace mojo
91