cscli: Add user-agent to all hub requests (#2915)

* cscli: Add user-agent to all hub requests

* fix unit test and avoid httpmock

* fix windows test
This commit is contained in:
mmetc 2024-03-25 10:40:41 +01:00 committed by GitHub
parent 52f86c2d10
commit 2e1ddec107
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 26 deletions

View file

@ -7,10 +7,24 @@ import (
"sort" "sort"
"strings" "strings"
"time" "time"
"github.com/crowdsecurity/go-cs-lib/version"
) )
// hubTransport wraps a Transport to set a custom User-Agent.
type hubTransport struct {
http.RoundTripper
}
func (t *hubTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req.Header.Set("User-Agent", "crowdsec/"+version.String())
return t.RoundTripper.RoundTrip(req)
}
// hubClient is the HTTP client used to communicate with the CrowdSec Hub.
var hubClient = &http.Client{ var hubClient = &http.Client{
Timeout: 120 * time.Second, Timeout: 120 * time.Second,
Transport: &hubTransport{http.DefaultTransport},
} }
// safePath returns a joined path and ensures that it does not escape the base directory. // safePath returns a joined path and ensures that it does not escape the base directory.

View file

@ -1,50 +1,56 @@
package cwhub package cwhub
import ( import (
"io"
"net/http"
"net/http/httptest"
"os" "os"
"path/filepath"
"testing" "testing"
"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/crowdsecurity/go-cs-lib/cstest"
) )
func TestDownloadFile(t *testing.T) { func TestDownloadFile(t *testing.T) {
examplePath := "./example.txt" ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer os.Remove(examplePath) switch r.URL.Path {
case "/xx":
w.WriteHeader(http.StatusOK)
_, _ = io.WriteString(w, "example content oneoneone")
default:
w.WriteHeader(http.StatusNotFound)
_, _ = io.WriteString(w, "not found")
}
}))
defer ts.Close()
httpmock.Activate() dest := filepath.Join(t.TempDir(), "example.txt")
defer httpmock.DeactivateAndReset() defer os.Remove(dest)
// OK err := downloadFile(ts.URL+"/xx", dest)
httpmock.RegisterResponder(
"GET",
"https://example.com/xx",
httpmock.NewStringResponder(200, "example content oneoneone"),
)
httpmock.RegisterResponder(
"GET",
"https://example.com/x",
httpmock.NewStringResponder(404, "not found"),
)
err := downloadFile("https://example.com/xx", examplePath)
require.NoError(t, err) require.NoError(t, err)
content, err := os.ReadFile(examplePath) content, err := os.ReadFile(dest)
assert.Equal(t, "example content oneoneone", string(content)) assert.Equal(t, "example content oneoneone", string(content))
require.NoError(t, err) require.NoError(t, err)
// bad uri // bad uri
err = downloadFile("https://zz.com", examplePath) err = downloadFile("https://zz.com", dest)
require.Error(t, err) cstest.RequireErrorContains(t, err, "lookup zz.com")
cstest.RequireErrorContains(t, err, "no such host")
// 404 // 404
err = downloadFile("https://example.com/x", examplePath) err = downloadFile(ts.URL+"/x", dest)
require.Error(t, err) cstest.RequireErrorContains(t, err, "bad http code 404")
// bad target // bad target
err = downloadFile("https://example.com/xx", "") err = downloadFile(ts.URL+"/xx", "")
require.Error(t, err) cstest.RequireErrorContains(t, err, cstest.PathNotFoundMessage)
// destination directory does not exist
err = downloadFile(ts.URL+"/xx", filepath.Join(t.TempDir(), "missing/example.txt"))
cstest.RequireErrorContains(t, err, cstest.PathNotFoundMessage)
} }