[ 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> ]
```
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"`
s.HTTPClientConfig.FollowRedirects = !*s.NoFollowRedirects
}
+ if s.Body != "" && s.BodyFile != "" {
+ return errors.New("setting body and body_file both are not allowed")
+ }
+
for key, value := range s.Headers {
switch textproto.CanonicalMIMEHeaderKey(key) {
case "Accept-Encoding":
input: "testdata/invalid-tcp-query-response-regexp.yml",
want: `error parsing config file: "Could not compile regular expression" regexp=":["`,
},
+ {
+ input: "testdata/invalid-http-body-config.yml",
+ want: `error parsing config file: setting body and body_file both are not allowed`,
+ },
}
for _, test := range tests {
t.Run(test.input, func(t *testing.T) {
--- /dev/null
+modules:
+ http_test:
+ prober: http
+ timeout: 5s
+ http:
+ body: "Test body"
+ body_file: "test_body.txt"
headers:
Content-Type: application/json
body: '{}'
+ http_post_body_file:
+ prober: http
+ timeout: 5s
+ http:
+ method: POST
+ body_file: "/files/body.txt"
http_basic_auth_example:
prober: http
timeout: 5s
"net/http/httptrace"
"net/textproto"
"net/url"
+ "os"
"strconv"
"strings"
"sync"
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)
"crypto/x509"
"encoding/pem"
"fmt"
+ "io"
"net/http"
"net/http/httptest"
"net/textproto"
checkMetrics(expectedMetrics, mfs, t)
})
}
+
+func TestBody(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)
+ }
+
+ tests := []config.HTTPProbe{
+ {IPProtocolFallback: true, Body: body},
+ {IPProtocolFallback: true, BodyFile: tmpBodyFile.Name()},
+ }
+
+ for i, test := range tests {
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ b, err := io.ReadAll(r.Body)
+ if err != nil {
+ t.Fatalf("Body test %d failed unexpectedly.", i)
+ }
+ if string(b) != body {
+ t.Fatalf("Body test %d failed unexpectedly.", i)
+ }
+ }))
+ 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: test},
+ registry,
+ log.NewNopLogger(),
+ )
+ if !result {
+ t.Fatalf("Body test %d failed unexpectedly.", i)
+ }
+ }
+}