OLD | NEW |
| (Empty) |
1 // Copyright 2013 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 "webkit/common/database/database_identifier.h" | |
6 | |
7 #include "base/strings/string_number_conversions.h" | |
8 #include "base/strings/string_util.h" | |
9 #include "url/url_canon.h" | |
10 | |
11 namespace storage { | |
12 | |
13 // static | |
14 std::string GetIdentifierFromOrigin(const GURL& origin) { | |
15 return DatabaseIdentifier::CreateFromOrigin(origin).ToString(); | |
16 } | |
17 | |
18 // static | |
19 GURL GetOriginFromIdentifier(const std::string& identifier) { | |
20 return DatabaseIdentifier::Parse(identifier).ToOrigin(); | |
21 } | |
22 | |
23 static bool SchemeIsUnique(const std::string& scheme) { | |
24 return scheme == "about" || scheme == "data" || scheme == "javascript"; | |
25 } | |
26 | |
27 // static | |
28 const DatabaseIdentifier DatabaseIdentifier::UniqueFileIdentifier() { | |
29 return DatabaseIdentifier("", "", 0, true, true); | |
30 } | |
31 | |
32 // static | |
33 DatabaseIdentifier DatabaseIdentifier::CreateFromOrigin(const GURL& origin) { | |
34 if (!origin.is_valid() || origin.is_empty() || | |
35 !origin.IsStandard() || SchemeIsUnique(origin.scheme())) | |
36 return DatabaseIdentifier(); | |
37 | |
38 if (origin.SchemeIsFile()) | |
39 return UniqueFileIdentifier(); | |
40 | |
41 int port = origin.IntPort(); | |
42 if (port == url::PORT_INVALID) | |
43 return DatabaseIdentifier(); | |
44 | |
45 // We encode the default port for the specified scheme as 0. GURL | |
46 // canonicalizes this as an unspecified port. | |
47 if (port == url::PORT_UNSPECIFIED) | |
48 port = 0; | |
49 | |
50 return DatabaseIdentifier(origin.scheme(), | |
51 origin.host(), | |
52 port, | |
53 false /* unique */, | |
54 false /* file */); | |
55 } | |
56 | |
57 // static | |
58 DatabaseIdentifier DatabaseIdentifier::Parse(const std::string& identifier) { | |
59 if (!base::IsStringASCII(identifier)) | |
60 return DatabaseIdentifier(); | |
61 if (identifier.find("..") != std::string::npos) | |
62 return DatabaseIdentifier(); | |
63 char forbidden[] = {'\\', '/', ':' ,'\0'}; | |
64 if (identifier.find_first_of(forbidden, 0, arraysize(forbidden)) != | |
65 std::string::npos) { | |
66 return DatabaseIdentifier(); | |
67 } | |
68 | |
69 size_t first_underscore = identifier.find_first_of('_'); | |
70 if (first_underscore == std::string::npos || first_underscore == 0) | |
71 return DatabaseIdentifier(); | |
72 | |
73 size_t last_underscore = identifier.find_last_of('_'); | |
74 if (last_underscore == std::string::npos || | |
75 last_underscore == first_underscore || | |
76 last_underscore == identifier.length() - 1) | |
77 return DatabaseIdentifier(); | |
78 | |
79 std::string scheme(identifier.data(), first_underscore); | |
80 if (scheme == "file") | |
81 return UniqueFileIdentifier(); | |
82 | |
83 // This magical set of schemes is always treated as unique. | |
84 if (SchemeIsUnique(scheme)) | |
85 return DatabaseIdentifier(); | |
86 | |
87 base::StringPiece port_str(identifier.begin() + last_underscore + 1, | |
88 identifier.end()); | |
89 int port = 0; | |
90 if (!base::StringToInt(port_str, &port) || port < 0 || port >= 1 << 16) | |
91 return DatabaseIdentifier(); | |
92 | |
93 std::string hostname(identifier.data() + first_underscore + 1, | |
94 last_underscore - first_underscore - 1); | |
95 GURL url(scheme + "://" + hostname + "/"); | |
96 | |
97 if (!url.IsStandard()) | |
98 hostname = ""; | |
99 | |
100 // If a url doesn't parse cleanly or doesn't round trip, reject it. | |
101 if (!url.is_valid() || url.scheme() != scheme || url.host() != hostname) | |
102 return DatabaseIdentifier(); | |
103 | |
104 return DatabaseIdentifier(scheme, hostname, port, false /* unique */, false); | |
105 } | |
106 | |
107 DatabaseIdentifier::DatabaseIdentifier() | |
108 : port_(0), | |
109 is_unique_(true), | |
110 is_file_(false) { | |
111 } | |
112 | |
113 DatabaseIdentifier::DatabaseIdentifier(const std::string& scheme, | |
114 const std::string& hostname, | |
115 int port, | |
116 bool is_unique, | |
117 bool is_file) | |
118 : scheme_(scheme), | |
119 hostname_(base::StringToLowerASCII(hostname)), | |
120 port_(port), | |
121 is_unique_(is_unique), | |
122 is_file_(is_file) { | |
123 } | |
124 | |
125 DatabaseIdentifier::~DatabaseIdentifier() {} | |
126 | |
127 std::string DatabaseIdentifier::ToString() const { | |
128 if (is_file_) | |
129 return "file__0"; | |
130 if (is_unique_) | |
131 return "__0"; | |
132 return scheme_ + "_" + hostname_ + "_" + base::IntToString(port_); | |
133 } | |
134 | |
135 GURL DatabaseIdentifier::ToOrigin() const { | |
136 if (is_file_) | |
137 return GURL("file:///"); | |
138 if (is_unique_) | |
139 return GURL(); | |
140 if (port_ == 0) | |
141 return GURL(scheme_ + "://" + hostname_); | |
142 return GURL(scheme_ + "://" + hostname_ + ":" + base::IntToString(port_)); | |
143 } | |
144 | |
145 } // namespace storage | |
OLD | NEW |