1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
use crate::{error::Error, resource::Resource}; use log::error; use std::io::{self, Read, Write}; use std::net::{Shutdown, TcpStream}; use url::Url; pub struct Http { stream: TcpStream, } impl Resource for Http { fn new(u: Url) -> Result<Http, Error> { if let None = u.host() { return Err(Error::InvalidArgument); } let host = u.host().unwrap(); let port: u16 = match u.port() { Some(port_num) => port_num, None => 80, }; TcpStream::connect((host.to_string().as_str(), port)) .or_else(|why| { error!( "connection error to {}:{}: {:?}", u.host().unwrap(), port, why ); Err(Error::Unknown) }) .and_then(|conn| Ok(Http { stream: conn })) } fn close(&mut self) { if let Err(why) = self.stream.shutdown(Shutdown::Both) { error!("error closing TCP stream: {:?}", why); } drop(&self.stream); } } impl Read for Http { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.stream.read(buf) } } impl Write for Http { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.stream.write(buf) } fn flush(&mut self) -> io::Result<()> { self.stream.shutdown(Shutdown::Write) } }