[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#24075: tls/https support in Guile (through r6rs binary ports?)
From: |
Ludovic Courtès |
Subject: |
bug#24075: tls/https support in Guile (through r6rs binary ports?) |
Date: |
Sat, 05 Nov 2016 20:02:32 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux) |
Hi!
Christopher Allan Webber <address@hidden> skribis:
>>From d4def07779c5532ffc6b7ee13820919bc23d1811 Mon Sep 17 00:00:00 2001
> From: Christopher Allan Webber <address@hidden>
> Date: Thu, 17 Sep 2015 15:14:54 -0500
> Subject: [PATCH] web: Add https support through gnutls.
>
> Since importing gnutls directly would result in a dependency cycle,
> we load gnutls lazily.
>
> This uses code originally written for Guix by Ludovic
>
> * module/web/client.scm: (%http-receive-buffer-size)
> (warn-no-gnutls-return-false, gnutls-module, ensure-gnutls)
> (gnutls-ref, tls-wrap): New variables.
> (open-socket-for-uri): Wrap in tls when uri scheme is https.
Woohoo, cool!
> +(define (ensure-gnutls)
> + (if (not (force gnutls-module))
> + (throw 'gnutls-not-available "(gnutls) module not available")))
I wonder if this is the right exception, but I can’t think of anything
better (there’s no generic “not supported” exception I think; (throw
'system-error … ENOSYS) would do that but it’s too vague.)
> +(define (gnutls-ref symbol)
> + "Fetch method-symbol from the gnutls module"
> + (module-ref (force gnutls-module) symbol))
> +
> (define current-http-proxy
> (make-parameter (let ((proxy (getenv "http_proxy")))
> (and (not (equal? proxy ""))
> proxy))))
>
> +(define (tls-wrap port server)
> + "Return PORT wrapped in a TLS connection to SERVER. SERVER must be a DNS
> +host name without trailing dot."
> + (define (log level str)
> + (format (current-error-port)
> + "gnutls: [~a|~a] ~a" (getpid) level str))
> +
> + (ensure-gnutls)
> +
> + (let ((session ((gnutls-ref 'make-session)
> + (gnutls-ref 'connection-end/client))))
What about leaving the ‘ensure-gnutls’ call and then simply use the
GnuTLS symbols directly and rely on autoloading, as in (guix build
download)?
--8<---------------cut here---------------start------------->8---
;; Autoload GnuTLS so that this module can be used even when GnuTLS is
;; not available. At compile time, this yields "possibly unbound
;; variable" warnings, but these are OK: we know that the variables will
;; be bound if we need them, because (guix download) adds GnuTLS as an
;; input in that case.
;; XXX: Use this hack instead of #:autoload to avoid compilation errors.
;; See <http://bugs.gnu.org/12202>.
(module-autoload! (current-module)
'(gnutls) '(make-session connection-end/client))
--8<---------------cut here---------------end--------------->8---
That would lead more concise and slightly more efficient code, and I
think it would still work as expected in the absence of (gnutls).
WDYT?
> + (define (read! bv start count)
> + (define read-bv (get-bytevector-n record count))
> + (define read-bv-len (bytevector-length read-bv))
> + (bytevector-copy! read-bv 0 bv 0 read-bv-len)
> + read-bv-len)
Beware: ‘get-bytevector-n’ can return the EOF object instead of a
number, so you need to check for that. (Conversely, ‘read!’ needs to
return 0 to indicate EOF.)
> + (define (open-socket)
> + (let loop ((addresses addresses))
Or just “(define sock …”.
Otherwise works for me!
Could you document HTTPS support in the doc of ‘open-socket-for-uri’
(info "(guile) Web Client")? Probably with something like:
@xref{Guile Preparations,
how to install the GnuTLS bindings for Guile,, gnutls-guile,
GnuTLS-Guile}, for more information.
Thank you Chris!
Ludo’.