feat(inputs.http_response): Add body form option (#14189)

This commit is contained in:
Joshua Powers 2023-10-30 02:06:22 -06:00 committed by GitHub
parent 38b8a1bcde
commit 62f66fb2e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 0 deletions

View File

@ -54,6 +54,12 @@ to use them.
# {'fake':'data'}
# '''
## Optional HTTP Request Body Form
## Key value pairs to encode and set at URL form. Can be used with the POST
## method + application/x-www-form-urlencoded content type to replicate the
## POSTFORM method.
# body_form = { "key": "value" }
## Optional name of the field that will contain the body of the response.
## By default it is set to an empty String indicating that the body's
## content won't be added

View File

@ -38,6 +38,7 @@ type HTTPResponse struct {
URLs []string `toml:"urls"`
HTTPProxy string `toml:"http_proxy"`
Body string
BodyForm map[string][]string `toml:"body_form"`
Method string
ResponseTimeout config.Duration
HTTPHeaderTags map[string]string `toml:"http_header_tags"`
@ -193,7 +194,16 @@ func (h *HTTPResponse) httpGather(u string) (map[string]interface{}, map[string]
var body io.Reader
if h.Body != "" {
body = strings.NewReader(h.Body)
} else if len(h.BodyForm) != 0 {
values := url.Values{}
for k, vs := range h.BodyForm {
for _, v := range vs {
values.Add(k, v)
}
}
body = strings.NewReader(values.Encode())
}
request, err := http.NewRequest(h.Method, u, body)
if err != nil {
return nil, nil, err

View File

@ -98,6 +98,20 @@ func setUpTestMux() http.Handler {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
fmt.Fprintf(w, "hit the good page!")
})
mux.HandleFunc("/form", func(w http.ResponseWriter, req *http.Request) {
body, err := io.ReadAll(req.Body)
defer req.Body.Close()
if err != nil {
http.Error(w, "couldn't read request body", http.StatusBadRequest)
return
}
if string(body) != "list=foobar&list=fizbuzz&test=42" {
fmt.Println(string(body))
w.WriteHeader(http.StatusBadRequest)
} else {
w.WriteHeader(http.StatusOK)
}
})
mux.HandleFunc("/invalidUTF8", func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte{0xff, 0xfe, 0xfd}) //nolint:errcheck // ignore the returned error as the test will fail anyway
})
@ -314,6 +328,46 @@ func TestResponseBodyField(t *testing.T) {
checkOutput(t, &acc, expectedFields, expectedTags, nil, nil)
}
func TestResponseBodyFormField(t *testing.T) {
mux := setUpTestMux()
ts := httptest.NewServer(mux)
defer ts.Close()
h := &HTTPResponse{
Log: testutil.Logger{},
URLs: []string{ts.URL + "/form"},
BodyForm: map[string][]string{
"test": {"42"},
"list": {"foobar", "fizbuzz"},
},
Method: "POST",
Headers: map[string]string{
"Content-Type": "application/x-www-form-urlencoded",
},
ResponseTimeout: config.Duration(time.Second * 20),
ResponseBodyField: "my_body_field",
}
var acc testutil.Accumulator
require.NoError(t, h.Gather(&acc))
expectedFields := map[string]interface{}{
"http_response_code": http.StatusOK,
"result_type": "success",
"result_code": 0,
"response_time": nil,
"content_length": nil,
"my_body_field": "",
}
expectedTags := map[string]interface{}{
"server": nil,
"method": "POST",
"status_code": "200",
"result": "success",
}
checkOutput(t, &acc, expectedFields, expectedTags, nil, nil)
}
func TestResponseBodyMaxSize(t *testing.T) {
mux := setUpTestMux()
ts := httptest.NewServer(mux)

View File

@ -29,6 +29,12 @@
# {'fake':'data'}
# '''
## Optional HTTP Request Body Form
## Key value pairs to encode and set at URL form. Can be used with the POST
## method + application/x-www-form-urlencoded content type to replicate the
## POSTFORM method.
# body_form = { "key": "value" }
## Optional name of the field that will contain the body of the response.
## By default it is set to an empty String indicating that the body's
## content won't be added