Skip to content

Commit

Permalink
# fix http headers, header could has same name key, but diff value.
Browse files Browse the repository at this point in the history
  • Loading branch information
tmtbe committed Dec 7, 2023
1 parent b5e2da0 commit e1da30b
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 18 deletions.
2 changes: 1 addition & 1 deletion ehttp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ pub mod streaming;
/// ..Request::get("https://www.example.com")
/// };
/// ```
pub fn headers(headers: &[(&str, &str)]) -> std::collections::BTreeMap<String, String> {
pub fn headers(headers: &[(&str, &str)]) -> Vec<(String, String)> {
headers
.iter()
.map(|e| (e.0.to_owned(), e.1.to_owned()))
Expand Down
8 changes: 3 additions & 5 deletions ehttp/src/native.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::collections::BTreeMap;

use crate::{Request, Response};

#[cfg(feature = "native-async")]
Expand Down Expand Up @@ -28,7 +26,7 @@ pub fn fetch_blocking(request: &Request) -> crate::Result<Response> {
let mut req = ureq::request(&request.method, &request.url);

for header in &request.headers {
req = req.set(header.0, header.1);
req = req.set(header.0.as_str(), header.1.as_str());
}

let resp = if request.body.is_empty() {
Expand All @@ -46,11 +44,11 @@ pub fn fetch_blocking(request: &Request) -> crate::Result<Response> {
let url = resp.get_url().to_owned();
let status = resp.status();
let status_text = resp.status_text().to_owned();
let mut headers = BTreeMap::new();
let mut headers = vec![];
for key in &resp.headers_names() {
if let Some(value) = resp.header(key) {
// lowercase for easy lookup
headers.insert(key.to_ascii_lowercase(), value.to_owned());
headers.push((key.to_ascii_lowercase(), value.to_owned()));
}
}

Expand Down
8 changes: 4 additions & 4 deletions ehttp/src/streaming/native.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::collections::BTreeMap;
use std::ops::ControlFlow;
use std::vec;

use crate::Request;

Expand All @@ -13,7 +13,7 @@ pub fn fetch_streaming_blocking(
let mut req = ureq::request(&request.method, &request.url);

for header in &request.headers {
req = req.set(header.0, header.1);
req = req.set(header.0.as_str(), header.1.as_str());
}

let resp = if request.body.is_empty() {
Expand All @@ -34,11 +34,11 @@ pub fn fetch_streaming_blocking(
let url = resp.get_url().to_owned();
let status = resp.status();
let status_text = resp.status_text().to_owned();
let mut headers = BTreeMap::new();
let mut headers = vec![];
for key in &resp.headers_names() {
if let Some(value) = resp.header(key) {
// lowercase for easy lookup
headers.insert(key.to_ascii_lowercase(), value.to_owned());
headers.push((key.to_ascii_lowercase(), value.to_owned()));
}
}

Expand Down
36 changes: 30 additions & 6 deletions ehttp/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::collections::BTreeMap;

/// A simple HTTP request.
#[derive(Clone, Debug)]
pub struct Request {
Expand All @@ -13,7 +11,7 @@ pub struct Request {
pub body: Vec<u8>,

/// ("Accept", "*/*"), …
pub headers: BTreeMap<String, String>,
pub headers: Vec<(String, String)>,
}

impl Request {
Expand All @@ -28,6 +26,20 @@ impl Request {
}
}

/// Get `Header` list from request with the given key.
pub fn get_header(&self, key: String) -> Vec<String> {
self.headers
.iter()
.filter(|h| h.0 == key)
.map(|h| h.1.clone())
.collect()
}

/// Add a `Header` for request.
pub fn add_header(&mut self, key: String, value: String) {
self.headers.push((key, value))
}

/// Create a `POST` request with the given url and body.
#[allow(clippy::needless_pass_by_value)]
pub fn post(url: impl ToString, body: Vec<u8>) -> Self {
Expand Down Expand Up @@ -59,7 +71,7 @@ pub struct Response {
pub status_text: String,

/// The returned headers. All header names are lower-case.
pub headers: BTreeMap<String, String>,
pub headers: Vec<(String, String)>,

/// The raw bytes of the response body.
pub bytes: Vec<u8>,
Expand All @@ -71,7 +83,19 @@ impl Response {
}

pub fn content_type(&self) -> Option<&str> {
self.headers.get("content-type").map(|s| s.as_str())
self.headers
.iter()
.find(|s| s.0 == "content-type")
.map(|s| s.1.as_str())
}

/// Get `Header` list from response with the given key.
pub fn get_header(&self, key: String) -> Vec<String> {
self.headers
.iter()
.filter(|h| h.0 == key)
.map(|h| h.1.clone())
.collect()
}
}

Expand Down Expand Up @@ -104,7 +128,7 @@ pub struct PartialResponse {
pub status_text: String,

/// The returned headers. All header names are lower-case.
pub headers: BTreeMap<String, String>,
pub headers: Vec<(String, String)>,
}

impl PartialResponse {
Expand Down
4 changes: 2 additions & 2 deletions example_eframe/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,8 @@ fn response_ui(ui: &mut egui::Ui, response: &ehttp::Response) {
.spacing(egui::vec2(ui.spacing().item_spacing.x * 2.0, 0.0))
.show(ui, |ui| {
for header in &response.headers {
ui.label(header.0);
ui.label(header.1);
ui.label(header.0.clone());
ui.label(header.1.clone());
ui.end_row();
}
})
Expand Down

0 comments on commit e1da30b

Please sign in to comment.