1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
pub use header::Header;
pub use header::parse_to_surf_header;
#[allow(warnings)]
pub mod header {
use std::collections::BTreeMap;
use surf::{http::headers::HeaderName, Request};
#[derive(Debug, Clone, Default)]
pub struct HeaderInfo {
pub method: String,
pub url: String,
pub headers: BTreeMap<Box<str>, Box<str>>,
}
impl HeaderInfo {
fn new(method: String, url: String, headers: BTreeMap<Box<str>, Box<str>>) -> Self {
Self {
method,
url,
headers,
}
}
}
/// ## parse_to_surf_header
///```rust
/// #[tokio::main]
///async fn main() {
/// use std::collections::BTreeMap;
/// use surf_header::Header;
/// use surf_header::parse_to_surf_header;
/// let h = r##"
/// GET / HTTP/1.1
/// Host: crates.io
/// Upgrade-Insecure-Requests: 1
/// User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.119 Safari/537.36
/// Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
/// Referer: https://crates.io/
/// Accept-Encoding: gzip, deflate
/// Accept-Language: en-US,en;q=0.9
/// Connection: close
/// "##;
/// let info = parse_to_surf_header(h).unwrap();
/// let mut req = surf::get(info.url).build();
/// req.headers(info.headers);
/// let client = surf::Client::new();
/// let mut res = client.send(req).await.unwrap();
/// println!("{:?}",res.body_string().await.unwrap());
///}
///```
pub fn parse_to_surf_header(header: &str) -> Result<HeaderInfo, Box<dyn std::error::Error>> {
macro_rules! split_to_vec {
($a:expr,$b:expr) => {
$a.to_string()
.split($b)
.filter(|s| !s.is_empty())
.map(|s| s.to_string().trim().to_owned())
.collect::<Vec<String>>()
};
}
let methods = split_to_vec!(header, "\n")
.first()
.expect("get method error")
.to_string()
.to_owned();
let method_vec = split_to_vec!(methods, " ");
let method = method_vec.clone().into_iter().nth(0).unwrap();
let header_vec = split_to_vec!(header, "\n")
.into_iter()
.skip(1)
.filter(|s| !s.is_empty())
.map(|s| split_to_vec!(s.to_string().trim().to_owned(), ": "))
.collect::<Vec<Vec<String>>>();
let mut header: BTreeMap<Box<str>, Box<str>> = BTreeMap::new();
for h in header_vec.clone().into_iter() {
let k = h.clone().into_iter().nth(0).unwrap();
let v = h.clone().into_iter().nth(1).unwrap();
header.insert(Box::from(k), Box::from(v));
}
let host = header_vec
.clone()
.into_iter()
.filter(|s| s.get(0).unwrap().to_string() == "Host".to_string())
.map(|s| s.get(1).unwrap().to_string())
.into_iter()
.nth(0)
.unwrap()
.to_string();
let forword_path = method_vec.get(1).unwrap().to_string();
let url = format!("https://{}{}", host, forword_path);
Ok(HeaderInfo::new(method, url, header))
}
pub trait Header {
/// ## parse_to_surf_header
///```rust
/// #[tokio::main]
///async fn main() {
/// use std::collections::BTreeMap;
/// use surf_header::Header;
/// use surf_header::parse_to_surf_header;
/// let h = r##"
/// GET / HTTP/1.1
/// Host: crates.io
/// Upgrade-Insecure-Requests: 1
/// User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.119 Safari/537.36
/// Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
/// Referer: https://crates.io/
/// Accept-Encoding: gzip, deflate
/// Accept-Language: en-US,en;q=0.9
/// Connection: close
/// "##;
/// let info = parse_to_surf_header(h).unwrap();
/// let mut req = surf::get(info.url).build();
/// req.headers(info.headers);
/// let client = surf::Client::new();
/// let mut res = client.send(req).await.unwrap();
/// println!("{:?}",res.body_string().await.unwrap());
///}
///```
fn headers(&mut self, headers: BTreeMap<Box<str>, Box<str>>);
}
impl Header for Request {
fn headers(&mut self, headers: BTreeMap<Box<str>, Box<str>>) {
for (k, v) in headers.iter() {
self.insert_header(
HeaderName::from_string(k.to_string()).unwrap(),
&v.to_string(),
);
}
}
}
}