//! 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, 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::Event::RequestLine(uhttp::RequestLine { version: uhttp::Version::HTTP1_1, method: "POST", target: &path, }), uhttp::Event::Header(uhttp::Header::Special(uhttp::HeaderSpecial::ContentLength( data.len(), ))), 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 { buf.read_from(&mut stream)?; let data = buf.filled(); let (d, r) = conn.handle_recv(data).lift(); match r { Err(uhttp::Error { kind: uhttp::ErrorKind::NeedMoreData, .. }) => { 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(()) }