Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion push.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ type PushOptions struct {

// Optional WaitGroup for waiting until all the push workers created with this WaitGroup are stopped.
WaitGroup *sync.WaitGroup

// CustomClient allows specifying a custom HTTP client for making the push requests.
//
// If nil, the default http.Client will be created.
CustomClient *http.Client
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, it's more clear to name it just as Client and add a comment, that it's optional http client for making push requests.

}

// InitPushWithOptions sets up periodic push for globally registered metrics to the given pushURL with the given interval.
Expand Down Expand Up @@ -325,7 +330,12 @@ func newPushContext(pushURL string, opts *PushOptions) (*pushContext, error) {
}

pushURLRedacted := pu.Redacted()
client := &http.Client{}

client := opts.CustomClient
if client == nil {
client = &http.Client{}
}

return &pushContext{
pushURL: pu,
method: method,
Expand Down
53 changes: 53 additions & 0 deletions push_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import (
"bytes"
"compress/gzip"
"context"
"crypto/tls"
"io"
"net/http"
"net/http/httptest"
"strings"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -241,3 +243,54 @@ func TestPushMetrics(t *testing.T) {
Headers: []string{"Foo: Bar", "baz:aaaa-bbb"},
}, "Baz: aaaa-bbb\r\nContent-Encoding: gzip\r\nContent-Type: text/plain\r\nFoo: Bar\r\n", "bar 42.12\nfoo 1234\n")
}

func TestCustomClientWithTLSConfig(t *testing.T) {
// Create a TLS configuration that accepts self-signed cert
Copy link

Copilot AI Jul 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The comment should use 'certificates' instead of 'cert' for proper grammar.

Suggested change
// Create a TLS configuration that accepts self-signed cert
// Create a TLS configuration that accepts self-signed certificate

Copilot uses AI. Check for mistakes.
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
}

// Create a custom client with TLS configuration
customClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
}

// Set up a TLS server that generates a self-signed certificate
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
defer server.Close()

s := NewSet()
c := s.NewCounter("test_tls_counter")
c.Inc()

// Test with properly configured TLS client
opts := &PushOptions{
CustomClient: customClient,
DisableCompression: true,
}

if err := s.PushMetrics(context.Background(), server.URL, opts); err != nil {
t.Fatalf("Push failed with properly configured TLS client: %s", err)
}

// Test with default client
optsNoCustomClient := &PushOptions{
DisableCompression: true,
}

err := s.PushMetrics(context.Background(), server.URL, optsNoCustomClient)
if err == nil {
t.Fatal("Push succeeded with default client, but should have failed due to self-signed certificate")
}

// Verify the error is TLS-related
if !strings.Contains(err.Error(), "certificate") &&
!strings.Contains(err.Error(), "TLS") &&
!strings.Contains(err.Error(), "x509") {
t.Fatalf("Expected TLS certificate error, got: %s", err)
}
}