mirror of https://github.com/status-im/consul.git
feat: support sending body in HTTP checks (#6602)
This commit is contained in:
parent
4f21bbdb4e
commit
8beb716414
|
@ -2911,6 +2911,7 @@ func (a *Agent) addCheck(check *structs.HealthCheck, chkType *structs.CheckType,
|
|||
HTTP: chkType.HTTP,
|
||||
Header: chkType.Header,
|
||||
Method: chkType.Method,
|
||||
Body: chkType.Body,
|
||||
Interval: chkType.Interval,
|
||||
Timeout: chkType.Timeout,
|
||||
Logger: a.logger,
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
osexec "os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
@ -333,6 +334,7 @@ type CheckHTTP struct {
|
|||
HTTP string
|
||||
Header map[string][]string
|
||||
Method string
|
||||
Body string
|
||||
Interval time.Duration
|
||||
Timeout time.Duration
|
||||
Logger hclog.Logger
|
||||
|
@ -355,6 +357,7 @@ func (c *CheckHTTP) CheckType() structs.CheckType {
|
|||
CheckID: c.CheckID.ID,
|
||||
HTTP: c.HTTP,
|
||||
Method: c.Method,
|
||||
Body: c.Body,
|
||||
Header: c.Header,
|
||||
Interval: c.Interval,
|
||||
ProxyHTTP: c.ProxyHTTP,
|
||||
|
@ -435,7 +438,8 @@ func (c *CheckHTTP) check() {
|
|||
target = c.ProxyHTTP
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, target, nil)
|
||||
bodyReader := strings.NewReader(c.Body)
|
||||
req, err := http.NewRequest(method, target, bodyReader)
|
||||
if err != nil {
|
||||
c.StatusHandler.updateCheck(c.CheckID, api.HealthCritical, err.Error())
|
||||
return
|
||||
|
|
|
@ -586,6 +586,74 @@ func TestCheckHTTPTimeout(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestCheckHTTPBody(t *testing.T) {
|
||||
t.Parallel()
|
||||
timeout := 5 * time.Millisecond
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
buf bytes.Buffer
|
||||
body []byte
|
||||
)
|
||||
code := 200
|
||||
if _, err := buf.ReadFrom(r.Body); err != nil {
|
||||
code = 999
|
||||
body = []byte(err.Error())
|
||||
} else {
|
||||
body = buf.Bytes()
|
||||
}
|
||||
|
||||
w.WriteHeader(code)
|
||||
w.Write(body)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
tests := []struct {
|
||||
desc string
|
||||
method string
|
||||
header http.Header
|
||||
body string
|
||||
}{
|
||||
{desc: "get body", method: "GET", body: "hello world"},
|
||||
{desc: "post body", method: "POST", body: "hello world"},
|
||||
{desc: "post json body", header: http.Header{"Content-Type": []string{"application/json"}}, method: "POST", body: "{\"foo\":\"bar\"}"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
notif := mock.NewNotify()
|
||||
|
||||
cid := structs.NewCheckID("checkbody", nil)
|
||||
logger := testutil.Logger(t)
|
||||
check := &CheckHTTP{
|
||||
CheckID: cid,
|
||||
HTTP: server.URL,
|
||||
Header: tt.header,
|
||||
Method: tt.method,
|
||||
Body: tt.body,
|
||||
Timeout: timeout,
|
||||
Interval: 2 * time.Millisecond,
|
||||
Logger: logger,
|
||||
StatusHandler: NewStatusHandler(notif, logger, 0, 0),
|
||||
}
|
||||
check.Start()
|
||||
defer check.Stop()
|
||||
|
||||
retry.Run(t, func(r *retry.R) {
|
||||
if got, want := notif.Updates(cid), 2; got < want {
|
||||
r.Fatalf("got %d updates want at least %d", got, want)
|
||||
}
|
||||
if got, want := notif.State(cid), api.HealthPassing; got != want {
|
||||
r.Fatalf("got status %q want %q", got, want)
|
||||
}
|
||||
if got, want := notif.Output(cid), tt.body; !strings.HasSuffix(got, want) {
|
||||
r.Fatalf("got output %q want suffix %q", got, want)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckHTTP_disablesKeepAlives(t *testing.T) {
|
||||
t.Parallel()
|
||||
notif := mock.NewNotify()
|
||||
|
|
|
@ -1287,6 +1287,7 @@ func (b *Builder) checkVal(v *CheckDefinition) *structs.CheckDefinition {
|
|||
HTTP: b.stringVal(v.HTTP),
|
||||
Header: v.Header,
|
||||
Method: b.stringVal(v.Method),
|
||||
Body: b.stringVal(v.Body),
|
||||
TCP: b.stringVal(v.TCP),
|
||||
Interval: b.durationVal(fmt.Sprintf("check[%s].interval", id), v.Interval),
|
||||
DockerContainerID: b.stringVal(v.DockerContainerID),
|
||||
|
|
|
@ -418,6 +418,7 @@ type CheckDefinition struct {
|
|||
HTTP *string `json:"http,omitempty" hcl:"http" mapstructure:"http"`
|
||||
Header map[string][]string `json:"header,omitempty" hcl:"header" mapstructure:"header"`
|
||||
Method *string `json:"method,omitempty" hcl:"method" mapstructure:"method"`
|
||||
Body *string `json:"body,omitempty" hcl:"body" mapstructure:"body"`
|
||||
OutputMaxSize *int `json:"output_max_size,omitempty" hcl:"output_max_size" mapstructure:"output_max_size"`
|
||||
TCP *string `json:"tcp,omitempty" hcl:"tcp" mapstructure:"tcp"`
|
||||
Interval *string `json:"interval,omitempty" hcl:"interval" mapstructure:"interval"`
|
||||
|
|
|
@ -3738,6 +3738,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"f3r6xFtM": [ "RyuIdDWv", "QbxEcIUM" ]
|
||||
},
|
||||
"method": "Dou0nGT5",
|
||||
"body": "5PBQd2OT",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
"tcp": "JY6fTTcw",
|
||||
"interval": "18714s",
|
||||
|
@ -3763,6 +3764,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"Ui0nU99X": [ "LMccm3Qe", "k5H5RggQ" ]
|
||||
},
|
||||
"method": "aldrIQ4l",
|
||||
"body": "wSjTy7dg",
|
||||
"tcp": "RJQND605",
|
||||
"interval": "22164s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
|
@ -3787,6 +3789,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"qxvdnSE9": [ "6wBPUYdF", "YYh8wtSZ" ]
|
||||
},
|
||||
"method": "gLrztrNw",
|
||||
"body": "0jkKgGUC",
|
||||
"tcp": "4jG5casb",
|
||||
"interval": "28767s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
|
@ -4005,6 +4008,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"l4HwQ112": ["fk56MNlo", "dhLK56aZ"]
|
||||
},
|
||||
"method": "9afLm3Mj",
|
||||
"body": "wVVL2V6f",
|
||||
"tcp": "fjiLFqVd",
|
||||
"interval": "23926s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
|
@ -4028,6 +4032,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"SHOVq1Vv": [ "jntFhyym", "GYJh32pp" ]
|
||||
},
|
||||
"method": "T66MFBfR",
|
||||
"body": "OwGjTFQi",
|
||||
"tcp": "bNnNfx2A",
|
||||
"interval": "22224s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
|
@ -4050,6 +4055,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"p2UI34Qz": [ "UsG1D0Qh", "NHhRiB6s" ]
|
||||
},
|
||||
"method": "ciYHWors",
|
||||
"body": "lUVLGYU7",
|
||||
"tcp": "FfvCwlqH",
|
||||
"interval": "12356s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
|
@ -4086,6 +4092,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"cVFpko4u": ["gGqdEB6k", "9LsRo22u"]
|
||||
},
|
||||
"method": "X5DrovFc",
|
||||
"body": "WeikigLh",
|
||||
"tcp": "ICbxkpSF",
|
||||
"interval": "24392s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
|
@ -4125,6 +4132,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"1UJXjVrT": [ "OJgxzTfk", "xZZrFsq7" ]
|
||||
},
|
||||
"method": "5wkAxCUE",
|
||||
"body": "7CRjCJyz",
|
||||
"tcp": "MN3oA9D2",
|
||||
"interval": "32718s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
|
@ -4147,6 +4155,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"vr7wY7CS": [ "EtCoNPPL", "9vAarJ5s" ]
|
||||
},
|
||||
"method": "wzByP903",
|
||||
"body": "4I8ucZgZ",
|
||||
"tcp": "2exjZIGE",
|
||||
"interval": "5656s",
|
||||
"output_max_size": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
|
@ -4356,6 +4365,7 @@ func TestFullConfig(t *testing.T) {
|
|||
f3r6xFtM = [ "RyuIdDWv", "QbxEcIUM" ]
|
||||
}
|
||||
method = "Dou0nGT5"
|
||||
body = "5PBQd2OT"
|
||||
tcp = "JY6fTTcw"
|
||||
interval = "18714s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
|
@ -4381,6 +4391,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"Ui0nU99X" = [ "LMccm3Qe", "k5H5RggQ" ]
|
||||
}
|
||||
method = "aldrIQ4l"
|
||||
body = "wSjTy7dg"
|
||||
tcp = "RJQND605"
|
||||
interval = "22164s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
|
@ -4405,6 +4416,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"qxvdnSE9" = [ "6wBPUYdF", "YYh8wtSZ" ]
|
||||
}
|
||||
method = "gLrztrNw"
|
||||
body = "0jkKgGUC"
|
||||
tcp = "4jG5casb"
|
||||
interval = "28767s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
|
@ -4627,6 +4639,7 @@ func TestFullConfig(t *testing.T) {
|
|||
l4HwQ112 = [ "fk56MNlo", "dhLK56aZ" ]
|
||||
}
|
||||
method = "9afLm3Mj"
|
||||
body = "wVVL2V6f"
|
||||
tcp = "fjiLFqVd"
|
||||
interval = "23926s"
|
||||
docker_container_id = "dO5TtRHk"
|
||||
|
@ -4649,6 +4662,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"SHOVq1Vv" = [ "jntFhyym", "GYJh32pp" ]
|
||||
}
|
||||
method = "T66MFBfR"
|
||||
body = "OwGjTFQi"
|
||||
tcp = "bNnNfx2A"
|
||||
interval = "22224s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
|
@ -4671,6 +4685,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"p2UI34Qz" = [ "UsG1D0Qh", "NHhRiB6s" ]
|
||||
}
|
||||
method = "ciYHWors"
|
||||
body = "lUVLGYU7"
|
||||
tcp = "FfvCwlqH"
|
||||
interval = "12356s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
|
@ -4707,6 +4722,7 @@ func TestFullConfig(t *testing.T) {
|
|||
cVFpko4u = [ "gGqdEB6k", "9LsRo22u" ]
|
||||
}
|
||||
method = "X5DrovFc"
|
||||
body = "WeikigLh"
|
||||
tcp = "ICbxkpSF"
|
||||
interval = "24392s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
|
@ -4746,6 +4762,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"1UJXjVrT" = [ "OJgxzTfk", "xZZrFsq7" ]
|
||||
}
|
||||
method = "5wkAxCUE"
|
||||
body = "7CRjCJyz"
|
||||
tcp = "MN3oA9D2"
|
||||
interval = "32718s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
|
@ -4768,6 +4785,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"vr7wY7CS" = [ "EtCoNPPL", "9vAarJ5s" ]
|
||||
}
|
||||
method = "wzByP903"
|
||||
body = "4I8ucZgZ"
|
||||
tcp = "2exjZIGE"
|
||||
interval = "5656s"
|
||||
output_max_size = ` + strconv.Itoa(checks.DefaultBufSize) + `
|
||||
|
@ -5071,6 +5089,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"Ui0nU99X": []string{"LMccm3Qe", "k5H5RggQ"},
|
||||
},
|
||||
Method: "aldrIQ4l",
|
||||
Body: "wSjTy7dg",
|
||||
TCP: "RJQND605",
|
||||
Interval: 22164 * time.Second,
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
|
@ -5095,6 +5114,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"qxvdnSE9": []string{"6wBPUYdF", "YYh8wtSZ"},
|
||||
},
|
||||
Method: "gLrztrNw",
|
||||
Body: "0jkKgGUC",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "4jG5casb",
|
||||
Interval: 28767 * time.Second,
|
||||
|
@ -5119,6 +5139,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"f3r6xFtM": {"RyuIdDWv", "QbxEcIUM"},
|
||||
},
|
||||
Method: "Dou0nGT5",
|
||||
Body: "5PBQd2OT",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "JY6fTTcw",
|
||||
Interval: 18714 * time.Second,
|
||||
|
@ -5293,6 +5314,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"cVFpko4u": {"gGqdEB6k", "9LsRo22u"},
|
||||
},
|
||||
Method: "X5DrovFc",
|
||||
Body: "WeikigLh",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "ICbxkpSF",
|
||||
Interval: 24392 * time.Second,
|
||||
|
@ -5342,6 +5364,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"1UJXjVrT": {"OJgxzTfk", "xZZrFsq7"},
|
||||
},
|
||||
Method: "5wkAxCUE",
|
||||
Body: "7CRjCJyz",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "MN3oA9D2",
|
||||
Interval: 32718 * time.Second,
|
||||
|
@ -5364,6 +5387,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"vr7wY7CS": {"EtCoNPPL", "9vAarJ5s"},
|
||||
},
|
||||
Method: "wzByP903",
|
||||
Body: "4I8ucZgZ",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "2exjZIGE",
|
||||
Interval: 5656 * time.Second,
|
||||
|
@ -5478,6 +5502,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"SHOVq1Vv": {"jntFhyym", "GYJh32pp"},
|
||||
},
|
||||
Method: "T66MFBfR",
|
||||
Body: "OwGjTFQi",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "bNnNfx2A",
|
||||
Interval: 22224 * time.Second,
|
||||
|
@ -5500,6 +5525,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"p2UI34Qz": {"UsG1D0Qh", "NHhRiB6s"},
|
||||
},
|
||||
Method: "ciYHWors",
|
||||
Body: "lUVLGYU7",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "FfvCwlqH",
|
||||
Interval: 12356 * time.Second,
|
||||
|
@ -5522,6 +5548,7 @@ func TestFullConfig(t *testing.T) {
|
|||
"l4HwQ112": {"fk56MNlo", "dhLK56aZ"},
|
||||
},
|
||||
Method: "9afLm3Mj",
|
||||
Body: "wVVL2V6f",
|
||||
OutputMaxSize: checks.DefaultBufSize,
|
||||
TCP: "fjiLFqVd",
|
||||
Interval: 23926 * time.Second,
|
||||
|
@ -5972,6 +5999,7 @@ func TestSanitize(t *testing.T) {
|
|||
"ID": "",
|
||||
"Interval": "0s",
|
||||
"Method": "",
|
||||
"Body": "",
|
||||
"Name": "zoo",
|
||||
"Notes": "",
|
||||
"OutputMaxSize": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
|
@ -6155,6 +6183,7 @@ func TestSanitize(t *testing.T) {
|
|||
"Header": {},
|
||||
"Interval": "0s",
|
||||
"Method": "",
|
||||
"Body": "",
|
||||
"Name": "blurb",
|
||||
"Notes": "",
|
||||
"OutputMaxSize": ` + strconv.Itoa(checks.DefaultBufSize) + `,
|
||||
|
|
|
@ -2671,6 +2671,7 @@ func TestDecodeSessionCreate(t *testing.T) {
|
|||
// HTTP string
|
||||
// Header map[string][]string
|
||||
// Method string
|
||||
// Body string
|
||||
// TLSSkipVerify bool
|
||||
// TCP string
|
||||
// IntervalDuration time.Duration
|
||||
|
|
|
@ -26,6 +26,7 @@ type CheckDefinition struct {
|
|||
HTTP string
|
||||
Header map[string][]string
|
||||
Method string
|
||||
Body string
|
||||
TCP string
|
||||
Interval time.Duration
|
||||
DockerContainerID string
|
||||
|
@ -171,6 +172,7 @@ func (c *CheckDefinition) CheckType() *CheckType {
|
|||
GRPCUseTLS: c.GRPCUseTLS,
|
||||
Header: c.Header,
|
||||
Method: c.Method,
|
||||
Body: c.Body,
|
||||
OutputMaxSize: c.OutputMaxSize,
|
||||
TCP: c.TCP,
|
||||
Interval: c.Interval,
|
||||
|
|
|
@ -34,6 +34,7 @@ type CheckType struct {
|
|||
HTTP string
|
||||
Header map[string][]string
|
||||
Method string
|
||||
Body string
|
||||
TCP string
|
||||
Interval time.Duration
|
||||
AliasNode string
|
||||
|
|
|
@ -1318,6 +1318,7 @@ type HealthCheckDefinition struct {
|
|||
TLSSkipVerify bool `json:",omitempty"`
|
||||
Header map[string][]string `json:",omitempty"`
|
||||
Method string `json:",omitempty"`
|
||||
Body string `json:",omitempty"`
|
||||
TCP string `json:",omitempty"`
|
||||
Interval time.Duration `json:",omitempty"`
|
||||
OutputMaxSize uint `json:",omitempty"`
|
||||
|
@ -1463,6 +1464,7 @@ func (c *HealthCheck) CheckType() *CheckType {
|
|||
GRPCUseTLS: c.Definition.GRPCUseTLS,
|
||||
Header: c.Definition.Header,
|
||||
Method: c.Definition.Method,
|
||||
Body: c.Definition.Body,
|
||||
TCP: c.Definition.TCP,
|
||||
Interval: c.Definition.Interval,
|
||||
DockerContainerID: c.Definition.DockerContainerID,
|
||||
|
|
|
@ -240,6 +240,7 @@ func (s *HTTPServer) convertOps(resp http.ResponseWriter, req *http.Request) (st
|
|||
TLSSkipVerify: check.Definition.TLSSkipVerify,
|
||||
Header: check.Definition.Header,
|
||||
Method: check.Definition.Method,
|
||||
Body: check.Definition.Body,
|
||||
TCP: check.Definition.TCP,
|
||||
Interval: interval,
|
||||
Timeout: timeout,
|
||||
|
|
|
@ -190,6 +190,7 @@ type AgentServiceCheck struct {
|
|||
HTTP string `json:",omitempty"`
|
||||
Header map[string][]string `json:",omitempty"`
|
||||
Method string `json:",omitempty"`
|
||||
Body string `json:",omitempty"`
|
||||
TCP string `json:",omitempty"`
|
||||
Status string `json:",omitempty"`
|
||||
Notes string `json:",omitempty"`
|
||||
|
|
|
@ -51,6 +51,7 @@ type HealthCheckDefinition struct {
|
|||
HTTP string
|
||||
Header map[string][]string
|
||||
Method string
|
||||
Body string
|
||||
TLSSkipVerify bool
|
||||
TCP string
|
||||
IntervalDuration time.Duration `json:"-"`
|
||||
|
|
|
@ -176,6 +176,8 @@ The table below shows this endpoint's support for
|
|||
- `Method` `(string: "")` - Specifies a different HTTP method to be used
|
||||
for an `HTTP` check. When no value is specified, `GET` is used.
|
||||
|
||||
- `Body` `(string: "")` - Specifies a body that should be sent with `HTTP` checks.
|
||||
|
||||
- `Header` `(map[string][]string: {})` - Specifies a set of headers that should
|
||||
be set for `HTTP` checks. Each header can have multiple values.
|
||||
|
||||
|
@ -221,7 +223,8 @@ The table below shows this endpoint's support for
|
|||
"Shell": "/bin/bash",
|
||||
"HTTP": "https://example.com",
|
||||
"Method": "POST",
|
||||
"Header": {"x-foo":["bar", "baz"]},
|
||||
"Header": {"Content-Type": "application/json"},
|
||||
"Body": "{\"check\":\"mem\"}",
|
||||
"TCP": "example.com:22",
|
||||
"Interval": "10s",
|
||||
"Timeout": "5s",
|
||||
|
|
|
@ -156,7 +156,8 @@ A HTTP check:
|
|||
"http": "https://localhost:5000/health",
|
||||
"tls_skip_verify": false,
|
||||
"method": "POST",
|
||||
"header": {"x-foo":["bar", "baz"]},
|
||||
"header": {"Content-Type": "application/json"},
|
||||
"body": "{\"method\":\"health\"}",
|
||||
"interval": "10s",
|
||||
"timeout": "1s"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue