///|
pub fn url_path(url_or_path : String) -> String {
let text = trim_ascii(url_or_path)
if text == "" {
return "/"
}
normalize_path(strip_fragment(strip_scheme_and_authority(text)))
}
///|
pub fn url_path_without_query(url_or_path : String) -> String {
let path = url_path(url_or_path)
match path.find("?") {
Some(index) => path.unsafe_substring(start=0, end=index)
None => path
}
}
///|
pub fn url_query(url_or_path : String) -> String? {
let path = url_path(url_or_path)
match path.find("?") {
Some(index) if index + 1 < path.length() =>
Some(path.unsafe_substring(start=index + 1, end=path.length()))
Some(_) => Some("")
None => None
}
}
///|
pub fn strip_fragment(text : String) -> String {
match text.find("#") {
Some(index) => text.unsafe_substring(start=0, end=index)
None => text
}
}
///|
pub fn strip_scheme_and_authority(text : String) -> String {
match text.find("://") {
Some(index) => {
let rest = text.unsafe_substring(start=index + 3, end=text.length())
match rest.find("/") {
Some(path_start) =>
rest.unsafe_substring(start=path_start, end=rest.length())
None => "/"
}
}
None => text
}
}
///|
pub fn can_fetch_url(text : String, agent : String, url : String) -> Bool {
allowed(text, agent, url_path(url))
}
///|
pub fn decide_url(robots : Robots, agent : String, url : String) -> Decision {
decide(robots, agent, url_path(url))
}
///|
pub fn explain_urls(
text : String,
agent : String,
urls : Array[String],
) -> String {
let paths : Array[String] = []
for url in urls {
paths.push(url_path(url))
}
explain(text, agent, paths)
}
///|
pub fn url_host(url : String) -> String? {
match url.find("://") {
Some(index) => {
let rest = url.unsafe_substring(start=index + 3, end=url.length())
let host_port = match rest.find("/") {
Some(path_start) => rest.unsafe_substring(start=0, end=path_start)
None => rest
}
let host = match host_port.find(":") {
Some(colon) => host_port.unsafe_substring(start=0, end=colon)
None => host_port
}
if host == "" {
None
} else {
Some(host)
}
}
None => None
}
}
///|
pub fn host_matches_robots(robots : Robots, url : String) -> Bool {
if robots.hosts.is_empty() {
return true
}
match url_host(url) {
Some(host) => contains_string_case_insensitive(robots.hosts, host)
None => false
}
}
///|
pub fn contains_string_case_insensitive(
values : Array[String],
value : String,
) -> Bool {
let needle = lower_ascii(value)
for item in values {
if lower_ascii(item) == needle {
return true
}
}
false
}