From d2f75a3040e72562ffa825d5c3efa7004af2640a Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Thu, 4 Sep 2014 12:02:52 -0700 Subject: [PATCH] Fix line delimited JSON response For GET /events, line delimit JSON. Fixes #7047 Signed-off-by: Jessica Frazelle Docker-DCO-1.1-Signed-off-by: Jessica Frazelle (github: ) --- api/server/server.go | 2 + events/events.go | 5 ++ integration-cli/docker_api_events_test.go | 57 +++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 integration-cli/docker_api_events_test.go diff --git a/api/server/server.go b/api/server/server.go index ece602160a..ea708bc6e9 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -278,6 +278,8 @@ func getEvents(eng *engine.Engine, version version.Version, w http.ResponseWrite } var job = eng.Job("events") + // lineDelimited JSON events was added #7047 + job.SetenvBool("lineDelim", version.GreaterThanOrEqualTo("1.15")) streamJSON(job, w, true) job.Setenv("since", r.Form.Get("since")) job.Setenv("until", r.Form.Get("until")) diff --git a/events/events.go b/events/events.go index 57a82cada0..7c32cdb22d 100644 --- a/events/events.go +++ b/events/events.go @@ -101,6 +101,11 @@ func writeEvent(job *engine.Job, event *utils.JSONMessage) error { // When sending an event JSON serialization errors are ignored, but all // other errors lead to the eviction of the listener. if b, err := json.Marshal(event); err == nil { + + if job.GetenvBool("lineDelim") { + b = append(b, []byte("\r\n")...) + } + if _, err = job.Stdout.Write(b); err != nil { return err } diff --git a/integration-cli/docker_api_events_test.go b/integration-cli/docker_api_events_test.go new file mode 100644 index 0000000000..de375bd93c --- /dev/null +++ b/integration-cli/docker_api_events_test.go @@ -0,0 +1,57 @@ +package main + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "testing" + "time" +) + +func TestGetEventsLineDelim(t *testing.T) { + name := "testimageevents" + defer deleteImages(name) + _, err := buildImage(name, + `FROM scratch + MAINTAINER "docker"`, + true) + if err != nil { + t.Fatal(err) + } + if err := deleteImages(name); err != nil { + t.Fatal(err) + } + + endpoint := fmt.Sprintf("/events?since=1&until=%d", time.Now().Unix()) + body, err := sockRequest("GET", endpoint) + if err != nil { + t.Fatal(err) + } + + linesRead := 0 + scanner := bufio.NewScanner(bytes.NewReader(body)) + for scanner.Scan() && linesRead < 2 { + line := scanner.Bytes() + if len(line) == 0 { + continue + } + + // make sure line delimited json + res := make(map[string]interface{}) + if err := json.Unmarshal(line, &res); err != nil { + t.Fatalf("Unmarshaling the line as JSON failed: %v", err) + } + + linesRead++ + } + if err := scanner.Err(); err != nil { + t.Fatalf("Scanner failed: %v", err) + } + + if linesRead < 2 { + t.Fatalf("Only %d lines were read from the stream", linesRead) + } + + logDone("events - test the api response is line delimited json") +}