Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the port of Origin be an Option<u16> #989

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions url/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ impl Url {
/// assert_eq!(url.origin(),
/// Origin::Tuple("ftp".into(),
/// Host::Domain("example.com".into()),
/// 21));
/// None));
/// # Ok(())
/// # }
/// # run().unwrap();
Expand All @@ -837,7 +837,7 @@ impl Url {
/// assert_eq!(url.origin(),
/// Origin::Tuple("https".into(),
/// Host::Domain("example.com".into()),
/// 443));
/// None));
/// # Ok(())
/// # }
/// # run().unwrap();
Expand Down
39 changes: 26 additions & 13 deletions url/src/origin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,45 @@
// except according to those terms.

use crate::host::Host;
use crate::parser::default_port;
use crate::Url;
use alloc::borrow::ToOwned;
use alloc::format;
use alloc::string::String;
use core::sync::atomic::{AtomicUsize, Ordering};

/// Get the origin from a URL according to the specification:
/// <https://url.spec.whatwg.org/#origin>
pub fn url_origin(url: &Url) -> Origin {
let scheme = url.scheme();
match scheme {
// > "blob"
// > 1. If url’s blob URL entry is non-null, then return url’s blob URL entry’s
// > environment’s origin.
// > 2. Let pathURL be the result of parsing the result of URL path serializing url.
// > 3. If pathURL is failure, then return a new opaque origin.
// > 4. If pathURL’s scheme is "http", "https", or "file", then return pathURL’s origin.
// > 5. Return a new opaque origin.
"blob" => {
let result = Url::parse(url.path());
match result {
Ok(ref url) => url_origin(url),
Err(_) => Origin::new_opaque(),
}
}
// > "ftp" "http" "https" "ws" "wss": Return the tuple origin (url’s scheme, url’s host,
// > url’s port, null).
//
"ftp" | "http" | "https" | "ws" | "wss" => Origin::Tuple(
scheme.to_owned(),
url.host().unwrap().to_owned(),
url.port_or_known_default().unwrap(),
url.port(),
),
// > "file": Unfortunate as it is, this is left as an exercise to the reader. When in
// > doubt, return a new opaque origin.
//
// TODO: Figure out what to do if the scheme is a file
"file" => Origin::new_opaque(),
// > Otherwise: Return a new opaque origin.
_ => Origin::new_opaque(),
}
}
Expand Down Expand Up @@ -58,7 +73,7 @@ pub enum Origin {
Opaque(OpaqueOrigin),

/// Consists of the URL's scheme, host and port
Tuple(String, Host<String>, u16),
Tuple(String, Host<String>, Option<u16>),
}

impl Origin {
Expand All @@ -78,12 +93,11 @@ impl Origin {
pub fn ascii_serialization(&self) -> String {
match *self {
Origin::Opaque(_) => "null".to_owned(),
Origin::Tuple(ref scheme, ref host, port) => {
if default_port(scheme) == Some(port) {
format!("{}://{}", scheme, host)
} else {
format!("{}://{}:{}", scheme, host, port)
}
Origin::Tuple(ref scheme, ref host, Some(port)) => {
format!("{}://{}:{}", scheme, host, port)
}
Origin::Tuple(ref scheme, ref host, _) => {
format!("{}://{}", scheme, host)
}
}
}
Expand All @@ -100,10 +114,9 @@ impl Origin {
}
_ => host.clone(),
};
if default_port(scheme) == Some(port) {
format!("{}://{}", scheme, host)
} else {
format!("{}://{}:{}", scheme, host, port)
match port {
Some(port) => format!("{}://{}:{}", scheme, host, port),
None => format!("{}://{}", scheme, host),
}
}
}
Expand Down
25 changes: 25 additions & 0 deletions url/tests/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,31 @@ fn test_origin_unicode_serialization() {
}
}

#[test]
fn test_origin_default_port() {
let urls_and_expected_origin_ports = [
("http://example.com:80", None),
("http://example.com", None),
("https://example.com:443", None),
("https://example.com", None),
("ftp://127.0.0.1:21/", None),
("ftp://127.0.0.1/", None),
("http://example.com:221", Some(221)),
("http://example.com:123", Some(123)),
("https://example.com:442", Some(442)),
("https://example.com:80", Some(80)),
("ftp://127.0.0.1:20/", Some(20)),
("ftp://127.0.0.1:80/", Some(80)),
];

for (url_string, expected_port) in &urls_and_expected_origin_ports {
match Url::parse(url_string).unwrap().origin() {
Origin::Opaque(..) => unreachable!("Should not have found an opaque origin."),
Origin::Tuple(_, _, port) => assert_eq!(port, *expected_port),
}
}
}

#[test]
#[cfg(feature = "std")]
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
Expand Down
Loading