track which pages are loaded via tls

pull/14/head
dvkt 4 years ago
parent 7148ddd999
commit 9128ffc85b

@ -17,6 +17,13 @@ impl<T: Read + Write> ReadWrite for T {}
/// Wrapper for TLS and regular TCP streams.
pub struct Stream {
io: Box<dyn ReadWrite>,
tls: bool,
}
impl Stream {
fn is_tls(&self) -> bool {
self.tls
}
}
impl Read for Stream {
@ -40,23 +47,25 @@ impl Write for Stream {
pub const TCP_TIMEOUT_IN_SECS: u64 = 8;
pub const TCP_TIMEOUT_DURATION: Duration = Duration::from_secs(TCP_TIMEOUT_IN_SECS);
/// Fetches a gopher URL and returns a raw Gopher response.
pub fn fetch_url(url: &str, try_tls: bool) -> Result<String> {
/// Fetches a gopher URL and returns a tuple of:
/// (did tls work?, raw Gopher response)
pub fn fetch_url(url: &str, try_tls: bool) -> Result<(bool, String)> {
let (_, host, port, sel) = parse_url(url);
fetch(host, port, sel, try_tls)
}
/// Fetches a gopher URL by its component parts and returns a raw
/// Gopher response.
pub fn fetch(host: &str, port: &str, selector: &str, try_tls: bool) -> Result<String> {
/// Fetches a gopher URL by its component parts and returns a tuple of:
/// (did tls work?, raw Gopher response)
pub fn fetch(host: &str, port: &str, selector: &str, try_tls: bool) -> Result<(bool, String)> {
let mut stream = request(host, port, selector, try_tls)?;
let mut body = String::new();
stream.read_to_string(&mut body)?;
Ok(body)
Ok((stream.is_tls(), body))
}
/// Downloads a binary to disk. Allows canceling with Ctrl-c.
/// Returns the path it was saved to and the size in bytes.
/// Returns a tuple of:
/// (path it was saved to, the size in bytes)
pub fn download_url(url: &str, try_tls: bool) -> Result<(String, usize)> {
let (_, host, port, sel) = parse_url(url);
let filename = sel
@ -110,6 +119,7 @@ pub fn request(host: &str, port: &str, selector: &str, try_tls: bool) -> Result<
stream.write(format!("{}\r\n", selector).as_ref())?;
return Ok(Stream {
io: Box::new(stream),
tls: true,
});
}
}
@ -119,6 +129,7 @@ pub fn request(host: &str, port: &str, selector: &str, try_tls: bool) -> Result<
stream.write(format!("{}\r\n", selector).as_ref())?;
Ok(Stream {
io: Box::new(stream),
tls: false,
})
}

@ -77,7 +77,7 @@ Once you've launched phetch, use `ctrl-h` to view the on-line help."
fn print_raw(url: &str, try_tls: bool) {
match gopher::fetch_url(url, try_tls) {
Ok(response) => println!("{}", response),
Ok((_, response)) => println!("{}", response),
Err(e) => {
eprintln!("{}", e);
exit(0)

@ -13,6 +13,7 @@ pub struct Menu {
pub link: usize, // selected link
pub scroll: usize, // scrolling offset
pub searching: bool, // search mode?
pub tls: bool, // retrieved via tls?
pub size: (usize, usize), // cols, rows
pub wide: bool, // in wide mode?
}
@ -39,6 +40,10 @@ impl fmt::Display for Menu {
}
impl View for Menu {
fn is_tls(&self) -> bool {
self.tls
}
fn raw(&self) -> String {
self.raw.to_string()
}
@ -61,8 +66,10 @@ impl View for Menu {
}
impl Menu {
pub fn from(url: String, response: String) -> Menu {
Self::parse(url, response)
pub fn from(url: String, response: String, tls: bool) -> Menu {
let mut menu = Self::parse(url, response);
menu.tls = tls;
menu
}
fn cols(&self) -> usize {
@ -788,6 +795,7 @@ impl Menu {
scroll: 0,
searching: false,
size: (0, 0),
tls: false,
wide: false,
}
}

@ -9,6 +9,7 @@ pub struct Text {
lines: usize, // # of lines
longest: usize, // longest line
size: (usize, usize), // cols, rows
pub tls: bool, // retrieved via tls?
pub wide: bool, // in wide mode? turns off margins
}
@ -19,6 +20,10 @@ impl fmt::Display for Text {
}
impl View for Text {
fn is_tls(&self) -> bool {
self.tls
}
fn url(&self) -> String {
self.url.to_string()
}
@ -129,7 +134,7 @@ impl View for Text {
}
impl Text {
pub fn from(url: String, response: String) -> Text {
pub fn from(url: String, response: String, tls: bool) -> Text {
let mut lines = 0;
let mut longest = 0;
for line in response.split_terminator('\n') {
@ -146,6 +151,7 @@ impl Text {
lines,
longest,
size: (0, 0),
tls,
wide: false,
}
}

@ -171,15 +171,15 @@ impl UI {
let thread_url = url.to_string();
let try_tls = self.tls;
// don't spin on first ever request
let res = if self.views.is_empty() {
let (tls, res) = if self.views.is_empty() {
gopher::fetch_url(&thread_url, try_tls)?
} else {
self.spinner("", move || gopher::fetch_url(&thread_url, try_tls))??
};
let (typ, _, _, _) = gopher::parse_url(&url);
match typ {
Type::Menu | Type::Search => Ok(Box::new(Menu::from(url.to_string(), res))),
Type::Text | Type::HTML => Ok(Box::new(Text::from(url.to_string(), res))),
Type::Menu | Type::Search => Ok(Box::new(Menu::from(url.to_string(), res, tls))),
Type::Text | Type::HTML => Ok(Box::new(Text::from(url.to_string(), res, tls))),
_ => Err(error!("Unsupported Gopher Response: {:?}", typ)),
}
}
@ -190,7 +190,7 @@ impl UI {
&url.trim_start_matches("gopher://phetch/")
.trim_start_matches("1/"),
) {
Ok(Box::new(Menu::from(url.to_string(), source)))
Ok(Box::new(Menu::from(url.to_string(), source, false)))
} else {
Err(error!("phetch URL not found: {}", url))
}
@ -467,7 +467,7 @@ impl UI {
if let Some(page) = self.views.get(self.focused) {
let url = page.url();
let raw = page.raw();
let mut text = Text::from(url, raw);
let mut text = Text::from(url, raw, page.is_tls());
text.wide = true;
self.add_page(Box::new(text));
}

@ -4,6 +4,7 @@ use std::fmt;
pub trait View: fmt::Display {
fn respond(&mut self, key: ui::Key) -> ui::Action;
fn render(&self) -> String;
fn is_tls(&self) -> bool;
fn url(&self) -> String;
fn raw(&self) -> String;
fn term_size(&mut self, cols: usize, rows: usize);

Loading…
Cancel
Save