-- Leo's gemini proxy

-- Connecting to typed-hole.org:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

commit 915c1ee7b42c1d6fdf570632b2a49b7587803203

Author: Julien Blanchard <julien@sideburns.eu>

Date: Tue Jul 9 15:09:50 2019 +0200


Follow links


diff --git a/Cargo.lock b/Cargo.lock

index 680f63c..7adc517 100644

--- a/Cargo.lock

+++ b/Cargo.lock

@@ -1,6 +1,14 @@

This file is automatically @generated by Cargo.

It is not intended for manual editing.

[[package]]

+name = "aho-corasick"

+version = "0.7.4"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+dependencies = [

+ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",

+]

+

+[[package]]

name = "arc-swap"

version = "0.3.11"

source = "registry+https://github.com/rust-lang/crates.io-index"

@@ -16,6 +24,8 @@ version = "0.1.0"

dependencies = [

"cursive 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",

"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",

+ "regex 1.1.9 (registry+https://github.com/rust-lang/crates.io-index)",

+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",

]


[[package]]

@@ -228,6 +238,16 @@ version = "1.0.1"

source = "registry+https://github.com/rust-lang/crates.io-index"


[[package]]

+name = "idna"

+version = "0.1.5"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+dependencies = [

+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",

+ "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",

+ "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",

+]

+

+[[package]]

name = "kernel32-sys"

version = "0.2.2"

source = "registry+https://github.com/rust-lang/crates.io-index"

@@ -260,6 +280,16 @@ version = "1.0.1"

source = "registry+https://github.com/rust-lang/crates.io-index"


[[package]]

+name = "matches"

+version = "0.1.8"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+

+[[package]]

+name = "memchr"

+version = "2.2.1"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+

+[[package]]

name = "native-tls"

version = "0.2.3"

source = "registry+https://github.com/rust-lang/crates.io-index"

@@ -383,6 +413,11 @@ dependencies = [

]


[[package]]

+name = "percent-encoding"

+version = "1.0.1"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+

+[[package]]

name = "pkg-config"

version = "0.3.14"

source = "registry+https://github.com/rust-lang/crates.io-index"

@@ -513,6 +548,26 @@ version = "0.1.54"

source = "registry+https://github.com/rust-lang/crates.io-index"


[[package]]

+name = "regex"

+version = "1.1.9"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+dependencies = [

+ "aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",

+ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",

+ "regex-syntax 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",

+ "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",

+ "utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",

+]

+

+[[package]]

+name = "regex-syntax"

+version = "0.6.8"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+dependencies = [

+ "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",

+]

+

+[[package]]

name = "remove_dir_all"

version = "0.5.2"

source = "registry+https://github.com/rust-lang/crates.io-index"

@@ -630,6 +685,14 @@ dependencies = [

]


[[package]]

+name = "thread_local"

+version = "0.3.6"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+dependencies = [

+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",

+]

+

+[[package]]

name = "time"

version = "0.1.42"

source = "registry+https://github.com/rust-lang/crates.io-index"

@@ -648,6 +711,27 @@ dependencies = [

]


[[package]]

+name = "ucd-util"

+version = "0.1.3"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+

+[[package]]

+name = "unicode-bidi"

+version = "0.3.4"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+dependencies = [

+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",

+]

+

+[[package]]

+name = "unicode-normalization"

+version = "0.1.8"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+dependencies = [

+ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",

+]

+

+[[package]]

name = "unicode-segmentation"

version = "1.3.0"

source = "registry+https://github.com/rust-lang/crates.io-index"

@@ -663,6 +747,21 @@ version = "0.1.0"

source = "registry+https://github.com/rust-lang/crates.io-index"


[[package]]

+name = "url"

+version = "1.7.2"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+dependencies = [

+ "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",

+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",

+ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",

+]

+

+[[package]]

+name = "utf8-ranges"

+version = "1.0.3"

+source = "registry+https://github.com/rust-lang/crates.io-index"

+

+[[package]]

name = "vcpkg"

version = "0.2.6"

source = "registry+https://github.com/rust-lang/crates.io-index"

@@ -702,6 +801,7 @@ version = "0.1.0"

source = "registry+https://github.com/rust-lang/crates.io-index"


[metadata]

+"checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282"

"checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841"

"checksum array-macro 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4ff37a25fb442a1fecfd399be0dde685558bca30fb998420532889a36852d2"

"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf"

@@ -729,11 +829,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"

"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"

"checksum hashbrown 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "29fba9abe4742d586dfd0c06ae4f7e73a1c2d86b856933509b269d82cdf06e18"

"checksum ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"

+"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"

"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"

"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"

"checksum libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319"

"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"

"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"

+"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"

+"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"

"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"

"checksum ncurses 5.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15699bee2f37e9f8828c7b35b2bc70d13846db453f2d507713b758fabe536b82"

"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db"

@@ -746,6 +849,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"

"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"

"checksum openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)" = "75bdd6dbbb4958d38e47a1d2348847ad1eb4dc205dc5d37473ae504391865acc"

"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"

+"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"

"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"

"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"

"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"

@@ -761,6 +865,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"

"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"

"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"

"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252"

+"checksum regex 1.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d9d8297cc20bbb6184f8b45ff61c8ee6a9ac56c156cec8e38c3e5084773c44ad"

+"checksum regex-syntax 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9b01330cce219c1c6b2e209e5ed64ccd587ae5c67bed91c0b49eecf02ae40e21"

"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"

"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339"

"checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2"

@@ -775,11 +881,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"

"checksum syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)" = "37ea458a750f59ab679b47fef9b6722c586c5742f4cfe18a120bbc807e5e01fd"

"checksum tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dc4738f2e68ed2855de5ac9cdbe05c9216773ecde4739b2f095002ab03a13ef"

"checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327"

+"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"

"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"

"checksum toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039"

+"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"

+"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"

+"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426"

"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9"

"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"

"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"

+"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"

+"checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde"

"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"

"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"

"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"

diff --git a/Cargo.toml b/Cargo.toml

index 20b4c7d..eaa6704 100644

--- a/Cargo.toml

+++ b/Cargo.toml

@@ -6,4 +6,6 @@ edition = "2018"


[dependencies]

cursive = "0.12"

-native-tls = "0.2"

\ No newline at end of file

+native-tls = "0.2"

+url = "*"

+regex = "*"

\ No newline at end of file

diff --git a/src/main.rs b/src/main.rs

index d45f12c..591ec83 100644

--- a/src/main.rs

+++ b/src/main.rs

@@ -1,25 +1,53 @@

use cursive::traits::*;

use cursive::align::HAlign;

use cursive::view::Scrollable;

-use cursive::views::{Dialog, Panel, TextView, EditView};

+use cursive::views::{Dialog, Panel, TextView, EditView, SelectView};

use cursive::Cursive;


extern crate native_tls;

+extern crate regex;


use native_tls::TlsConnector;

+use regex::Regex;

+

use std::net::TcpStream;

use std::io::{Read, Write};


-fn main() {

- let info = "

+use std::env;

+use std::fs::File;

+use std::fs::OpenOptions;

+use std::str;

+use std::str::FromStr;

+use url::Url;

+

+struct Status {

+ code: i8,

+ meta: String

+}

+

+impl FromStr for Status {

+ type Err = std::string::ParseError;

+

+ // Parses a string into an instance of 'Status'

+ fn from_str(status_line: &str) -> Result<Self, Self::Err> {

+ let mut splits = status_line.split("\t");

+ let code: i8 = splits.nth(1).unwrap().parse().unwrap();

+ let meta: String = String::from(splits.nth(2).unwrap());

+

+ Ok(Status { code, meta })

+ }

+}

+

+const HELP: &'static str = "

Press g to visit an URL

Press q to exit

";


+fn main() {

let mut siv = Cursive::default();


siv.add_fullscreen_layer(

- Dialog::around(Panel::new(TextView::new(info).with_id("content").scrollable().full_screen()))

+ Dialog::around(Panel::new(TextView::new(HELP).with_id("content").scrollable().full_screen()))

.title("Asuka Browser")

// This is the alignment for the button

.h_align(HAlign::Center)

@@ -27,9 +55,9 @@ Press q to exit

);


// Show a welcome popup

- siv.add_layer(Dialog::info(

- "Welcome to Asuka, the first ncurses Gemini browser!\n",

- ));

+ // siv.add_layer(Dialog::info(

+ // "Welcome to Asuka, the first ncurses Gemini browser!\n",

+ // ));


// We can quit by pressing q

siv.add_global_callback('q', |s| s.quit());

@@ -49,51 +77,114 @@ fn prompt_for_url(s: &mut Cursive) {

EditView::new()

.on_submit(visit_url)

.with_id("url_field")

- .fixed_width(20),

+ .fixed_width(20)

));

}


fn visit_url(s: &mut Cursive, url: &str) {

- let mut main_view = s.find_id::<TextView>("content").unwrap();

s.pop_layer();


- let cleaned_url = str::replace(url, "gemini://", "");

-

- match get_data(&cleaned_url) {

+ match get_data(&url) {

Ok(new_content) => {

- main_view.set_content(new_content);

- s.focus_id("content").unwrap();

+ let mut select = SelectView::new()

+ .h_align(HAlign::Left)

+ .autojump();

+

+ s.add_layer(Dialog::info(url));

+

+ select.add_all_str(new_content.lines());

+ select.set_on_submit(follow_link);

+

+ s.add_layer(

+ Dialog::around(select.scrollable().full_screen()).title(url),

+ );

},

Err(msg) => {

- // Show the error in a popup

s.add_layer(Dialog::info(msg));

}

}

+}


+fn follow_link(s: &mut Cursive, line: &str) {

+ let text = format!("{}", line);

+ let re1 = Regex::new(r"^\[(.*)\|(.*)\]$").unwrap(); // `[Foo|link]` links

+ let re2 = Regex::new(r"^=>\s(\S*)\s(\w*)$").unwrap(); // `=> link Foo` links

+

+ if re1.is_match(&text) {

+ let caps = re1.captures(&text).unwrap();

+ s.pop_layer();

+ let url = caps.get(2).map_or("", |m| m.as_str());

+ let next_url = match url.chars().next() {

+ Some('/') => format!("{}{}", get_last_url(), url),

+ Some(_) => url.to_owned(),

+ None => url.to_owned()

+ };

+ visit_url(s, &next_url)

+ } else if re2.is_match(&text) {

+ let caps = re2.captures(&text).unwrap();

+ s.pop_layer();

+ let url = caps.get(1).map_or("", |m| m.as_str());

+ let next_url = match url.chars().next() {

+ Some('/') => format!("{}{}", get_last_url(), url),

+ Some(_) => url.to_owned(),

+ None => url.to_owned()

+ };

+ visit_url(s, &next_url)

+ } else {

+ ()

+ }

}


fn get_data(url: &str) -> Result<String, String> {

+ let urlp = Url::parse(url).unwrap();

+ let host = urlp.host_str().unwrap();

+ let path = urlp.path();

+ let urlf = format!("{}:1965", host);

+

let mut builder = TlsConnector::builder();

builder.danger_accept_invalid_hostnames(true);

builder.danger_accept_invalid_certs(true);

let connector = builder.build().unwrap();


- let stream = TcpStream::connect(format!("{}:1965", url));

+ let stream = TcpStream::connect(&urlf);


match stream {

Ok(stream) => {

- let mstream = connector.connect(url, stream);

+ let mstream = connector.connect(&host, stream);


match mstream {

Ok(mut stream) => {

- stream.write_all(b"/\r\n").unwrap();

+ append_history(url);

+

+ let url_with_path = format!("{}\r\n", path);

+ stream.write_all(url_with_path.as_bytes()).unwrap();

let mut res = vec![];

stream.read_to_end(&mut res).unwrap();

Ok(String::from_utf8_lossy(&res).to_string())

},

- Err(e) => Err(format!("Could not connect to {}\n{}", url, e))

+ Err(e) => Err(format!("Could not connect to {}\n{}", urlf, e))

}

},

- Err(e) => Err(format!("Could not connect to {}\n{}", url, e))

+ Err(e) => Err(format!("Could not connect to {}\n{}", urlf, e))

}

}

+

+fn get_last_url() -> String {

+ let mut file = File::open("/tmp/asuka_history").expect("file not found");

+ let mut content = String::new();

+ file.read_to_string(&mut content).expect("Unable to read file");

+ content.lines().last().unwrap().to_owned()

+}

+

+fn append_history(url: &str) {

+ let mut file = OpenOptions::new()

+ .read(true)

+ .create(true)

+ .write(true)

+ .append(true)

+ .open("/tmp/asuka_history")

+ .unwrap();

+

+ let line = format!("{}\n", url);

+ file.write_all(line.as_bytes()).expect("Unable to write file");

+}



---

Served by Pollux Gemini Server.

-- Response ended

-- Page fetched on Sun May 19 11:03:08 2024