Index: url/origin.cc |
diff --git a/url/origin.cc b/url/origin.cc |
index 8aaa173fa5e0d98728067daca5af80b349e0ba28..0109b42eb1afdf3630662b128b945319d675144c 100644 |
--- a/url/origin.cc |
+++ b/url/origin.cc |
@@ -4,16 +4,101 @@ |
#include "url/origin.h" |
+#include "base/strings/string_number_conversions.h" |
#include "base/strings/string_util.h" |
+#include "url/gurl.h" |
+#include "url/url_canon.h" |
+#include "url/url_constants.h" |
+#include "url/url_util.h" |
namespace url { |
-Origin::Origin() : string_("null") {} |
+Origin::Origin() { |
+ Init(GURL()); |
+} |
+ |
+Origin::Origin(const GURL& url) { |
+ Init(url); |
+} |
+ |
+Origin::Origin(const std::string& scheme, |
+ const std::string& host, |
+ uint16 port) { |
+ // Special-case unique origins (because GURL normalizes '://:0' into a |
+ // valid URL, which is unexpected: https://crbug.com/493123). Otherwise, pass |
+ // the data through GURL for normalization: |
+ if (!scheme.size() && !host.size() && !port) { |
+ Init(GURL()); |
+ } else { |
+ Init(GURL(scheme + kStandardSchemeSeparator + host + |
+ (port ? ":" + base::IntToString(port) : ""))); |
+ } |
+} |
+ |
+Origin::Origin(const std::string& origin) { |
+ // Pass the string through GURL for normalization: |
+ Init(GURL(origin)); |
+} |
+ |
+void Origin::Init(const GURL& url) { |
+ DCHECK(!url.SchemeIsFileSystem() || url.inner_url()); |
+ |
+ // Start with a unique origin, parse from there: |
+ scheme_.clear(); |
+ host_.clear(); |
+ port_ = 0; |
+ unique_ = true; |
+ serialization_requires_port_ = false; |
+ valid_ = false; |
+ |
+ url::Replacements<char> replacements; |
+ replacements.ClearUsername(); |
+ replacements.ClearPassword(); |
+ replacements.ClearPath(); |
+ replacements.ClearQuery(); |
+ replacements.ClearRef(); |
+ |
+ GURL origin = url.SchemeIsFileSystem() |
+ ? url.inner_url()->ReplaceComponents(replacements) |
+ : url.ReplaceComponents(replacements); |
+ |
+ if (!origin.is_valid()) |
+ return; |
+ |
+ valid_ = true; |
+ |
+ if (!origin.IsStandard()) |
+ return; |
+ |
+ unique_ = false; |
+ scheme_ = origin.scheme(); |
+ |
+ if (origin.SchemeIs(kFileScheme)) |
+ return; |
+ |
+ host_ = origin.host(); |
+ port_ = origin.EffectiveIntPort(); |
+ serialization_requires_port_ = origin.IntPort() != PORT_UNSPECIFIED; |
+} |
+ |
+std::string Origin::serialize() const { |
+ if (unique_) |
+ return kUniqueOriginSerialization; |
+ |
+ if (host_.empty()) |
+ return scheme_ + kStandardSchemeSeparator; |
+ |
+ return scheme_ + kStandardSchemeSeparator + host_ + |
+ (serialization_requires_port_ ? ":" + base::IntToString(port_) : ""); |
+} |
+ |
+bool Origin::IsSameOriginWith(const Origin& other) const { |
+ return !unique_ && !other.unique_ && scheme_ == other.scheme_ && |
+ host_ == other.host_ && port_ == other.port_; |
+} |
-Origin::Origin(const std::string& origin) : string_(origin) { |
- DCHECK(origin == "null" || MatchPattern(origin, "?*://?*")); |
- DCHECK_GT(origin.size(), 0u); |
- DCHECK(origin == "file://" || origin[origin.size() - 1] != '/'); |
+std::ostream& operator<<(std::ostream& out, const url::Origin& url) { |
+ return out << url.serialize(); |
} |
} // namespace url |