rebound/rebound.rkt

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))]
))