Host Header Added Twice
I was following the example in the project's readme (under esp-mbedtls heading):
... existing
let mut request = client
.request(reqwless::request::Method::GET, "https://www.google.com")
.await
.unwrap()
.content_type(reqwless::headers::ContentType::TextPlain)
.headers(&[("Host", "google.com")])
.send(&mut buffer)
.await
.unwrap();
However, I got a bunch of bad requests responses when trying to visit https://www.google.com as well as http://www.mobile-j.de.
Note I was setting the Host in the headers each time.
After debugging the request (by sending it to my localhost) I saw the host header was being added twice.
GET / HTTP/1.1
Host: 192.168.1.2
Content-Type: text/plain
Content-Length: 0
Host: api.telegram.org
user-agent: Mozilla/5.0 (X11; Linux x86_64; rv:135.0) Gecko/20100101 Firefox/135.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language: en-US,en;q=0.5
It looks like 192.168.1.2 was being added by reqwless by itself and the telegram host by explicit set of headers.
Thanks for the library!
Hi,
I can't make a PR, but the easiest way to solve it is by updating RequestBuilder: Old:
pub trait RequestBuilder<'req, B>
where
B: RequestBody,
{
type WithBody<T: RequestBody>: RequestBuilder<'req, T>;
/// Set optional headers on the request.
fn headers(self, headers: &'req [(&'req str, &'req str)]) -> Self;
/// Set the path of the HTTP request.
fn path(self, path: &'req str) -> Self;
/// Set the data to send in the HTTP request body.
fn body<T: RequestBody>(self, body: T) -> Self::WithBody<T>;
/// Set the host header.
fn host(self, host: &'req str) -> Self;
/// Set the content type header for the request.
fn content_type(self, content_type: ContentType) -> Self;
/// Set the accept header for the request.
fn accept(self, content_type: ContentType) -> Self;
/// Set the basic authentication header for the request.
fn basic_auth(self, username: &'req str, password: &'req str) -> Self;
/// Return an immutable request.
fn build(self) -> Request<'req, B>;
}
Update:
pub trait RequestBuilder<'req, B>
where
B: RequestBody,
{
type WithBody<T: RequestBody>: RequestBuilder<'req, T>;
/// Set optional headers on the request.
/// All headers which are NOT: Host, Content-Type, Content-Length
fn extra_headers(self, headers: &'req [(&'req str, &'req str)]) -> Self;
/// Set the path of the HTTP request.
fn path(self, path: &'req str) -> Self;
/// Set the data to send in the HTTP request body.
fn body<T: RequestBody>(self, body: T) -> Self::WithBody<T>;
/// Set the host header.
fn host(self, host: &'req str) -> Self;
/// Set the content type header for the request.
fn content_type(self, content_type: ContentType) -> Self;
/// Set the accept header for the request.
fn accept(self, content_type: ContentType) -> Self;
/// Set the basic authentication header for the request.
fn basic_auth(self, username: &'req str, password: &'req str) -> Self;
/// Return an immutable request.
fn build(self) -> Request<'req, B>;
}
Also update where the function is used.
To make it more clear the README should also be updated for the esp-mbedtls part to contain this as the example:
/// ... [initialization code. See esp-wifi]
let state = TcpClientState::<1, 4096, 4096>::new();
let mut tcp_client = TcpClient::new(stack, &state);
let dns_socket = DnsSocket::new(&stack);
let mut tls = Tls::new(peripherals.SHA)
.unwrap()
.with_hardware_rsa(peripherals.RSA);
let config = TlsConfig::new(
reqwless::TlsVersion::Tls1_3,
reqwless::Certificates {
ca_chain: reqwless::X509::pem(CERT.as_bytes()).ok(),
..Default::default()
},
tls.reference(),
);
let mut client = HttpClient::new_with_tls(&tcp_client, &dns_socket, config);
let mut request = client
.request(reqwless::request::Method::GET, "https://www.google.com")
.await
.unwrap()
.content_type(reqwless::headers::ContentType::TextPlain)
.send(&mut buffer)
.await
.unwrap();
I hope this helps :)