]> gitweb.factorcode.org Git - factor.git/commitdiff
gemini: client for Project gemini.
authorJohn Benediktsson <mrjbq7@gmail.com>
Thu, 11 Mar 2021 22:20:58 +0000 (14:20 -0800)
committerJohn Benediktsson <mrjbq7@gmail.com>
Thu, 11 Mar 2021 22:20:58 +0000 (14:20 -0800)
extra/gemini/authors.txt [new file with mode: 0644]
extra/gemini/gemini.factor [new file with mode: 0644]
extra/gemini/summary.txt [new file with mode: 0644]
extra/gemini/tags.txt [new file with mode: 0644]

diff --git a/extra/gemini/authors.txt b/extra/gemini/authors.txt
new file mode 100644 (file)
index 0000000..e091bb8
--- /dev/null
@@ -0,0 +1 @@
+John Benediktsson
diff --git a/extra/gemini/gemini.factor b/extra/gemini/gemini.factor
new file mode 100644 (file)
index 0000000..e6d22a2
--- /dev/null
@@ -0,0 +1,110 @@
+! Copyright (C) 2021 John Benediktsson
+! See http://factorcode.org/license.txt for BSD license
+
+USING: accessors ascii continuations io io.encodings.utf8
+io.sockets io.sockets.secure kernel present sequences
+sequences.extras splitting ;
+
+IN: gemini
+
+! Project Gemini
+! "Speculative specification"
+! v0.14.3, November 29, 2020
+
+! https://gemini.circumlunar.space/docs/specification.gmi
+
+! URL" gemini://gemini.circumlunar.space"
+
+<PRIVATE
+
+CONSTANT: STATUS-CATEGORIES H{
+    { 10 "Input" }
+    { 20 "Success" }
+    { 30 "Redirect" }
+    { 40 "Temporary Failure" }
+    { 50 "Permanent Failure" }
+    { 60 "Client Certificate Required" }
+}
+
+CONSTANT: STATUS-CODES H{
+    { 10 "Input" }
+    { 11 "Sensitive Input" }
+    { 20 "Success" }
+    { 30 "Redirect - Temporary" }
+    { 31 "Redirect - Permanent" }
+    { 40 "Temporary Failure" }
+    { 41 "Server Unavailable" }
+    { 42 "CGI Error" }
+    { 43 "Proxy Error" }
+    { 44 "Slow Down" }
+    { 50 "Permanent Failure" }
+    { 51 "Not Found" }
+    { 52 "Gone" }
+    { 53 "Proxy Request Refused" }
+    { 59 "Bad Request" }
+    { 60 "Client Certificate Requested" }
+    { 61 "Certificate Not Authorized" }
+    { 62 "Certificate Not Valid" }
+}
+
+: read-body ( -- body )
+    [ readln ] loop>array ;
+
+: ?read-body ( status -- body/f )
+    ?first CHAR: 2 = [ read-body ] [ f ] if ;
+
+: read-response ( -- status meta body/f )
+    readln [ blank? ] split1-when over ?read-body ;
+
+: send-request ( url -- )
+    present write "\r\n" write flush ;
+
+: gemini-addr ( url -- addr )
+    [ host>> ] [ port>> 1965 or ] bi <inet> ;
+
+: gemini-tls ( -- )
+    ! XXX: Implement Trust-On-First-Use
+    [ send-secure-handshake ] [ certificate-verify-error? ] ignore-error ;
+
+PRIVATE>
+
+: gemini-get ( url -- status meta body/f )
+    dup gemini-addr utf8 [
+        gemini-tls
+        send-request
+        read-response
+    ] with-client ;
+
+: gemini. ( url -- )
+    gemini-get 2nip [ print ] each ;
+
+! "gemtext"
+
+! Text Lines
+! 
+! ... each line is a paragraph
+! ... each blank line is a vertical space
+! 
+! 
+! Link Lines
+! 
+! =>[<whitespace>]<URL>[<whitespace><USER-FRIENDLY LINK NAME>]<CR><LF>
+! 
+! Preformatted toggle lines
+! 
+! ```
+! 
+! Heading Lines
+! 
+! # 
+! ##
+! ###
+! 
+! Unordered list lines
+! 
+! * 
+!
+! Quote lines
+! 
+! >
+! >
diff --git a/extra/gemini/summary.txt b/extra/gemini/summary.txt
new file mode 100644 (file)
index 0000000..b729f50
--- /dev/null
@@ -0,0 +1 @@
+Gemini client
diff --git a/extra/gemini/tags.txt b/extra/gemini/tags.txt
new file mode 100644 (file)
index 0000000..992ae12
--- /dev/null
@@ -0,0 +1 @@
+network