RejectedSoftware Forums

Sign up

requestHTTP and TLS

I'm struggling to update my requestHTTP function call to use TLS. I've attempted to set the [HTTPClientSettings]|(https://vibed.org/api/vibe.http.client/HTTPClientSettings) thus:

auto settings = new HTTPClientSettings;
settings.tlsContextSetup = (scope ctx) {
    ctx.kind = TLSContextKind.client;
};

HTTPClientResponse response = requestHTTP(url, (scope HTTPClientRequest request) {
    request.method = HTTPMethod.POST;
    immutable requestBody = EXAMPLE.format(stuff);
    request.writeBody(cast(ubyte[]) requestBody, JSON_MIME);
}, settings);

But I get an error:

Error: function `vibe.stream.tls.TLSContext.kind() const` is not callable using argument types `(TLSContextKind)`: expected 0 argument(s), not 1

What am I missing?

Thanks,

Curtis

Re: requestHTTP and TLS

Am 03.12.2024 um 03:48 schrieb Curtis:

I'm struggling to update my requestHTTP function call to use TLS. I've
attempted to set the [HTTPClientSettings]|(https://vibed.org/api/
vibe.http.client/HTTPClientSettings) thus:

auto settings = new HTTPClientSettings;
settings.tlsContextSetup = (scope ctx) {
    ctx.kind = TLSContextKind.client;
};

HTTPClientResponse response = requestHTTP(url, (scope HTTPClientRequest 
request) {
    request.method = HTTPMethod.POST;
    immutable requestBody = EXAMPLE.format(stuff);
    request.writeBody(cast(ubyte[]) requestBody, JSON_MIME);
}, settings);

But I get an error:

Error: function `vibe.stream.tls.TLSContext.kind() const` is not 
callable using argument types `(TLSContextKind)`: expected 0 
argument(s), not 1

What am I missing?

Thanks,

Curtis

The kind property is read-only and is determined at instantiation time
(in this case it should always be TLSContextKind.client). What you
typically need to do within the tlsContextSetup callback, though, is
to set up rules for certificate verification.

On Linux that would typically be done like this, where the exact path
may differ between distributions:

ctx.useTrustedCertificateFile("/etc/ssl/certs/ca-certificates.crt");

If you are dealing with self-signed certificates, you would have to
lower peerValidationMode to TLSPeerValidationMode.validCert and then
ideally set the peerValidationCallback to check if the certificate is
known or signed by your own CA certificate.

Re: requestHTTP and TLS

On Tue, 3 Dec 2024 18:20:17 +0100, Sönke Ludwig wrote:

Am 03.12.2024 um 03:48 schrieb Curtis:

I'm struggling to update my requestHTTP function call to use TLS. I've
attempted to set the [HTTPClientSettings]|(https://vibed.org/api/
vibe.http.client/HTTPClientSettings) thus:

auto settings = new HTTPClientSettings;
settings.tlsContextSetup = (scope ctx) {
    ctx.kind = TLSContextKind.client;
};

HTTPClientResponse response = requestHTTP(url, (scope HTTPClientRequest 
request) {
    request.method = HTTPMethod.POST;
    immutable requestBody = EXAMPLE.format(stuff);
    request.writeBody(cast(ubyte[]) requestBody, JSON_MIME);
}, settings);

But I get an error:

Error: function `vibe.stream.tls.TLSContext.kind() const` is not 
callable using argument types `(TLSContextKind)`: expected 0 
argument(s), not 1

What am I missing?

Thanks,

Curtis

The kind property is read-only and is determined at instantiation time
(in this case it should always be TLSContextKind.client). What you
typically need to do within the tlsContextSetup callback, though, is
to set up rules for certificate verification.

On Linux that would typically be done like this, where the exact path
may differ between distributions:

ctx.useTrustedCertificateFile("/etc/ssl/certs/ca-certificates.crt");

If you are dealing with self-signed certificates, you would have to
lower peerValidationMode to TLSPeerValidationMode.validCert and then
ideally set the peerValidationCallback to check if the certificate is
known or signed by your own CA certificate.

Thanks! The server I'm connecting to is using a Let's Encrypt cert so I've updated my code to:

settings.tlsContextSetup = (scope ctx) {
    ctx.useTrustedCertificateFile("/etc/ssl/certs/ISRG_Root_X1.pem");
};

and have left TLSPeerValidationMode alone since it it's a public certificate.

Now I'm running into a D error where it's saying my void delegate function can't be implicitly converted to void delegate nothrow:

Error: cannot implicitly convert expression '__lambda5' of type 'void delegate(TLSContext ctx) @safe' to 'void delegate(TLSContext ctx) nothrow @safe'

I tried changing the signature to (ctx) nothrow {... and void delegate() f(ctx) nothrow but the compiler complains about syntax errors.

Re: requestHTTP and TLS

Am 03.12.2024 um 20:26 schrieb Curtis:

On Tue, 3 Dec 2024 18:20:17 +0100, Sönke Ludwig wrote:

(...)

Thanks! The server I'm connecting to is using a Let's Encrypt cert so
I've updated my code to:

settings.tlsContextSetup = (scope ctx) {
    ctx.useTrustedCertificateFile("/etc/ssl/certs/ISRG_Root_X1.pem");
};

and have left TLSPeerValidationMode alone since it it's a public
certificate.

Now I'm running into a D error where it's saying my void delegate
function can't be implicitly converted to void delegate nothrow:

Error: cannot implicitly convert expression '__lambda5' of type 'void 
delegate(TLSContext ctx) @safe' to 'void delegate(TLSContext ctx) 
nothrow @safe'

I tried changing the signature to (ctx) nothrow {... and void <br>delegate() f(ctx) nothrow but the compiler complains about syntax errors.

Try wrapping the useTrustedCertificateFile call in a try-catch:

settings.tlsContextSetup = (scope ctx) {
     try ctx.useTrustedCertificateFile("/etc/ssl/certs/
ISRG_Root_X1.pem");
     catch (Exception e) {
         import vibe.core.log : logException;
         logException(e, "Failed to load trusted certificate store");
     }
};

Looking at the API an implementation, I actually wonder why the callback
needs to be nothrow at all. It looks like it would actually make a lot
of sense to let it throw on error.

Re: requestHTTP and TLS

On Wed, 4 Dec 2024 08:43:55 +0100, Sönke Ludwig wrote:

Am 03.12.2024 um 20:26 schrieb Curtis:

On Tue, 3 Dec 2024 18:20:17 +0100, Sönke Ludwig wrote:

(...)

Thanks! The server I'm connecting to is using a Let's Encrypt cert so
I've updated my code to:

settings.tlsContextSetup = (scope ctx) {
    ctx.useTrustedCertificateFile("/etc/ssl/certs/ISRG_Root_X1.pem");
};

and have left TLSPeerValidationMode alone since it it's a public
certificate.

Now I'm running into a D error where it's saying my void delegate
function can't be implicitly converted to void delegate nothrow:

Error: cannot implicitly convert expression '__lambda5' of type 'void 
delegate(TLSContext ctx) @safe' to 'void delegate(TLSContext ctx) 
nothrow @safe'

I tried changing the signature to (ctx) nothrow {... and void <br>delegate() f(ctx) nothrow but the compiler complains about syntax errors.

Try wrapping the useTrustedCertificateFile call in a try-catch:

settings.tlsContextSetup = (scope ctx) {
     try ctx.useTrustedCertificateFile("/etc/ssl/certs/
ISRG_Root_X1.pem");
     catch (Exception e) {
         import vibe.core.log : logException;
         logException(e, "Failed to load trusted certificate store");
     }
};

Looking at the API an implementation, I actually wonder why the callback
needs to be nothrow at all. It looks like it would actually make a lot
of sense to let it throw on error.

I added a try-catch and was able to get the app complied and working.

Appreciate the help!