http_req
http_req copied to clipboard
async support
Are there any plans on adding async support? Let me know if a pull request in that direction would be welcome.
Yes, pull request in that direction would be welcome. But please try not to overuse dependencies, because it could make the library too heavy.
@jayjamesjay are you expecting something with mio more like this?
tmp-h9kdub v0.1.0 (/home/cecile/.cache/cargo-temp/tmp-h9KDuB)
├── http_req v0.8.1
│ ├── native-tls v0.2.8
│ │ ├── log v0.4.14
│ │ │ └── cfg-if v1.0.0
│ │ ├── openssl v0.10.36
│ │ │ ├── bitflags v1.3.2
│ │ │ ├── cfg-if v1.0.0
│ │ │ ├── foreign-types v0.3.2
│ │ │ │ └── foreign-types-shared v0.1.1
│ │ │ ├── libc v0.2.101
│ │ │ ├── once_cell v1.8.0
│ │ │ └── openssl-sys v0.9.66
│ │ │ └── libc v0.2.101
│ │ │ [build-dependencies]
│ │ │ ├── autocfg v1.0.1
│ │ │ ├── cc v1.0.70
│ │ │ └── pkg-config v0.3.19
│ │ ├── openssl-probe v0.1.4
│ │ └── openssl-sys v0.9.66 (*)
│ └── unicase v2.6.0
│ [build-dependencies]
│ └── version_check v0.9.3
└── mio v0.7.13
├── libc v0.2.101
└── log v0.4.14 (*)
POC (this code is flawed):
use std::error::Error;
use mio::net::{TcpListener, TcpStream};
use mio::{event, Events, Interest, Poll, Token};
use http_req::{request::RequestBuilder, response::StatusCode, tls, uri::Uri};
use std::convert::TryFrom;
use std::io::{Read, Write};
use std::net::{SocketAddr, ToSocketAddrs};
// Some tokens to allow us to identify which event is for which socket.
const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);
fn main() -> Result<(), Box<dyn Error>> {
let addr: Uri = Uri::try_from("http://example.org").unwrap();
let mut writer = Vec::new();
// Create a poll instance.
let mut poll = Poll::new()?;
// Create storage for events.
let mut events = Events::with_capacity(128);
// Setup the client socket.
let mut client = TcpStream::connect(
(addr.host().unwrap(), addr.corr_port())
.to_socket_addrs()
.unwrap()
.next()
.unwrap(),
)?;
/*
let mut tls = tls::Config::default()
.connect(addr.host().unwrap_or(""), &mut client)
.unwrap();
*/
// Register the socket.
poll.registry()
.register(&mut client, CLIENT, Interest::READABLE | Interest::WRITABLE)?;
let mut response = None;
// Start an event loop.
'main: loop {
// Poll Mio for events, blocking until we get an event.
poll.poll(&mut events, None)?;
// Process each event.
for event in events.iter() {
// We can use the token we previously provided to `register` to
// determine for which socket the event is.
match event.token() {
CLIENT => {
if event.is_writable() {
eprintln!("##### write");
match RequestBuilder::new(&addr)
.header("Connection", "Close")
.send(&mut client, &mut writer)
{
Err(err) => {
eprintln!("{:?}", err);
}
Ok(res) => {
response.replace(res);
let _ = std::io::stdout().write_all(&writer);
break 'main;
}
}
// We can (likely) write to the socket without blocking.
}
if event.is_readable() {
// We can (likely) read from the socket without blocking.
}
// Since the server just shuts down the connection, let's
// just exit from our event loop.
//return Ok(());
}
// We don't expect any events with tokens other than those we provided.
_ => unreachable!(),
}
}
}
if let Some(response) = response.as_ref() {
assert_eq!(response.status_code(), StatusCode::new(200));
}
Ok(())
}
Then use std::futures::Future to make this async.
Yes, something like this.