Merge pull request #1952 from hashicorp/b-http-buf

Apply a 4K limit to the output size for HTTP checks
This commit is contained in:
Ryan Uber 2016-04-14 15:53:14 -07:00
commit 85a8f7c906
3 changed files with 22 additions and 9 deletions

View File

@ -2,7 +2,7 @@ package agent
import ( import (
"fmt" "fmt"
"io/ioutil" "io"
"log" "log"
"net" "net"
"net/http" "net/http"
@ -423,13 +423,14 @@ func (c *CheckHTTP) check() {
} }
defer resp.Body.Close() defer resp.Body.Close()
// Format the response body // Read the response into a circular buffer to limit the size
body, err := ioutil.ReadAll(resp.Body) output, _ := circbuf.NewBuffer(CheckBufSize)
if err != nil { if _, err := io.Copy(output, resp.Body); err != nil {
c.Logger.Printf("[WARN] agent: check '%v': Get error while reading body: %s", c.CheckID, err) c.Logger.Printf("[WARN] agent: check '%v': Get error while reading body: %s", c.CheckID, err)
body = []byte{}
} }
result := fmt.Sprintf("HTTP GET %s: %s Output: %s", c.HTTP, resp.Status, body)
// Format the response body
result := fmt.Sprintf("HTTP GET %s: %s Output: %s", c.HTTP, resp.Status, output.String())
if resp.StatusCode >= 200 && resp.StatusCode <= 299 { if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
// PASSING (2xx) // PASSING (2xx)

View File

@ -1,6 +1,7 @@
package agent package agent
import ( import (
"bytes"
"errors" "errors"
"fmt" "fmt"
"log" "log"
@ -186,7 +187,10 @@ func TestCheckTTL(t *testing.T) {
func mockHTTPServer(responseCode int) *httptest.Server { func mockHTTPServer(responseCode int) *httptest.Server {
mux := http.NewServeMux() mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Body larger than 4k limit
body := bytes.Repeat([]byte{'a'}, 2*CheckBufSize)
w.WriteHeader(responseCode) w.WriteHeader(responseCode)
w.Write(body)
return return
}) })
@ -219,6 +223,11 @@ func expectHTTPStatus(t *testing.T, url string, status string) {
if mock.state["foo"] != status { if mock.state["foo"] != status {
t.Fatalf("should be %v %v", status, mock.state) t.Fatalf("should be %v %v", status, mock.state)
} }
// Allow slightly more data than CheckBufSize, for the header
if n := len(mock.output["foo"]); n > (CheckBufSize + 256) {
t.Fatalf("output too long: %d (%d-byte limit)", n, CheckBufSize)
}
} }
func TestCheckHTTPCritical(t *testing.T) { func TestCheckHTTPCritical(t *testing.T) {

View File

@ -20,7 +20,8 @@ There are five different kinds of checks:
* Script + Interval - These checks depend on invoking an external application * Script + Interval - These checks depend on invoking an external application
that performs the health check, exits with an appropriate exit code, and potentially that performs the health check, exits with an appropriate exit code, and potentially
generates some output. A script is paired with an invocation interval (e.g. generates some output. A script is paired with an invocation interval (e.g.
every 30 seconds). This is similar to the Nagios plugin system. every 30 seconds). This is similar to the Nagios plugin system. The output of
a script check is limited to 4K. Output larger than this will be truncated.
* HTTP + Interval - These checks make an HTTP `GET` request every Interval (e.g. * HTTP + Interval - These checks make an HTTP `GET` request every Interval (e.g.
every 30 seconds) to the specified URL. The status of the service depends on the HTTP response code: every 30 seconds) to the specified URL. The status of the service depends on the HTTP response code:
@ -29,7 +30,8 @@ There are five different kinds of checks:
to check a simple HTTP operation. By default, HTTP checks will be configured to check a simple HTTP operation. By default, HTTP checks will be configured
with a request timeout equal to the check interval, with a max of 10 seconds. with a request timeout equal to the check interval, with a max of 10 seconds.
It is possible to configure a custom HTTP check timeout value by specifying It is possible to configure a custom HTTP check timeout value by specifying
the `timeout` field in the check definition. the `timeout` field in the check definition. The output of the check is
limited to roughly 4K. Responses larger than this will be truncated.
* TCP + Interval - These checks make an TCP connection attempt every Interval * TCP + Interval - These checks make an TCP connection attempt every Interval
(e.g. every 30 seconds) to the specified IP/hostname and port. The status of (e.g. every 30 seconds) to the specified IP/hostname and port. The status of
@ -68,7 +70,8 @@ determine the Docker API endpoint. The application is expected to run, perform a
check of the service running inside the container, and exit with an appropriate exit code. check of the service running inside the container, and exit with an appropriate exit code.
The check should be paired with an invocation interval. The shell on which the check The check should be paired with an invocation interval. The shell on which the check
has to be performed is configurable which makes it possible to run containers which has to be performed is configurable which makes it possible to run containers which
have different shells on the same host. have different shells on the same host. Check output for Docker is limited to
4K. Any output larger than this will be truncated.
## Check Definition ## Check Definition