/* * Copyright 2026 Flix Authors * * Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE.md file. */////// Type of HTTP responses, and its functions.///pubmod Net.HttpResponse {use IoError.ErrorKinduse IoError.IoErroruse Net.Bodyuse Net.HttpLayeruse Net.HttpResponseuse Net.HttpResponse.HttpResponse////// Type of HTTP responses.////// An HTTP response has a final URL, a status code, multi-valued headers, and a body.///pubenumHttpResponse({ url = String, status = Int32, headers = Map[String, List[String]], body = Body })////// Returns the final URL of the response `r` (after any redirects).///pubdefurl(r: HttpResponse): String = matchr {case HttpResponse(x) => x#url }////// Returns the status code of the response `r`.///pubdefstatus(r: HttpResponse): Int32 = matchr {case HttpResponse(x) => x#status }////// Returns the headers of the response `r`.///pubdefheaders(r: HttpResponse): Map[String, List[String]] = matchr {case HttpResponse(x) => x#headers }////// Returns the body of the response `r` as a string.////// If the body is binary, it is decoded as UTF-8.///pubdefbody(r: HttpResponse): String = matchr {case HttpResponse(x) => matchx#body {case Body.Text(s) => scase Body.Bytes(v) => HttpLayer.bytesToString(v) } }////// Returns the body of the response `r` as bytes.////// If the body is text, it is encoded as UTF-8.///pubdefbodyBytes(r: HttpResponse): Vector[Int8] = matchr {case HttpResponse(x) => matchx#body {case Body.Bytes(v) => vcase Body.Text(s) => HttpLayer.stringToBytes(s) } }////// Returns the list of values for the header with the given `name`, or `None` if not present.///pubdefheader(name: String, r: HttpResponse): Option[List[String]] =Map.get(name, headers(r))////// Returns the first value of the header with the given `name`, or `None` if not present.///pubdefheaderValue(name: String, r: HttpResponse): Option[String] =matchheader(name, r) {case Some(v :: _) => Some(v)case_ => None }////// Returns `true` if the response status is 200 OK.///pubdefisOk(r: HttpResponse): Bool = status(r) ==200////// Returns `true` if the response status is in the 2xx range.///pubdefisSuccess(r: HttpResponse): Bool =lets = status(r);200<=sands<=299////// Returns `true` if the response status is in the 3xx range.///pubdefisRedirect(r: HttpResponse): Bool =lets = status(r);300<=sands<=399////// Returns `true` if the response status is in the 4xx range.///pubdefisClientError(r: HttpResponse): Bool =lets = status(r);400<=sands<=499////// Returns `true` if the response status is in the 5xx range.///pubdefisServerError(r: HttpResponse): Bool =lets = status(r);500<=sands<=599////// Returns `true` if the response status is in the 4xx or 5xx range.///pubdefisError(r: HttpResponse): Bool =isClientError(r) orisServerError(r)////// Returns `Ok(r)` if the response status is in the 2xx range, or `Err` otherwise.///pubdefexpect(r: HttpResponse): Result[IoError, HttpResponse] =if (isSuccess(r)) Ok(r)else Err(IoError(ErrorKind.Other, "Unexpected HTTP status: ${status(r)}"))////// Returns the value of the `content-type` header, or `None` if not present.///pubdefcontentType(r: HttpResponse): Option[String] =headerValue("content-type", r)////// Returns the value of the `content-length` header parsed as an `Int64`, or `None` if not present or not a valid number.///pubdefcontentLength(r: HttpResponse): Option[Int64] =matchheaderValue("content-length", r) {case Some(v) => Int64.fromString(v)case None => None }}