diff --git a/client.go b/client.go index 1a370012..97381049 100644 --- a/client.go +++ b/client.go @@ -915,6 +915,46 @@ func (c *Client) SetRootCertificateFromString(pemContent string) *Client { return c } +// SetClientRootCertificate method helps to add one or more client's root certificates into Resty client +// +// client.SetClientRootCertificate("/path/to/root/pemFile.pem") +func (c *Client) SetClientRootCertificate(pemFilePath string) *Client { + rootPemData, err := os.ReadFile(pemFilePath) + if err != nil { + c.log.Errorf("%v", err) + return c + } + + config, err := c.tlsConfig() + if err != nil { + c.log.Errorf("%v", err) + return c + } + if config.ClientCAs == nil { + config.ClientCAs = x509.NewCertPool() + } + + config.ClientCAs.AppendCertsFromPEM(rootPemData) + return c +} + +// SetClientRootCertificateFromString method helps to add one or more client's root certificates into Resty client +// +// client.SetClientRootCertificateFromString("pem file content") +func (c *Client) SetClientRootCertificateFromString(pemContent string) *Client { + config, err := c.tlsConfig() + if err != nil { + c.log.Errorf("%v", err) + return c + } + if config.ClientCAs == nil { + config.ClientCAs = x509.NewCertPool() + } + + config.ClientCAs.AppendCertsFromPEM([]byte(pemContent)) + return c +} + // SetOutputDirectory method sets output directory for saving HTTP response into file. // If the output directory not exists then resty creates one. This setting is optional one, // if you're planning using absolute path in `Request.SetOutput` and can used together. diff --git a/client_test.go b/client_test.go index 748be258..ac14c0b1 100644 --- a/client_test.go +++ b/client_test.go @@ -309,6 +309,56 @@ func TestClientSetRootCertificateFromStringErrorTls(t *testing.T) { assertNil(t, transport) } +func TestClientSetClientRootCertificate(t *testing.T) { + client := dc() + client.SetClientRootCertificate(filepath.Join(getTestDataPath(), "sample-root.pem")) + + transport, err := client.Transport() + + assertNil(t, err) + assertNotNil(t, transport.TLSClientConfig.ClientCAs) +} + +func TestClientSetClientRootCertificateNotExists(t *testing.T) { + client := dc() + client.SetClientRootCertificate(filepath.Join(getTestDataPath(), "not-exists-sample-root.pem")) + + transport, err := client.Transport() + + assertNil(t, err) + assertNil(t, transport.TLSClientConfig) +} + +func TestClientSetClientRootCertificateFromString(t *testing.T) { + client := dc() + rootPemData, err := os.ReadFile(filepath.Join(getTestDataPath(), "sample-root.pem")) + assertNil(t, err) + + client.SetClientRootCertificateFromString(string(rootPemData)) + + transport, err := client.Transport() + + assertNil(t, err) + assertNotNil(t, transport.TLSClientConfig.ClientCAs) +} + +func TestClientSetClientRootCertificateFromStringErrorTls(t *testing.T) { + client := NewWithClient(&http.Client{}) + client.outputLogTo(io.Discard) + + rootPemData, err := os.ReadFile(filepath.Join(getTestDataPath(), "sample-root.pem")) + assertNil(t, err) + rt := &CustomRoundTripper{} + client.SetTransport(rt) + transport, err := client.Transport() + + client.SetClientRootCertificateFromString(string(rootPemData)) + + assertNotNil(t, rt) + assertNotNil(t, err) + assertNil(t, transport) +} + func TestClientOnBeforeRequestModification(t *testing.T) { tc := dc() tc.OnBeforeRequest(func(c *Client, r *Request) error {