summaryrefslogtreecommitdiff
path: root/chromium/mojo/runner/url_resolver.cc
blob: e0ab27c260a2c75375686831b7eb1a3662016058 (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
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright 2014 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/runner/url_resolver.h"

#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "mojo/runner/switches.h"
#include "mojo/shell/query_util.h"
#include "mojo/util/filename_util.h"
#include "url/url_util.h"

namespace mojo {
namespace runner {

URLResolver::URLResolver() {
  // Needed to treat first component of mojo URLs as host, not path.
  url::AddStandardScheme("mojo");
}

URLResolver::~URLResolver() {
}

// static
std::vector<URLResolver::OriginMapping> URLResolver::GetOriginMappings(
    const base::CommandLine::StringVector& args) {
  std::vector<OriginMapping> origin_mappings;
  const std::string kArgsForSwitches[] = {
      "-" + std::string(switches::kMapOrigin) + "=",
      "--" + std::string(switches::kMapOrigin) + "=",
  };
  for (auto& arg : args) {
    for (size_t i = 0; i < arraysize(kArgsForSwitches); i++) {
      const std::string& argsfor_switch = kArgsForSwitches[i];
      std::string arg_string;
#if defined(OS_WIN)
      arg_string = base::UTF16ToUTF8(arg);
#else
      arg_string = arg;
#endif
      if (arg_string.compare(0, argsfor_switch.size(), argsfor_switch) == 0) {
        std::string value =
            arg_string.substr(argsfor_switch.size(), std::string::npos);
        size_t delim = value.find('=');
        if (delim <= 0 || delim >= value.size())
          continue;
        origin_mappings.push_back(
            OriginMapping(value.substr(0, delim),
                          value.substr(delim + 1, std::string::npos)));
      }
    }
  }
  return origin_mappings;
}

void URLResolver::AddURLMapping(const GURL& url, const GURL& mapped_url) {
  url_map_[url] = mapped_url;
}

void URLResolver::AddOriginMapping(const GURL& origin, const GURL& base_url) {
  if (!origin.is_valid() || !base_url.is_valid() ||
      origin != origin.GetOrigin()) {
    // Disallow invalid mappings.
    LOG(ERROR) << "Invalid origin for mapping: " << origin;
    return;
  }
  // Force both origin and base_url to have trailing slashes.
  origin_map_[origin] = util::AddTrailingSlashIfNeeded(base_url);
}

GURL URLResolver::ApplyMappings(const GURL& url) const {
  std::string query;
  GURL mapped_url = shell::GetBaseURLAndQuery(url, &query);
  for (;;) {
    const auto& url_it = url_map_.find(mapped_url);
    if (url_it != url_map_.end()) {
      mapped_url = url_it->second;
      continue;
    }

    GURL origin = mapped_url.GetOrigin();
    const auto& origin_it = origin_map_.find(origin);
    if (origin_it == origin_map_.end())
      break;
    mapped_url = GURL(origin_it->second.spec() +
                      mapped_url.spec().substr(origin.spec().length()));
  }

  if (query.length())
    mapped_url = GURL(mapped_url.spec() + query);
  return mapped_url;
}

void URLResolver::SetMojoBaseURL(const GURL& mojo_base_url) {
  DCHECK(mojo_base_url.is_valid());
  // Force a trailing slash on the base_url to simplify resolving
  // relative files and URLs below.
  mojo_base_url_ = util::AddTrailingSlashIfNeeded(mojo_base_url);
}

GURL URLResolver::ResolveMojoURL(const GURL& mojo_url) const {
  if (mojo_url.scheme() != "mojo") {
    // The mapping has produced some sort of non-mojo: URL - file:, http:, etc.
    return mojo_url;
  }

  // It's still a mojo: URL, use the default mapping scheme.
  std::string query;
  GURL base_url = shell::GetBaseURLAndQuery(mojo_url, &query);
  if (mojo_base_url_.SchemeIsFile()) {
    const GURL url_with_directory(
        mojo_base_url_.Resolve(base_url.host() + "/"));
    const base::FilePath file_path(util::UrlToFilePath(url_with_directory));
    if (base::DirectoryExists(file_path))
      return url_with_directory.Resolve(base_url.host() + ".mojo" + query);
  }
  return mojo_base_url_.Resolve(base_url.host() + ".mojo" + query);
}

}  // namespace runner
}  // namespace mojo