Skip to content

Commit 5f86cbc

Browse files
authored
Merge pull request #53 from zaghaghi/feat/global-headers
feat: global request headers via -H/--header
2 parents bcd3819 + 82bdbd6 commit 5f86cbc

5 files changed

Lines changed: 40 additions & 9 deletions

File tree

src/app.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ pub struct App {
4242
}
4343

4444
impl App {
45-
pub async fn new(input: String) -> Result<Self> {
46-
let state = State::from_input(input).await?;
45+
pub async fn new(input: String, global_headers: Vec<(String, String)>) -> Result<Self> {
46+
let state = State::from_input(input, global_headers).await?;
4747
let home = Home::new()?;
4848
let config = Config::new()?;
4949
let mode = Mode::Home;

src/cli.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,12 @@ pub struct Cli {
1212
help = "Input file or url, in json or yaml format with openapi specification"
1313
)]
1414
pub input: String,
15+
16+
#[arg(
17+
short = 'H',
18+
long = "header",
19+
value_name = "NAME: VALUE",
20+
help = "Global header to attach to every request, in `Name: Value` form. May be repeated."
21+
)]
22+
pub headers: Vec<String>,
1523
}

src/main.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,30 @@ pub mod utils;
1414

1515
use clap::Parser;
1616
use cli::Cli;
17-
use color_eyre::eyre::Result;
17+
use color_eyre::eyre::{eyre, Result};
1818

1919
use crate::{
2020
app::App,
2121
utils::{initialize_logging, initialize_panic_handler},
2222
};
2323

24+
fn parse_header(raw: &str) -> Result<(String, String)> {
25+
let (name, value) = raw.split_once(':').ok_or_else(|| eyre!("invalid header `{raw}`: expected `Name: Value`"))?;
26+
let name = name.trim();
27+
if name.is_empty() {
28+
return Err(eyre!("invalid header `{raw}`: empty name"));
29+
}
30+
Ok((name.to_string(), value.trim().to_string()))
31+
}
32+
2433
async fn tokio_main() -> Result<()> {
2534
initialize_logging()?;
2635

2736
initialize_panic_handler()?;
2837

2938
let args = Cli::parse();
30-
let mut app = App::new(args.input).await?;
39+
let global_headers = args.headers.iter().map(|h| parse_header(h)).collect::<Result<Vec<_>>>()?;
40+
let mut app = App::new(args.input, global_headers).await?;
3141
app.run().await?;
3242

3343
Ok(())

src/panes/parameter_editor.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ impl ParameterEditor {
105105
schema: parameter.schema.clone(),
106106
});
107107
});
108+
109+
for (name, value) in &state.global_headers {
110+
if header_items.iter().any(|item: &ParameterItem| item.name.eq_ignore_ascii_case(name)) {
111+
continue;
112+
}
113+
header_items.push(ParameterItem { name: name.clone(), value: Some(value.clone()), ..Default::default() });
114+
}
115+
108116
if !path_items.is_empty() {
109117
self.parameters.push(ParameterTab {
110118
location: "Path".to_string(),

src/state.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub struct State {
2020
pub responses: HashMap<String, Response>,
2121
pub pending_operations: HashSet<String>,
2222
pub spinner_frame: usize,
23+
pub global_headers: Vec<(String, String)>,
2324
}
2425

2526
#[derive(Debug, Default, Clone)]
@@ -72,6 +73,7 @@ impl State {
7273
responses: HashMap::default(),
7374
pending_operations: HashSet::default(),
7475
spinner_frame: 0,
76+
global_headers: Vec::new(),
7577
})
7678
}
7779

@@ -104,15 +106,18 @@ impl State {
104106
responses: HashMap::default(),
105107
pending_operations: HashSet::default(),
106108
spinner_frame: 0,
109+
global_headers: Vec::new(),
107110
})
108111
}
109112

110-
pub async fn from_input(input: String) -> Result<Self> {
111-
if let Ok(url) = reqwest::Url::parse(input.as_str()) {
112-
State::from_url(url).await
113+
pub async fn from_input(input: String, global_headers: Vec<(String, String)>) -> Result<Self> {
114+
let mut state = if let Ok(url) = reqwest::Url::parse(input.as_str()) {
115+
State::from_url(url).await?
113116
} else {
114-
State::from_path(input).await
115-
}
117+
State::from_path(input).await?
118+
};
119+
state.global_headers = global_headers;
120+
Ok(state)
116121
}
117122

118123
pub fn get_operation(&self, operation_id: Option<String>) -> Option<&OperationItem> {

0 commit comments

Comments
 (0)