| 
									
										
										
										
											2020-04-07 22:56:13 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2022-02-14 21:52:12 +00:00
										 |  |  |  * Copyright (c) 2022, Linus Groh <linusg@serenityos.org> | 
					
						
							| 
									
										
										
										
											2020-04-07 22:56:13 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-04-07 22:56:13 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-04 18:02:33 +00:00
										 |  |  | #include <AK/DeprecatedString.h>
 | 
					
						
							| 
									
										
										
										
											2023-07-27 21:40:41 +12:00
										 |  |  | #include <AK/URL.h>
 | 
					
						
							|  |  |  | #include <AK/URLParser.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-07 22:56:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-12 20:37:43 +01:00
										 |  |  | namespace Web::HTML { | 
					
						
							| 
									
										
										
										
											2020-04-07 22:56:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class Origin { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2022-03-14 13:21:51 -06:00
										 |  |  |     Origin() = default; | 
					
						
							| 
									
										
										
										
											2023-10-10 15:00:58 +03:30
										 |  |  |     Origin(Optional<DeprecatedString> const& scheme, AK::URL::Host const& host, u16 port) | 
					
						
							| 
									
										
										
										
											2022-09-29 01:37:44 +02:00
										 |  |  |         : m_scheme(scheme) | 
					
						
							| 
									
										
										
										
											2020-04-07 22:56:13 +02:00
										 |  |  |         , m_host(host) | 
					
						
							|  |  |  |         , m_port(port) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-14 21:52:12 +00:00
										 |  |  |     // https://html.spec.whatwg.org/multipage/origin.html#concept-origin-opaque
 | 
					
						
							| 
									
										
										
										
											2023-10-10 15:00:58 +03:30
										 |  |  |     bool is_opaque() const { return !m_scheme.has_value() && m_host.has<Empty>() && m_port == 0; } | 
					
						
							| 
									
										
										
										
											2020-04-07 22:56:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-10 15:00:58 +03:30
										 |  |  |     StringView scheme() const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return m_scheme.map([](auto& str) { return str.view(); }).value_or(StringView {}); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-27 21:40:41 +12:00
										 |  |  |     AK::URL::Host const& host() const { return m_host; } | 
					
						
							| 
									
										
										
										
											2020-04-07 22:56:13 +02:00
										 |  |  |     u16 port() const { return m_port; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-14 21:54:20 +00:00
										 |  |  |     // https://html.spec.whatwg.org/multipage/origin.html#same-origin
 | 
					
						
							|  |  |  |     bool is_same_origin(Origin const& other) const | 
					
						
							| 
									
										
										
										
											2020-09-22 18:25:48 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-02-14 21:54:20 +00:00
										 |  |  |         // 1. If A and B are the same opaque origin, then return true.
 | 
					
						
							|  |  |  |         if (is_opaque() && other.is_opaque()) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 2. If A and B are both tuple origins and their schemes, hosts, and port are identical, then return true.
 | 
					
						
							|  |  |  |         // 3. Return false.
 | 
					
						
							| 
									
										
										
										
											2022-09-29 01:37:44 +02:00
										 |  |  |         return scheme() == other.scheme() | 
					
						
							| 
									
										
										
										
											2020-09-22 18:25:48 +02:00
										 |  |  |             && host() == other.host() | 
					
						
							|  |  |  |             && port() == other.port(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-14 21:59:47 +00:00
										 |  |  |     // https://html.spec.whatwg.org/multipage/origin.html#same-origin-domain
 | 
					
						
							|  |  |  |     bool is_same_origin_domain(Origin const& other) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // 1. If A and B are the same opaque origin, then return true.
 | 
					
						
							|  |  |  |         if (is_opaque() && other.is_opaque()) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 2. If A and B are both tuple origins, run these substeps:
 | 
					
						
							|  |  |  |         if (!is_opaque() && !other.is_opaque()) { | 
					
						
							|  |  |  |             // 1. If A and B's schemes are identical, and their domains are identical and non-null, then return true.
 | 
					
						
							|  |  |  |             // FIXME: Check domains once supported.
 | 
					
						
							| 
									
										
										
										
											2022-09-29 01:37:44 +02:00
										 |  |  |             if (scheme() == other.scheme()) | 
					
						
							| 
									
										
										
										
											2022-02-14 21:59:47 +00:00
										 |  |  |                 return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // 2. Otherwise, if A and B are same origin and their domains are identical and null, then return true.
 | 
					
						
							|  |  |  |             // FIXME: Check domains once supported.
 | 
					
						
							|  |  |  |             if (is_same_origin(other)) | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 3. Return false.
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-28 09:50:11 -04:00
										 |  |  |     // https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin
 | 
					
						
							| 
									
										
										
										
											2022-12-04 18:02:33 +00:00
										 |  |  |     DeprecatedString serialize() const | 
					
						
							| 
									
										
										
										
											2022-02-28 09:50:11 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         // 1. If origin is an opaque origin, then return "null"
 | 
					
						
							|  |  |  |         if (is_opaque()) | 
					
						
							|  |  |  |             return "null"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 2. Otherwise, let result be origin's scheme.
 | 
					
						
							|  |  |  |         StringBuilder result; | 
					
						
							| 
									
										
										
										
											2022-09-29 01:37:44 +02:00
										 |  |  |         result.append(scheme()); | 
					
						
							| 
									
										
										
										
											2022-02-28 09:50:11 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // 3. Append "://" to result.
 | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         result.append("://"sv); | 
					
						
							| 
									
										
										
										
											2022-02-28 09:50:11 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // 4. Append origin's host, serialized, to result.
 | 
					
						
							| 
									
										
										
										
											2023-07-27 21:40:41 +12:00
										 |  |  |         result.append(URLParser::serialize_host(host()).release_value_but_fixme_should_propagate_errors().to_deprecated_string()); | 
					
						
							| 
									
										
										
										
											2022-02-28 09:50:11 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // 5. If origin's port is non-null, append a U+003A COLON character (:), and origin's port, serialized, to result.
 | 
					
						
							|  |  |  |         if (port() != 0) { | 
					
						
							| 
									
										
										
										
											2022-07-11 20:10:18 +00:00
										 |  |  |             result.append(':'); | 
					
						
							| 
									
										
										
										
											2022-12-04 18:02:33 +00:00
										 |  |  |             result.append(DeprecatedString::number(port())); | 
					
						
							| 
									
										
										
										
											2022-02-28 09:50:11 -04:00
										 |  |  |         } | 
					
						
							|  |  |  |         // 6. Return result
 | 
					
						
							| 
									
										
										
										
											2022-12-06 01:12:49 +00:00
										 |  |  |         return result.to_deprecated_string(); | 
					
						
							| 
									
										
										
										
											2022-02-28 09:50:11 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-14 15:50:47 +01:00
										 |  |  |     // https://html.spec.whatwg.org/multipage/origin.html#concept-origin-effective-domain
 | 
					
						
							| 
									
										
										
										
											2023-07-27 21:40:41 +12:00
										 |  |  |     Optional<AK::URL::Host> effective_domain() const | 
					
						
							| 
									
										
										
										
											2022-09-14 15:50:47 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         // 1. If origin is an opaque origin, then return null.
 | 
					
						
							|  |  |  |         if (is_opaque()) | 
					
						
							| 
									
										
										
										
											2023-07-27 21:40:41 +12:00
										 |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2022-09-14 15:50:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // FIXME: 2. If origin's domain is non-null, then return origin's domain.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 3. Return origin's host.
 | 
					
						
							|  |  |  |         return m_host; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-14 21:54:20 +00:00
										 |  |  |     bool operator==(Origin const& other) const { return is_same_origin(other); } | 
					
						
							| 
									
										
										
										
											2022-02-08 19:39:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-07 22:56:13 +02:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2023-10-10 15:00:58 +03:30
										 |  |  |     Optional<DeprecatedString> m_scheme; | 
					
						
							| 
									
										
										
										
											2023-07-27 21:40:41 +12:00
										 |  |  |     AK::URL::Host m_host; | 
					
						
							| 
									
										
										
										
											2020-04-07 22:56:13 +02:00
										 |  |  |     u16 m_port { 0 }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-08 19:39:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace AK { | 
					
						
							|  |  |  | template<> | 
					
						
							| 
									
										
										
										
											2022-07-12 20:37:43 +01:00
										 |  |  | struct Traits<Web::HTML::Origin> : public GenericTraits<Web::HTML::Origin> { | 
					
						
							|  |  |  |     static unsigned hash(Web::HTML::Origin const& origin) | 
					
						
							| 
									
										
										
										
											2022-02-08 19:39:47 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-07-27 21:40:41 +12:00
										 |  |  |         auto hash_without_host = pair_int_hash(origin.scheme().hash(), origin.port()); | 
					
						
							|  |  |  |         if (origin.host().has<Empty>()) | 
					
						
							|  |  |  |             return hash_without_host; | 
					
						
							|  |  |  |         return pair_int_hash(hash_without_host, URLParser::serialize_host(origin.host()).release_value_but_fixme_should_propagate_errors().hash()); | 
					
						
							| 
									
										
										
										
											2022-02-08 19:39:47 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | } // namespace AK
 |