| 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 |