Skip to content

Commit

Permalink
Parse query params separately
Browse files Browse the repository at this point in the history
  • Loading branch information
TheRealLorenz committed Nov 30, 2023
1 parent b0393ff commit 1914f6f
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 6 deletions.
7 changes: 6 additions & 1 deletion demo.http
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ Bar: Baz

###

PUT https://httpin.org/put
PUT https://httpbin.org/put

{
"foo": "bar"
}

###

GET https://httpbin.org/get?param1=2&param2=3

37 changes: 34 additions & 3 deletions rq-cli/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,41 @@ enum FocusState {

impl MenuItem for HttpRequest {
fn render(&self) -> Vec<ratatui::text::Line<'_>> {
let mut lines = vec![Line::from(vec![
let mut lines = Vec::new();

let mut first_line_spans = vec![
Span::styled(self.method.to_string(), Style::default().fg(Color::Green)),
Span::raw(format!(" {} {:?}", self.url, self.version)),
])];
Span::raw(" "),
Span::raw(self.url.as_str()),
];
let version_span = Span::raw(format!(" {:?}", self.version));

let mut query = self
.query
.iter()
.enumerate()
.map(|(i, (k, v))| {
Line::from(vec![
Span::raw(" ".repeat(self.method.to_string().len() + 1)),
Span::styled(
if i == 0 { "?" } else { "&" },
Style::default().fg(Color::Blue),
),
Span::raw(k),
Span::raw("="),
Span::raw(v),
])
})
.collect::<Vec<_>>();

if query.is_empty() {
first_line_spans.push(version_span);
lines.push(Line::from(first_line_spans));
} else {
lines.push(Line::from(first_line_spans));
query.last_mut().unwrap().spans.push(version_span);
lines.extend(query);
}

let headers: Vec<Line> = self
.headers()
Expand Down
9 changes: 7 additions & 2 deletions rq-core/src/grammar.pest
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ request = {
body?
}

request_line = _{ (method ~ " "+)? ~ uri ~ (" "+ ~ version)? ~ NEWLINE }
uri = { (!whitespace ~ ANY)+ }
request_line = _{ (method ~ " "+)? ~ uri ~ query? ~ (" "+ ~ version)? ~ NEWLINE }
uri = { (!(whitespace| "?") ~ ANY)+ }
method = { ("GET" | "DELETE" | "POST" | "PUT") }
version = { "HTTP/" ~ ("0.9" | "1.0" | "1.1" | "2.0" | "3.0") }
whitespace = _{ " " | "\t" | NEWLINE }

query = { "?" ~ query_item ~ ("&" ~ query_item)* }
query_item = { query_name ~ "=" ~ query_value }
query_name = { (!(NEWLINE | "=") ~ ANY)+ }
query_value = { (!(NEWLINE | "&") ~ ANY)+ }

headers = { header+ }
header = { header_name ~ ":" ~ whitespace ~ header_value ~ NEWLINE }
header_name = { (!(NEWLINE | ":") ~ ANY)+ }
Expand Down
19 changes: 19 additions & 0 deletions rq-core/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ fn http_version_from_str(input: &str) -> Version {
pub struct HttpRequest {
pub method: Method,
pub url: String,
pub query: HashMap<String, String>,
pub version: Version,
headers: HttpHeaders,
pub body: String,
Expand All @@ -80,6 +81,23 @@ impl<'i> From<Pair<'i, Rule>> for HttpRequest {
.unwrap_or_default();

let url = pairs.next().unwrap().as_str().to_string();

let query = pairs
.next_if(|pair| pair.as_rule() == Rule::query)
.map(|pair| {
pair.into_inner()
.map(|pair| {
let mut pairs = pair.into_inner();

let key = pairs.next().unwrap().as_str().to_string();
let value = pairs.next().unwrap().as_str().to_string();

(key, value)
})
.collect::<HashMap<String, String>>()
})
.unwrap_or_default();

let version = pairs
.next_if(|pair| pair.as_rule() == Rule::version)
.map(|pair| http_version_from_str(pair.as_str()))
Expand All @@ -98,6 +116,7 @@ impl<'i> From<Pair<'i, Rule>> for HttpRequest {
Self {
method,
url,
query,
version,
headers,
body,
Expand Down
1 change: 1 addition & 0 deletions rq-core/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type RequestResult = Result<Response, Box<dyn std::error::Error + Send + Sync>>;
pub async fn execute(req: &HttpRequest) -> RequestResult {
let request = CLIENT
.request(req.method.clone(), &req.url)
.query(&req.query)
.headers(req.headers())
.body(req.body.clone());

Expand Down

0 comments on commit 1914f6f

Please sign in to comment.