Skip to main content

mz_testdrive/action/
http.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10use anyhow::bail;
11use mz_ore::collections::HashSet;
12use reqwest::Method;
13use reqwest::header::CONTENT_TYPE;
14
15use crate::action::{ControlFlow, State};
16use crate::parser::BuiltinCommand;
17
18pub async fn run_request(
19    mut cmd: BuiltinCommand,
20    _: &mut State,
21) -> Result<ControlFlow, anyhow::Error> {
22    let url = cmd.args.string("url")?;
23    let method: Method = cmd.args.parse("method")?;
24    let content_type = cmd.args.opt_string("content-type");
25    let further_accepted_status_codes = match cmd.args.opt_string("accept-additional-status-codes")
26    {
27        Some(s) => s
28            .split(',')
29            .map(|s| s.parse::<u16>().unwrap())
30            .collect::<HashSet<u16>>(),
31        None => HashSet::new(),
32    };
33    cmd.args.done()?;
34    let body = cmd.input.join("\n");
35
36    println!("$ http-request {} {}\n{}", method, url, body);
37
38    let client = reqwest::Client::new();
39
40    let mut request = client.request(method, &url).body(body);
41
42    if let Some(value) = &content_type {
43        request = request.header(CONTENT_TYPE, value);
44    }
45
46    let response = request.send().await?;
47    let status = response.status();
48
49    println!("{}\n{}", status, response.text().await?);
50
51    if status.is_success() || further_accepted_status_codes.contains(&status.as_u16()) {
52        Ok(ControlFlow::Continue)
53    } else {
54        bail!("http request returned failing status: {}", status)
55    }
56}