From b9393ea625da4007d78f798f58f2417aa0214f78 Mon Sep 17 00:00:00 2001 From: dvkt Date: Sat, 4 Jan 2020 15:46:12 -0800 Subject: [PATCH 01/13] little color module --- src/color.rs | 25 +++++++++++++++++++++++++ src/lib.rs | 1 + 2 files changed, 26 insertions(+) create mode 100644 src/color.rs diff --git a/src/color.rs b/src/color.rs new file mode 100644 index 0000000..86c3fa8 --- /dev/null +++ b/src/color.rs @@ -0,0 +1,25 @@ +use std::fmt; + +macro_rules! color { + ($t:ident, $code:expr) => { + pub struct $t; + impl fmt::Display for $t { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "\x1b[{}m", $code) + } + } + }; +} + +color!(Black, 90); +color!(Red, 91); +color!(Green, 92); +color!(Yellow, 93); +color!(Blue, 94); +color!(Magenta, 95); +color!(Cyan, 96); +color!(White, 97); + +color!(Reset, 0); +color!(Bold, 1); +color!(Underline, 4); diff --git a/src/lib.rs b/src/lib.rs index 6e7b348..5be46c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +pub mod color; pub mod request; pub mod server; From f521ea21d1627e09179f45d5786130c9a27aa049 Mon Sep 17 00:00:00 2001 From: dvkt Date: Sat, 4 Jan 2020 15:49:15 -0800 Subject: [PATCH 02/13] jazz up logs --- src/server.rs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/server.rs b/src/server.rs index 7ad79d9..3026b4a 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,4 +1,4 @@ -use crate::{Request, Result}; +use crate::{color, Request, Result}; use gophermap::{GopherMenu, ItemType}; use std::{ fs, @@ -28,14 +28,26 @@ pub fn start(host: &str, port: u16, root: &str) -> Result<()> { let full_root_path = fs::canonicalize(&root)?.to_string_lossy().to_string(); let pool = ThreadPool::new(MAX_WORKERS); - println!("-> Listening on {} at {}", addr, full_root_path); + println!( + "{}- Listening on {} at {}{}", + color::Yellow, + addr, + full_root_path, + color::Reset + ); for stream in listener.incoming() { let stream = stream?; - println!("-> Connection from: {}", stream.peer_addr()?); + println!( + "{}┌ Connection{} from {}{}", + color::Green, + color::Reset, + color::Magenta, + stream.peer_addr()? + ); let req = Request::from(host, port, root)?; pool.execute(move || { if let Err(e) = accept(stream, req) { - eprintln!("-! {}", e); + eprintln!("{}└ {}{}", color::Red, e, color::Reset); } }); } @@ -47,7 +59,13 @@ fn accept(stream: TcpStream, mut req: Request) -> Result<()> { let reader = BufReader::new(&stream); let mut lines = reader.lines(); if let Some(Ok(line)) = lines.next() { - println!("-> Client sent: {:?}", line); + println!( + "{}│{} Client sent: {:?}{}", + color::Green, + color::Reset, + line, + color::Reset + ); req.parse_request(&line); write_response(&stream, req)?; } From cd9fb92636354fa2e04a9930b1bc82f8e48c48ca Mon Sep 17 00:00:00 2001 From: dvkt Date: Sat, 4 Jan 2020 16:02:56 -0800 Subject: [PATCH 03/13] ignore trailing slash --- src/request.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/request.rs b/src/request.rs index df97f94..3d8231c 100644 --- a/src/request.rs +++ b/src/request.rs @@ -50,5 +50,12 @@ impl Request { } } self.selector.push_str(line); + + // strip trailing / + if let Some(last) = self.selector.chars().last() { + if last == '/' { + self.selector.pop(); + } + } } } From 51bd604cb2cb853579c9cf1689beb289bf65e138 Mon Sep 17 00:00:00 2001 From: dvkt Date: Sat, 4 Jan 2020 16:03:03 -0800 Subject: [PATCH 04/13] jazz up logging more --- src/server.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/server.rs b/src/server.rs index 3026b4a..a7a13ac 100644 --- a/src/server.rs +++ b/src/server.rs @@ -29,9 +29,13 @@ pub fn start(host: &str, port: u16, root: &str) -> Result<()> { let pool = ThreadPool::new(MAX_WORKERS); println!( - "{}- Listening on {} at {}{}", + "{}┬ Listening {}on {}{}{} at {}{}{}", + color::Yellow, + color::Reset, color::Yellow, addr, + color::Reset, + color::Blue, full_root_path, color::Reset ); @@ -60,9 +64,10 @@ fn accept(stream: TcpStream, mut req: Request) -> Result<()> { let mut lines = reader.lines(); if let Some(Ok(line)) = lines.next() { println!( - "{}│{} Client sent: {:?}{}", + "{}│{} Client sent: {}{:?}{}", color::Green, color::Reset, + color::Cyan, line, color::Reset ); From 3a59b3779c9a79b06507af271c53f8468e91acc9 Mon Sep 17 00:00:00 2001 From: dvkt Date: Sat, 4 Jan 2020 16:22:11 -0800 Subject: [PATCH 05/13] more logging statements --- src/server.rs | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/server.rs b/src/server.rs index a7a13ac..ab62d4c 100644 --- a/src/server.rs +++ b/src/server.rs @@ -64,7 +64,7 @@ fn accept(stream: TcpStream, mut req: Request) -> Result<()> { let mut lines = reader.lines(); if let Some(Ok(line)) = lines.next() { println!( - "{}│{} Client sent: {}{:?}{}", + "{}│{} Client sent:\t{}{:?}{}", color::Green, color::Reset, color::Cyan, @@ -191,6 +191,15 @@ where } menu.end()?; + println!( + "{}│{} Server reply:\t{}DIR {}{}{}", + color::Green, + color::Reset, + color::Yellow, + color::Bold, + req.relative_file_path(), + color::Reset, + ); Ok(()) } @@ -199,8 +208,18 @@ fn write_file<'a, W>(mut w: &'a W, req: Request) -> Result<()> where &'a W: Write, { - let mut f = fs::File::open(&req.file_path())?; + let path = req.file_path(); + let mut f = fs::File::open(&path)?; io::copy(&mut f, &mut w)?; + println!( + "{}│{} Server reply:\t{}FILE {}{}{}", + color::Green, + color::Reset, + color::Yellow, + color::Bold, + req.relative_file_path(), + color::Reset, + ); Ok(()) } @@ -215,7 +234,7 @@ where let reader = if is_executable(&path) { shell(&path, &[&req.query, &req.host, &req.port.to_string()])? } else { - fs::read_to_string(path)? + fs::read_to_string(&path)? }; for line in reader.lines() { @@ -236,6 +255,15 @@ where line.push_str("\r\n"); w.write_all(line.as_bytes())?; } + println!( + "{}│{} Server reply:\t{}MAP {}{}{}", + color::Green, + color::Reset, + color::Yellow, + color::Bold, + req.relative_file_path(), + color::Reset, + ); Ok(()) } @@ -244,6 +272,13 @@ where &'a W: Write, { let line = format!("3Not Found: {}\t/\tnone\t70\r\n", req.selector); + println!( + "{}│ Not found: {}{}{}", + color::Red, + color::Cyan, + req.relative_file_path(), + color::Reset, + ); w.write_all(line.as_bytes())?; Ok(()) } From 9852a13da7e34bb2982df032b1ecbd3dd4571693 Mon Sep 17 00:00:00 2001 From: dvkt Date: Sat, 4 Jan 2020 16:24:22 -0800 Subject: [PATCH 06/13] more colors --- src/color.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/color.rs b/src/color.rs index 86c3fa8..a7988cf 100644 --- a/src/color.rs +++ b/src/color.rs @@ -20,6 +20,15 @@ color!(Magenta, 95); color!(Cyan, 96); color!(White, 97); +color!(DarkBlack, 30); +color!(DarkRed, 31); +color!(DarkGreen, 32); +color!(DarkYellow, 33); +color!(DarkBlue, 34); +color!(DarkMagenta, 35); +color!(DarkCyan, 36); +color!(DarkWhite, 37); + color!(Reset, 0); color!(Bold, 1); color!(Underline, 4); From e5a422c8cd6c46b3a4858bfb0dd9ea8c0872d889 Mon Sep 17 00:00:00 2001 From: dvkt Date: Sat, 4 Jan 2020 16:29:50 -0800 Subject: [PATCH 07/13] (cargo-release) version 0.1.5 --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a3054d2..e47e60f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,7 +42,7 @@ dependencies = [ [[package]] name = "phd" -version = "0.1.5-dev" +version = "0.1.5" dependencies = [ "content_inspector 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "gophermap 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 513ae4a..219c9ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "phd" -version = "0.1.5-dev" +version = "0.1.5" authors = ["dvkt "] license = "MIT" edition = "2018" diff --git a/README.md b/README.md index 7e8a820..4f29068 100644 --- a/README.md +++ b/README.md @@ -92,9 +92,9 @@ then: binaries for linux, mac, and raspberry pi are available at https://github.com/dvkt/phd/releases: -- [phd-v0.1.4-linux-x86_64.tar.gz][0] -- [phd-v0.1.4-linux-armv7.tar.gz (RPi)][1] -- [phd-v0.1.4-macos.zip][2] +- [phd-v0.1.5-linux-x86_64.tar.gz][0] +- [phd-v0.1.5-linux-armv7.tar.gz (RPi)][1] +- [phd-v0.1.5-macos.zip][2] just unzip/untar the `phd` program into your $PATH and get going! @@ -116,7 +116,7 @@ just unzip/untar the `phd` program into your $PATH and get going! - [ ] man page - [ ] ipv6 -[0]: https://github.com/dvkt/phd/releases/download/v0.1.3/phd-v0.1.4-linux-x86_64.tar.gz -[1]: https://github.com/dvkt/phd/releases/download/v0.1.3/phd-v0.1.4-linux-armv7.tar.gz -[2]: https://github.com/dvkt/phd/releases/download/v0.1.3/phd-v0.1.4-macos.zip +[0]: https://github.com/dvkt/phd/releases/download/v0.1.5/phd-v0.1.5-linux-x86_64.tar.gz +[1]: https://github.com/dvkt/phd/releases/download/v0.1.5/phd-v0.1.5-linux-armv7.tar.gz +[2]: https://github.com/dvkt/phd/releases/download/v0.1.5/phd-v0.1.5-macos.zip [map]: https://en.wikipedia.org/wiki/Gopher_(protocol)#Source_code_of_a_menu From 840c1dd5cce55da7f9eb14a5b02a8d1b8c1e617d Mon Sep 17 00:00:00 2001 From: dvkt Date: Sat, 4 Jan 2020 16:30:00 -0800 Subject: [PATCH 08/13] (cargo-release) start next development iteration 0.1.6-dev --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e47e60f..da7b105 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,7 +42,7 @@ dependencies = [ [[package]] name = "phd" -version = "0.1.5" +version = "0.1.6-dev" dependencies = [ "content_inspector 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "gophermap 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 219c9ef..dfe59e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "phd" -version = "0.1.5" +version = "0.1.6-dev" authors = ["dvkt "] license = "MIT" edition = "2018" From 9ee7416403e6e8e8d977449f8ac50d2b7c683726 Mon Sep 17 00:00:00 2001 From: dvkt Date: Sat, 4 Jan 2020 16:49:36 -0800 Subject: [PATCH 09/13] add version badge to readme --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4f29068..dd38501 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,11 @@ | )| )| ) |__/ | / |__/ | --->

+-->


+ + + +

`phd` is an esoteric gopher server for small gopherholes. From 43e596d01b1055f38075eab7984ae3d05dc831ae Mon Sep 17 00:00:00 2001 From: dvkt Date: Mon, 6 Jan 2020 02:14:21 -0800 Subject: [PATCH 10/13] fix version regex --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dfe59e1..5a23552 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,8 +25,8 @@ gophermap = "0.1.2" [package.metadata.release] pre-release-replacements = [ - {file="README.md", search="phd-v\\d\\.\\d\\.\\d-", replace="{{crate_name}}-v{{version}}-"}, - {file="README.md", search="/v\\d\\.\\d\\.\\d/", replace="/v{{version}}/"}, + {file="README.md", search="phd-v\\d+\\.\\d+\\.\\d+-", replace="{{crate_name}}-v{{version}}-"}, + {file="README.md", search="/v\\d+\\.\\d+\\.\\d+/", replace="/v{{version}}/"}, ] dev-version-ext = "dev" From 616a164baff9601c46b3e048c54e0b25c0ab7c02 Mon Sep 17 00:00:00 2001 From: dvkt Date: Mon, 6 Jan 2020 11:35:19 -0800 Subject: [PATCH 11/13] ruby example --- README.md | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dd38501..9efd4bd 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ sub-directories, and binary files over gopher. any `.gph` files will be served up as [gopermaps][map] and executable `.gph` files will be run as a script with their output served to the client, like cgi! -special files: +### special files: - **header.gph**: if it exists in a directory, its content will be shown above the directory's content. put ascii art in it. @@ -33,6 +33,8 @@ any line in a `.gph` file that doesn't contain tabs (`\t`) and doesn't start with an `i` will get an `i` automatically prefixed, turning it into a gopher information item. +### dynamic content: + any `.gph` file that is marked **executable** with be run as if it were a shell script and its output will be sent to the client. it will be passed three arguments: the query string (if any, the host, and the @@ -67,6 +69,40 @@ then: [INFO] |_| |_|_| \__, |\___/| .__/|_| |_|\___|_| [INFO] |___/ |_| +### ruby on rails: + +`sh` is fun, but for serious work you need a serious scripting +language like Ruby or PHP or Node.JS: + + $ cat sizes.gph + #!/usr/bin/env ruby + + def filesize(file) + (size=File.size file) > (k=1024) ? "#{size/k}K" : "#{size}B" + end + + puts "~ file sizes ~" + spaces = 20 + Dir[__dir__ + "/*"].each do |entry| + name = File.basename entry + puts "#{name}#{' ' * (spaces - name.length)}#{filesize entry}" + end + +now you can finally share the file sizes of a directory with the world +of Gopher! + + $ phetch -r 0.0.0.0:7070/1/sizes + i~ file sizes ~ (null) 127.0.0.1 7070 + iCargo.toml 731B (null) 127.0.0.1 7070 + iLICENSE 1K (null) 127.0.0.1 7070 + iMakefile 724B (null) 127.0.0.1 7070 + itarget 288B (null) 127.0.0.1 7070 + iphd 248K (null) 127.0.0.1 7070 + iCargo.lock 2K (null) 127.0.0.1 7070 + iREADME.md 4K (null) 127.0.0.1 7070 + img 96B (null) 127.0.0.1 7070 + isizes.gph 276B (null) 127.0.0.1 7070 + isrc 224B (null) 127.0.0.1 7070 ## usage From 49dab5b83d59f4ddba7fd4cba338887ed08bce0e Mon Sep 17 00:00:00 2001 From: dvkt Date: Mon, 6 Jan 2020 11:36:06 -0800 Subject: [PATCH 12/13] colors --- README.md | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 9efd4bd..a895d4b 100644 --- a/README.md +++ b/README.md @@ -42,10 +42,12 @@ port. do with them what you will. for example: - $ cat echo.gph - #!/bin/sh - echo "Hi, world! You said:" $1 - echo "1Visit Gopherpedia / gopherpedia.com 70" +```sh +$ cat echo.gph +#!/bin/sh +echo "Hi, world! You said:" $1 +echo "1Visit Gopherpedia / gopherpedia.com 70" +``` then: @@ -55,9 +57,11 @@ then: or more seriously: - $ cat figlet.gph - #!/bin/sh - figlet $1 +```sh +$ cat figlet.gph +#!/bin/sh +figlet $1 +``` then: @@ -74,19 +78,21 @@ then: `sh` is fun, but for serious work you need a serious scripting language like Ruby or PHP or Node.JS: - $ cat sizes.gph - #!/usr/bin/env ruby - - def filesize(file) - (size=File.size file) > (k=1024) ? "#{size/k}K" : "#{size}B" - end - - puts "~ file sizes ~" - spaces = 20 - Dir[__dir__ + "/*"].each do |entry| - name = File.basename entry - puts "#{name}#{' ' * (spaces - name.length)}#{filesize entry}" - end +```ruby +$ cat sizes.gph +#!/usr/bin/env ruby + +def filesize(file) + (size=File.size file) > (k=1024) ? "#{size/k}K" : "#{size}B" +end + +puts "~ file sizes ~" +spaces = 20 +Dir[__dir__ + "/*"].each do |entry| +name = File.basename entry +puts "#{name}#{' ' * (spaces - name.length)}#{filesize entry}" +end +``` now you can finally share the file sizes of a directory with the world of Gopher! From 99178d51d9f63beaa7a33a80d40208a252659cb4 Mon Sep 17 00:00:00 2001 From: dvkt Date: Mon, 6 Jan 2020 11:37:07 -0800 Subject: [PATCH 13/13] indent --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a895d4b..267da84 100644 --- a/README.md +++ b/README.md @@ -89,8 +89,8 @@ end puts "~ file sizes ~" spaces = 20 Dir[__dir__ + "/*"].each do |entry| -name = File.basename entry -puts "#{name}#{' ' * (spaces - name.length)}#{filesize entry}" + name = File.basename entry + puts "#{name}#{' ' * (spaces - name.length)}#{filesize entry}" end ```