//! A simple client that POSTs some data to a path //! //! Usage: //! cargo run --example client -- use std::{error::Error, io::Write, net::TcpStream}; use httplz::Lift; pub fn main() -> Result<(), Box> { let mut args = std::env::args().skip(1); let (host, port, path, data) = args .next() .and_then(|h| Some((h, args.next()?, args.next()?, args.next()?))) .ok_or_else(|| Box::::from(String::from("Missing required argument")))?; let mut stream = TcpStream::connect((host.as_str(), port.parse()?))?; let buf = vec![0; 4096]; let mut buf = httplz_ext::Buf::new(buf); let mut conn = httplz::Connection::new(httplz::Role::Client); let events = &[ httplz::RequestLine { version: httplz::Version::HTTP1_1, method: "POST", target: &path, } .into(), httplz::HeaderOther::from(("Host", host.as_bytes())).into(), httplz::HeaderOther::from(("Accept", "*/*")).into(), httplz::HeaderSpecial::ContentLength(data.len()).into(), httplz::Event::HeadersDone, httplz::Event::BodyChunk(data.as_bytes()), httplz::Event::SendDone, ]; for event in events { if let Err(e) = conn.handle_send(event, &mut buf) { panic!("{e:?}"); }; } stream.write_all(buf.filled())?; buf.clear(); loop { let data = buf.filled(); let (d, r) = conn.handle_recv(data).lift(); match r { Err(httplz::Error { kind: httplz::ErrorKind::NeedMoreData, .. }) => { buf.read_from(&mut stream)?; continue; }, Err(e) => panic!("{e:?}"), Ok(ev) => { println!("{ev}"); if ev == httplz::Event::RecvDone { break; } }, }; let len = buf.filled().len() - d.len(); buf.pop_front(len); } Ok(()) }