diff --git a/CHANGELOG.md b/CHANGELOG.md index b268bdc443a3..faff9f9f4814 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,8 @@ Main (unreleased) - Allow defining `HTTPClientConfig` for `discovery.ec2`. (@cmbrad) +- The `remote.http` component can optionally define a request body. (@tpaschalis) + ### Bugfixes - Update `pyroscope.ebpf` to fix a logical bug causing to profile to many kthreads instead of regular processes https://github.com/grafana/pyroscope/pull/2778 (@korniltsev) diff --git a/component/remote/http/http.go b/component/remote/http/http.go index c45833ba81df..254f8f90f3c3 100644 --- a/component/remote/http/http.go +++ b/component/remote/http/http.go @@ -41,6 +41,7 @@ type Arguments struct { Method string `river:"method,attr,optional"` Headers map[string]string `river:"headers,attr,optional"` + Body string `river:"body,attr,optional"` Client common_config.HTTPClientConfig `river:"client,block,optional"` } @@ -193,7 +194,12 @@ func (c *Component) pollError() error { ctx, cancel := context.WithTimeout(context.Background(), c.args.PollTimeout) defer cancel() - req, err := http.NewRequest(c.args.Method, c.args.URL, nil) + var body io.Reader + if c.args.Body != "" { + body = strings.NewReader(c.args.Body) + } + + req, err := http.NewRequest(c.args.Method, c.args.URL, body) if err != nil { level.Error(c.log).Log("msg", "failed to build request", "err", err) return fmt.Errorf("building request: %w", err) diff --git a/component/remote/http/http_test.go b/component/remote/http/http_test.go index f8ef2214394f..e59d7c6e74c9 100644 --- a/component/remote/http/http_test.go +++ b/component/remote/http/http_test.go @@ -3,6 +3,7 @@ package http_test import ( "context" "fmt" + "io" "net/http" "net/http/httptest" "sync" @@ -27,6 +28,9 @@ func Test(t *testing.T) { defer srv.Close() handler.SetHandler(func(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + require.NoError(t, err) + require.Equal(t, string(b), "hello there!") fmt.Fprintln(w, "Hello, world!") }) @@ -40,10 +44,11 @@ func Test(t *testing.T) { "x-custom" = "value", "User-Agent" = "custom_useragent", } + body = "%s" poll_frequency = "50ms" poll_timeout = "25ms" - `, srv.URL, http.MethodPut) + `, srv.URL, http.MethodPut, "hello there!") var args http_component.Arguments require.NoError(t, river.Unmarshal([]byte(cfg), &args)) diff --git a/docs/sources/flow/reference/components/remote.http.md b/docs/sources/flow/reference/components/remote.http.md index 1060ff78b54d..7428cb62d18d 100644 --- a/docs/sources/flow/reference/components/remote.http.md +++ b/docs/sources/flow/reference/components/remote.http.md @@ -37,6 +37,7 @@ Name | Type | Description | Default | Required `url` | `string` | URL to poll. | | yes `method` | `string` | Define HTTP method for the request | `"GET"` | no `headers` | `map(string)` | Custom headers for the request. | `{}` | no +`body` | `string` | The request body. | `""` | no `poll_frequency` | `duration` | Frequency to poll the URL. | `"1m"` | no `poll_timeout` | `duration` | Timeout when polling the URL. | `"10s"` | no `is_secret` | `bool` | Whether the response body should be treated as a secret. | false | no