// PKL-129: HTTP fetch wrapper for the JS target. `mizchi/x/http`
// supplies a Node.js / browser `fetch`-backed `get` implementation,
// so the JS target resolves `https://` imports too.
//
// `main` runs as `async fn main` so the call site can await
// `@http.get` directly; the wrapper just captures the body / errors
// into an `Option` return.
///|
pub async fn fetch_uri(url : String) -> String? {
let mut current = url
let mut remaining = 5
while remaining > 0 {
try {
let (resp, body) = @http.get(current)
if is_http_redirect(resp.code) {
match resp.headers.get("location") {
Some(next) => {
current = next
remaining = remaining - 1
continue
}
None => {
println(
"http \{resp.code} \{resp.reason} fetching \{current} (no Location header)",
)
return None
}
}
}
if resp.code < 200 || resp.code >= 300 {
println("http \{resp.code} \{resp.reason} fetching \{current}")
return None
}
return Some(body.text())
} catch {
e => {
println("http fetch failed: \{e}")
return None
}
}
}
println("http fetch failed: too many redirects (last url: \{current})")
None
}
///|
pub async fn fetch_uri_bytes(url : String) -> Bytes? {
let mut current = url
let mut remaining = 5
while remaining > 0 {
try {
let (resp, body) = @http.get(current)
if is_http_redirect(resp.code) {
match resp.headers.get("location") {
Some(next) => {
current = next
remaining = remaining - 1
continue
}
None => {
println(
"http \{resp.code} \{resp.reason} fetching \{current} (no Location header)",
)
return None
}
}
}
if resp.code < 200 || resp.code >= 300 {
println("http \{resp.code} \{resp.reason} fetching \{current}")
return None
}
return Some(body.binary())
} catch {
e => {
println("http fetch failed: \{e}")
return None
}
}
}
println("http fetch failed: too many redirects (last url: \{current})")
None
}