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 "config.h"
6#include "core/frame/csp/CSPSource.h"
7
8#include "core/frame/csp/ContentSecurityPolicy.h"
9#include "platform/weborigin/KURL.h"
10#include "platform/weborigin/KnownPorts.h"
11#include "platform/weborigin/SecurityOrigin.h"
12#include "wtf/text/WTFString.h"
13
14namespace blink {
15
16CSPSource::CSPSource(ContentSecurityPolicy* policy, const String& scheme, const String& host, int port, const String& path, WildcardDisposition hostWildcard, WildcardDisposition portWildcard)
17    : m_policy(policy)
18    , m_scheme(scheme)
19    , m_host(host)
20    , m_port(port)
21    , m_path(path)
22    , m_hostWildcard(hostWildcard)
23    , m_portWildcard(portWildcard)
24{
25}
26
27bool CSPSource::matches(const KURL& url) const
28{
29    if (!schemeMatches(url))
30        return false;
31    if (isSchemeOnly())
32        return true;
33    return hostMatches(url) && portMatches(url) && pathMatches(url);
34}
35
36bool CSPSource::schemeMatches(const KURL& url) const
37{
38    if (m_scheme.isEmpty())
39        return m_policy->protocolMatchesSelf(url);
40    return equalIgnoringCase(url.protocol(), m_scheme);
41}
42
43bool CSPSource::hostMatches(const KURL& url) const
44{
45    const String& host = url.host();
46    if (equalIgnoringCase(host, m_host))
47        return true;
48    return m_hostWildcard == HasWildcard && host.endsWith("." + m_host, false);
49
50}
51
52bool CSPSource::pathMatches(const KURL& url) const
53{
54    if (m_path.isEmpty())
55        return true;
56
57    String path = decodeURLEscapeSequences(url.path());
58
59    if (m_path.endsWith("/"))
60        return path.startsWith(m_path, false);
61
62    return path == m_path;
63}
64
65bool CSPSource::portMatches(const KURL& url) const
66{
67    if (m_portWildcard == HasWildcard)
68        return true;
69
70    int port = url.port();
71
72    if (port == m_port)
73        return true;
74
75    if (!port)
76        return isDefaultPortForProtocol(m_port, url.protocol());
77
78    if (!m_port)
79        return isDefaultPortForProtocol(port, url.protocol());
80
81    return false;
82}
83
84bool CSPSource::isSchemeOnly() const
85{
86    return m_host.isEmpty();
87}
88
89} // namespace
90