Have been reading over the specs for HTTP/2 and gRPC lately. It looks like you have to use some TLS protocol negotiation system I've never seen before and I'm not sure the stdlib is compatible with it.
It looks like its part of the handshake which means one can't patch it on without duplicating or modifying the standard library. Which makes this part a bit of a doozy.
Is support for this buried somewhere or is it as troubling as it looks?
It looks like OpenSSL does support this via SSL_CTX_set_alpn_select_cb[1] but Nim's wrapper does not have it[2].
As far as the API goes it looks like you provide a seq[string] of protocols you are wiling to communicate on that TLS session and it does a callback to inform you which the client selected via a callback.
This is sadly needed to do anything with encrypted SPDY/HTTP2 (but not QUIC.)
[1]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_alpn_select_cb.html [2]: https://nim-lang.org/docs/openssl.html
i don't know what you need to do with the alpn_cb, but one can easily import any missing procs that haven't made it into openssl. in this case:
import openssl
type AlpnSelectCb = proc(ssl: SSLPtr, outproto:var ptr UncheckedArray[byte],outlen:var uint8,inproto: ptr UncheckedArray[byte],inlen:cuint,arg:pointer):cint {.cdecl.}
proc SSL_CTX_set_alpn_select_cb(ctx:SslCtx, callback:AlpnSelectCb,arg:pointer){.cdecl,importc,dynlib:DLLSSLName.}
i've taken one small liberty using byte and uint8 instead of the technically accurate cuchar, if you're running ssl on a machine with a non-8bit char, in Nim, please write a blog post about it, that sounds fascinating.😜It looks like this can be wrapped in to two stdlib functions; one that sets the list from a seq[string] and then expose the selected protocol as an option[string]. There is a standard way of selection which is offered by OpenSSL so it isn't strictly necessary to expose that part.
This would look something like:
proc set_alpn_protocols(context: var SslContext; protocols: openarray[string])
proc alpn_protocols(context: SslContext): Option[string]
Happy to accept any patches that add this support. :)
If you want a bigger project: BearSSL support in the stdlib would be cool too :D