extern crate mio; extern crate mio_httpc; use mio::{Events, Poll}; use mio_httpc::{CallBuilder, Httpc, RecvState, SendState}; fn main() { let mut poll = Poll::new().unwrap(); let mut htp = Httpc::new(10, None); let mut args: Vec = ::std::env::args().collect(); if args.len() == 1 { args.push("https://www.reddit.com".to_string()); } let mut call = CallBuilder::get() .url(args[1].as_str()) .expect("Invalid url") .call(&mut htp, poll.registry()) .expect("Call start failed"); let mut sending = true; let mut done = false; let mut recv_vec = Vec::new(); while !done { let mut events = Events::with_capacity(8); poll.poll(&mut events, None).unwrap(); for ev in events.iter() { // println!("ev {}",ev.token().0); let cid = htp.event(&ev).expect("Event not from http request"); assert!(call.is_ref(cid)); if sending { // None because we are not sending any body match htp.call_send(poll.registry(), &mut call, None) { SendState::Done => { panic!("Done while sending"); } SendState::Error(e) => { panic!("Failed while sending {}", e); } SendState::Wait => {} SendState::Receiving => { println!("Switching to receiving!"); sending = false; } _ => {} } } // no else here because when it switches to receiving you should call call_recv immediately if !sending { // Loop until receiving RecvState::Wait or an error. // This is so socket is always drained entirely. Otherwise poll will not return // anything. Httpc uses edge triggered sockets. loop { match htp.call_recv(poll.registry(), &mut call, Some(&mut recv_vec)) { RecvState::Done => { println!("Done"); done = true; break; } RecvState::Response(resp, bsz) => { println!("Got response {}\nbody_sz={}", resp.status, bsz); for h in resp.headers() { println!("Header={}", h); } if bsz.is_empty() { println!("Finish as content-length is 0"); done = true; break; } // recv_vec.reserve(bsz); } RecvState::ReceivedBody(sz) => { println!("Got chunk {} bytes", sz); } // If no Vec provied to call_recv the final body is returned with this. RecvState::DoneWithBody(rt) => { if let Ok(s) = String::from_utf8(rt) { println!("Body: {}", s); } panic!("We provided vec, should not get body as well!"); } RecvState::Error(e) => { panic!("Get failed {}", e); } RecvState::Sending => { println!("Switch to sending, must be redirect!"); sending = true; break; } RecvState::Wait => { break; } } } } } } if let Ok(s) = String::from_utf8(recv_vec) { println!("Body: {}", s); } }