Skip to content

Commit

Permalink
Add support for HTTP request body as file
Browse files Browse the repository at this point in the history
Resolves #391
  • Loading branch information
danteu committed Nov 14, 2022
1 parent 037af75 commit 47c6ae5
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 1 deletion.
6 changes: 5 additions & 1 deletion CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ The other placeholders are specified separately.
[ ip_protocol_fallback: <boolean> | default = true ]

# The body of the HTTP request used in probe.
body: [ <string> ]
[ body: <string> ]

# Read the HTTP request body from from a file.
# It is mutually exclusive with `body`.
[ body_file: <filename> ]

```

Expand Down
5 changes: 5 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ type HTTPProbe struct {
FailIfHeaderMatchesRegexp []HeaderMatch `yaml:"fail_if_header_matches,omitempty"`
FailIfHeaderNotMatchesRegexp []HeaderMatch `yaml:"fail_if_header_not_matches,omitempty"`
Body string `yaml:"body,omitempty"`
BodyFile string `yaml:"body_file,omitempty"`
HTTPClientConfig config.HTTPClientConfig `yaml:"http_client_config,inline"`
Compression string `yaml:"compression,omitempty"`
BodySizeLimit units.Base2Bytes `yaml:"body_size_limit,omitempty"`
Expand Down Expand Up @@ -330,6 +331,10 @@ func (s *HTTPProbe) UnmarshalYAML(unmarshal func(interface{}) error) error {
s.HTTPClientConfig.FollowRedirects = !*s.NoFollowRedirects
}

if s.Body != "" && s.BodyFile != "" {
return errors.New("body and body_file must not both be set")
}

for key, value := range s.Headers {
switch textproto.CanonicalMIMEHeaderKey(key) {
case "Accept-Encoding":
Expand Down
12 changes: 12 additions & 0 deletions prober/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"net/http/httptrace"
"net/textproto"
"net/url"
"os"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -408,6 +409,17 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr
body = strings.NewReader(httpConfig.Body)
}

// If a body file is configured, add its content to the request.
if httpConfig.BodyFile != "" {
body_file, err := os.Open(httpConfig.BodyFile)
if err != nil {
level.Error(logger).Log("msg", "Error creating request", "err", err)
return
}
defer body_file.Close()
body = body_file
}

request, err := http.NewRequest(httpConfig.Method, targetURL.String(), body)
if err != nil {
level.Error(logger).Log("msg", "Error creating request", "err", err)
Expand Down
36 changes: 36 additions & 0 deletions prober/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1431,3 +1431,39 @@ func TestBody(t *testing.T) {
t.Fatalf("Body test failed unexpectedly.")
}
}

func TestBodyFile(t *testing.T) {
body := "Test Body"
tmpBodyFile, err := os.CreateTemp("", "body.txt")
if err != nil {
t.Fatalf("Error creating body tempfile: %s", err)
}
if _, err := tmpBodyFile.Write([]byte(body)); err != nil {
t.Fatalf("Error writing body tempfile: %s", err)
}
if err := tmpBodyFile.Close(); err != nil {
t.Fatalf("Error closing body tempfie: %s", err)
}

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
b, err := ioutil.ReadAll(r.Body)
if err != nil {
t.Fatalf("Body file test failed unexpectedly.")
}
if string(b) != body {
t.Fatalf("Body file test failed unexpectedly.")
}
}))
defer ts.Close()

registry := prometheus.NewRegistry()
testCTX, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
result := ProbeHTTP(testCTX, ts.URL, config.Module{Timeout: time.Second, HTTP: config.HTTPProbe{
IPProtocolFallback: true,
BodyFile: tmpBodyFile.Name(),
}}, registry, log.NewNopLogger())
if !result {
t.Fatalf("Body file test failed unexpectedly.")
}
}

0 comments on commit 47c6ae5

Please sign in to comment.