60 lines
2.1 KiB
Racket
60 lines
2.1 KiB
Racket
#lang racket/gui
|
|
(require openssl)
|
|
|
|
(define port 1965)
|
|
(define target "geminiprotocol.net")
|
|
(define request "gemini://geminiprotocol.net/index.gmi\r\n")
|
|
|
|
(define-values (in out) (ssl-connect/enable-break target port))
|
|
(file-stream-buffer-mode out 'none)
|
|
|
|
(display request out)
|
|
(flush-output out)
|
|
|
|
(let* ([response-head (read-line in)]
|
|
[status (string->number (substring response-head 0 2))]
|
|
[status-first (quotient status 10)]
|
|
[status-last (modulo status 10)]
|
|
[info (if (> (string-length response-head) 2)
|
|
(string-trim (substring response-head 2))
|
|
"[none given]")])
|
|
(case status-first
|
|
[(1) (case status-last
|
|
[(1) (display "requesting sensitive input, ")]
|
|
[else (display "requesting normal input, ")])
|
|
(displayln (~a "input prompt: " info))]
|
|
|
|
[(2) (case info
|
|
[("text/gemini" "text/plain") (displayln (port->string in))]
|
|
[else (displayln (~a "requested file is of unhandled mimetype: " info))])]
|
|
|
|
[(3) (case status-last
|
|
[(1) (display "permanently")]
|
|
[else (display "temporarily")])
|
|
(displayln (~a " redirecting to: " info))]
|
|
|
|
[(4) (display "temporary failure, reason: ")
|
|
(case status-last
|
|
[(1) (display "server unavailable")]
|
|
[(2) (display "cgi error")]
|
|
[(3) (display "proxy error")]
|
|
[(4) (display "SLOW DOWN")]
|
|
[else (display "unspecified")])
|
|
(displayln (~a "; error message: " info))]
|
|
|
|
[(5) (display "permanent failure, reason: ")
|
|
(case status-last
|
|
[(1) (display "file not found")]
|
|
[(2) (display "gone")]
|
|
[(3) (display "proxy request refused")]
|
|
[(9) (display "bad request")]
|
|
[else (display "unspecified")])
|
|
(displayln (~a "; error message: " info))]
|
|
|
|
[(6) (display "client certificate ")
|
|
(case status-last
|
|
[(1) (display "not authorized")]
|
|
[(2) (display "not valid")]
|
|
[else (display "required")])
|
|
(displayln (~a "; error message: " info))]
|
|
)) |