~julienxx/castor

64ae298982ee94d20ba47adf2b81f402dfceb456 — Julien Blanchard a month ago 0e04540 0.8.7
Prefer IPV4 addresses when choice is available
6 files changed, 88 insertions(+), 71 deletions(-)

M Cargo.lock
M Cargo.toml
M src/finger/client.rs
M src/gemini/client.rs
M src/gopher/client.rs
M src/gopher/parser.rs
M Cargo.lock => Cargo.lock +1 -1
@@ 112,7 112,7 @@ dependencies = [

[[package]]
name = "castor"
version = "0.8.6"
version = "0.8.7"
dependencies = [
 "ansi-parser",
 "dirs",

M Cargo.toml => Cargo.toml +1 -1
@@ 1,6 1,6 @@
[package]
name = "castor"
version = "0.8.6"
version = "0.8.7"
authors = ["Julien Blanchard <julien@typed-hole.org>"]
edition = "2018"


M src/finger/client.rs => src/finger/client.rs +32 -24
@@ 1,6 1,5 @@
use std::io::{Read, Write};
use std::net::TcpStream;
use std::net::ToSocketAddrs;
use std::net::{SocketAddr::V4, SocketAddr::V6, TcpStream, ToSocketAddrs};
use std::thread;
use std::time::Duration;



@@ 10,31 9,40 @@ pub fn get_data<T: Protocol>(url: T) -> Result<(Option<Vec<u8>>, Vec<u8>), Strin
    let url = url.get_source_url();
    let host = url.host_str().unwrap().to_string();
    let urlf = format!("{}:79", host);
    let socket = match urlf.to_socket_addrs() {
        Ok(iter) => iter.rev().next(),
        Err(_) => None,
    };

    match socket {
        Some(socket) => match TcpStream::connect_timeout(&socket, Duration::new(5, 0)) {
            Ok(mut stream) => thread::spawn(move || {
                let username = if url.username() == "" {
                    url.path().replace("/", "")
                } else {
                    String::from(url.username())
    match urlf.to_socket_addrs() {
        Ok(mut addrs_iter) => match addrs_iter.next() {
            Some(socket_addr) => {
                let socket_addr = match socket_addr {
                    V4(ip) => V4(ip),
                    V6(ip) => match addrs_iter.next() {
                        Some(addr) => addr,
                        None => V6(ip),
                    },
                };

                let request = format!("{}\r\n", username);
                stream.write_all(request.as_bytes()).unwrap();
                let mut res = vec![];
                stream.read_to_end(&mut res).unwrap();
                match TcpStream::connect_timeout(&socket_addr, Duration::new(5, 0)) {
                    Ok(mut stream) => thread::spawn(move || {
                        let username = if url.username() == "" {
                            url.path().replace("/", "")
                        } else {
                            String::from(url.username())
                        };

                Ok((None, res))
            })
            .join()
            .unwrap(),
            Err(e) => Err(format!("Could not connect to {}\n{}", urlf, e)),
        },
        None => Err(format!("Could not connect to {}\n", urlf)),
                        let request = format!("{}\r\n", username);
                        stream.write_all(request.as_bytes()).unwrap();
                        let mut res = vec![];
                        stream.read_to_end(&mut res).unwrap();

                        Ok((None, res))
                    })
                        .join()
                        .unwrap(),
                    Err(e) => Err(format!("Could not connect to {}\n{}", urlf, e)),
                }
            }
            None => Err(format!("Could not connect to {}\n", urlf)),
        }
        Err(e) => Err(format!("Could not connect to {}\n{}", urlf, e)),
    }
}

M src/gemini/client.rs => src/gemini/client.rs +10 -2
@@ 1,6 1,6 @@
use native_tls::TlsConnector;
use std::io::{Read, Write};
use std::net::{TcpStream, ToSocketAddrs};
use std::net::{SocketAddr::V4, SocketAddr::V6, TcpStream, ToSocketAddrs};
use std::thread;
use std::time::Duration;



@@ 24,8 24,16 @@ pub fn get_data<T: Protocol>(url: T) -> Result<(Option<Vec<u8>>, Vec<u8>), Strin
    let connector = builder.build().unwrap();

    match urlf.to_socket_addrs() {
        Ok(addrs_iter) => match addrs_iter.rev().next() {
        Ok(mut addrs_iter) => match addrs_iter.next() {
            Some(socket_addr) => {
                let socket_addr = match socket_addr {
                    V4(ip) => V4(ip),
                    V6(ip) => match addrs_iter.next() {
                        Some(addr) => addr,
                        None => V6(ip)
                    }
                };

                let stream = TcpStream::connect_timeout(&socket_addr, Duration::new(5, 0));

                match stream {

M src/gopher/client.rs => src/gopher/client.rs +43 -36
@@ 1,7 1,6 @@
use percent_encoding::percent_decode;
use std::io::{Read, Write};
use std::net::TcpStream;
use std::net::ToSocketAddrs;
use std::net::{SocketAddr::V4, SocketAddr::V6, TcpStream, ToSocketAddrs};
use std::thread;
use std::time::Duration;



@@ 16,46 15,54 @@ pub fn get_data<T: Protocol>(url: T) -> Result<(Option<Vec<u8>>, Vec<u8>), Strin
    };
    let urlf = format!("{}:{}", host, port);

    let socket = match urlf.to_socket_addrs() {
        Ok(iter) => iter.rev().next(),
        Err(_) => None,
    };
    match urlf.to_socket_addrs() {
        Ok(mut addrs_iter) => match addrs_iter.next() {
            Some(socket_addr) => {
                let socket_addr = match socket_addr {
                    V4(ip) => V4(ip),
                    V6(ip) => match addrs_iter.next() {
                        Some(addr) => addr,
                        None => V6(ip),
                    },
                };

    match socket {
        Some(socket) => match TcpStream::connect_timeout(&socket, Duration::new(5, 0)) {
            Ok(mut stream) => thread::spawn(move || {
                let path = url.path().to_string();
                match TcpStream::connect_timeout(&socket_addr, Duration::new(5, 0)) {
                    Ok(mut stream) => thread::spawn(move || {
                        let path = url.path().to_string();

                let mut url = match url.query() {
                    Some(query) => format!("{}?{}\r\n", path, query),
                    None => format!("{}\r\n", path),
                };
                        let mut url = match url.query() {
                            Some(query) => format!("{}?{}\r\n", path, query),
                            None => format!("{}\r\n", path),
                        };

                let url = if url.starts_with("/0")
                    || url.starts_with("/1")
                    || url.starts_with("/g")
                    || url.starts_with("/I")
                    || url.starts_with("/9")
                {
                    url.split_off(2)
                } else if url == "/\n" {
                    String::from("\r\n")
                } else {
                    url
                };
                        let url = if url.starts_with("/0")
                            || url.starts_with("/1")
                            || url.starts_with("/g")
                            || url.starts_with("/I")
                            || url.starts_with("/9")
                        {
                            url.split_off(2)
                        } else if url == "/\n" {
                            String::from("\r\n")
                        } else {
                            url
                        };

                let url = percent_decode(url.as_bytes()).decode_utf8().unwrap();
                        let url = percent_decode(url.as_bytes()).decode_utf8().unwrap();

                stream.write_all(url.as_bytes()).unwrap();
                let mut res = vec![];
                stream.read_to_end(&mut res).unwrap();
                        stream.write_all(url.as_bytes()).unwrap();
                        let mut res = vec![];
                        stream.read_to_end(&mut res).unwrap();

                Ok((None, res))
            })
            .join()
            .unwrap(),
            Err(e) => Err(format!("Could not connect to {}\n{}", urlf, e)),
                        Ok((None, res))
                    })
                    .join()
                    .unwrap(),
                    Err(e) => Err(format!("Could not connect to {}\n{}", urlf, e)),
                }
            }
            None => Err(format!("Could not connect to {}\n", urlf)),
        },
        None => Err(format!("Could not connect to {}\n", urlf)),
        Err(e) => Err(format!("Could not connect to {}\n{}", urlf, e)),
    }
}

M src/gopher/parser.rs => src/gopher/parser.rs +1 -7
@@ 42,13 42,7 @@ impl FromStr for TextElement {
            // Text line
            if line.contains("gopher://") {
                Ok(TextElement::LinkItem(String::from(line)))
            } else if line.contains("http://") || line.contains("https://") {
                Ok(TextElement::ExternalLinkItem(String::from(line)))
            } else if line.contains("gemini://") {
                Ok(TextElement::ExternalLinkItem(String::from(line)))
            } else if line.contains("ftp://") {
                Ok(TextElement::ExternalLinkItem(String::from(line)))
            } else if line.contains("finger://") {
            } else if line.contains("http://") || line.contains("https://") || line.contains("gemini://") || line.contains("finger://") || line.contains("ftp://") {
                Ok(TextElement::ExternalLinkItem(String::from(line)))
            } else {
                Ok(TextElement::Text(colors::colorize(line)))