rebound/request-page.rkt

68 lines
2.6 KiB
Racket

#lang racket/gui
(require openssl net/url-string)
(require "strings.rkt")
(provide request-url request-url-str)
(define (format-request url)
(~a (url->string url) "\r\n"))
(define (request-url-str url-str)
(let ([url (string->url (if (equal? "gemini://" (substring url-str 0 9))
url-str
(~a "gemini://" url-str)))])
(unless (url-port url)
(set-url-port! url 1965))
(request-url (url-host url) (url-port url) (format-request url))))
(define (request-url host port request)
(let-values ([(in out) (ssl-connect/enable-break host 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) (~a sensitive-input info)]
[else (~a normal-input info)])]
[(2) (case info
[("text/gemini" "text/plain")
(port->string in)]
[else (~a unhandled-mimetype info)])]
[(3) (case status-last
[(1) (displayln
(~a permanently-redirecting info))]
[else (displayln
(~a temporarily-redirecting info))])
(request-url-str info)]
[(4) (case status-last
[(1) (~a server-unavailable info)]
[(2) (~a cgi-error info)]
[(3) (~a proxy-error info)]
[(4) (~a slow-down info)]
[else (~a temporary-unspecified info)])]
[(5) (case status-last
[(1) (~a file-not-found info)]
[(2) (~a file-gone info)]
[(3) (~a proxy-refused info)]
[(9) (~a bad-request info)]
[else (~a permanent-unspecified info)])]
[(6) (case status-last
[(1) (~a cert-unauthorized info)]
[(2) (~a cert-invalid info)]
[else (~a cert-required info)])]
[else (~a bad-status status)]))))