//! A simple client that POSTs some data to a path //! //! Usage: //! cargo run --example client -- use std::{error::Error, io::Write, net::TcpStream}; use uhttp::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 = uhttp_ext::Buf::new(buf); let mut conn = uhttp::Connection::new(uhttp::Role::Client); let events = &[ uhttp::RequestLine { version: uhttp::Version::HTTP1_1, method: "POST", target: &path, } .into(), uhttp::HeaderOther::from(("Host", host.as_bytes())).into(), uhttp::HeaderOther::from(("Accept", "*/*")).into(), uhttp::HeaderSpecial::ContentLength(data.len()).into(), uhttp::Event::HeadersDone, uhttp::Event::BodyChunk(data.as_bytes()), uhttp::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(uhttp::Error { kind: uhttp::ErrorKind::NeedMoreData, .. }) => { buf.read_from(&mut stream)?; continue; }, Err(e) => panic!("{e:?}"), Ok(ev) => { println!("{ev}"); if ev == uhttp::Event::RecvDone { break; } }, }; let len = buf.filled().len() - d.len(); buf.pop_front(len); } Ok(()) }