blast-off.scm 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #!/usr/bin/env -S guile -e main -s
  2. !#
  3. (add-to-load-path (string-append (dirname (dirname (current-filename))) "/src"))
  4. (use-modules (gemini request)
  5. (gemini response)
  6. (gemini server)
  7. (gemini util log)
  8. (fibers timers)
  9. (gnutls)
  10. (ice-9 getopt-long)
  11. (ice-9 textual-ports)
  12. (rnrs bytevectors)
  13. (srfi srfi-11)
  14. (srfi srfi-41)
  15. (web uri))
  16. (define (print-help args)
  17. (display (string-append "\
  18. usage: " (car args) " [options]
  19. options:
  20. -h, --help Display this help
  21. -v, --verbose Enable additional log messages
  22. -l, --listen=HOST:PORT Listen on HOST:PORT (default localhost:1965)
  23. -c, --cert=path/to/cert.pem Server certificate file
  24. -k, --key=path/to/key.pem Server private key file
  25. Start a simple Gemini server.
  26. ")))
  27. (define (handle-request req)
  28. (build-gemini-response
  29. #:status 20
  30. #:meta "text/gemini"
  31. #:body (lambda (port)
  32. (let loop ((n 10))
  33. (cond ((= n 0)
  34. (format port "Blast off!\n"))
  35. (else
  36. (format port "~a...\n" n)
  37. (force-output port)
  38. (sleep 1)
  39. (loop (1- n))))))))
  40. (define (parse-address address)
  41. (cond ((not address)
  42. (values #f #f))
  43. ((string-contains address ":")
  44. (apply values (string-split address #\:)))
  45. (else
  46. (values address #f))))
  47. (define (load-credentials cert key)
  48. (let ((creds (make-certificate-credentials)))
  49. (when (and cert key)
  50. (log-debug "Loading cert: ~a" cert)
  51. (log-debug "Loading key: ~a" key)
  52. (set-certificate-credentials-x509-key-files!
  53. creds cert key x509-certificate-format/pem))
  54. creds))
  55. (define (main args)
  56. (let* ((option-spec '((help (single-char #\h) (value #f))
  57. (verbose (single-char #\v) (value #f))
  58. (listen (single-char #\l) (value #t))
  59. (cert (single-char #\c) (value #t))
  60. (key (single-char #\k) (value #t))))
  61. (opts (getopt-long args option-spec))
  62. (help (option-ref opts 'help #f))
  63. (verbose (option-ref opts 'verbose #f))
  64. (listen (option-ref opts 'listen #f))
  65. (cert (option-ref opts 'cert #f))
  66. (key (option-ref opts 'key #f)))
  67. (cond (help
  68. (print-help args))
  69. (else
  70. (when verbose
  71. (set-gemini-log-level! 'debug))
  72. (let-values (((host port) (parse-address listen))
  73. ((creds) (load-credentials cert key)))
  74. (run-server handle-request
  75. #:host host
  76. #:port port
  77. #:credentials creds))))))