///|
/// An HTTP request. Builders copy headers before returning.
///
/// ```mbt check
/// test {
/// let request = @http.Request::post("/items")
/// .header("Accept", "application/json")
/// .body_text("hello")
/// assert_eq(request.body, Bytes(b"hello"))
/// }
/// ```
pub(all) struct Request {
http_method : String
url : String
headers : Headers
body : Body
} derive(Eq, Debug)
///|
/// Compares all request fields.
pub extend Request with Eq::{equal, not_equal}
///|
/// Debug representation of a request.
pub extend Request with @debug.Debug::{to_repr}
///|
/// Creates a request with the supplied method, empty headers and an empty body.
pub fn Request::new(http_method : String, url : String) -> Request {
{ http_method, url, headers: Headers::new(), body: Bytes(b""), }
}
///|
/// Creates a GET request.
pub fn Request::get(url : String) -> Request {
Request::new("GET", url)
}
///|
/// Creates a POST request.
pub fn Request::post(url : String) -> Request {
Request::new("POST", url)
}
///|
/// Creates a PUT request.
pub fn Request::put(url : String) -> Request {
Request::new("PUT", url)
}
///|
/// Creates a PATCH request.
pub fn Request::patch(url : String) -> Request {
Request::new("PATCH", url)
}
///|
/// Creates a DELETE request.
pub fn Request::delete(url : String) -> Request {
Request::new("DELETE", url)
}
///|
/// Returns a new request with an appended header and independent headers.
pub fn Request::header(
self : Request,
name : String,
value : String,
) -> Request {
let headers = self.headers.copy()
headers.append(name, value)
{ ..self, headers, }
}
///|
/// Returns a new request with the supplied bytes and independent headers.
pub fn Request::body_bytes(self : Request, body : Bytes) -> Request {
{ ..self, headers: self.headers.copy(), body: Bytes(body), }
}
///|
/// Returns a new request whose body is read from `stream` as it is sent, and
/// independent headers. With `length`, the stream must produce exactly that
/// many bytes, sent as `Content-Length`; without it, a transport sends the
/// body chunked. The body can be sent once: see `StreamBody`.
pub fn Request::body_stream(
self : Request,
stream : &BodyStream,
length? : Int64,
) -> Request {
{
..self,
headers: self.headers.copy(),
body: Stream(StreamBody::new(stream, length?)),
}
}
///|
/// Returns a new request whose body is the UTF-8 encoding of the text, with
/// any lone surrogate written as U+FFFD (see `encode_utf8`).
pub fn Request::body_text(self : Request, body : String) -> Request {
self.body_bytes(encode_utf8(body))
}
///|
/// Encodes JSON as UTF-8 and supplies application/json only if content-type is absent.
pub fn Request::json_body(self : Request, body : Json) -> Request {
let request = self.body_text(body.stringify())
if !request.headers.contains("content-type") {
request.headers.set("content-type", "application/json")
}
request
}