Skip to content

Commit 2e0c462

Browse files
committed
Bugfix v2: Return proper error content type. (elastic#1516)
fixes elastic#1514
1 parent 02e8ffb commit 2e0c462

File tree

3 files changed

+40
-21
lines changed

3 files changed

+40
-21
lines changed

beater/common_handlers.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -443,11 +443,7 @@ func processRequest(r *http.Request, p processor.Processor, config transform.Con
443443
}
444444

445445
func sendStatus(w http.ResponseWriter, r *http.Request, res serverResponse) {
446-
contentType := "text/plain; charset=utf-8"
447-
if acceptsJSON(r) {
448-
contentType = "application/json"
449-
}
450-
w.Header().Set("Content-Type", contentType)
446+
setContentType(w, r)
451447
w.WriteHeader(res.code)
452448

453449
responseCounter.Inc()
@@ -478,6 +474,14 @@ func sendStatus(w http.ResponseWriter, r *http.Request, res serverResponse) {
478474
}
479475
}
480476

477+
func setContentType(w http.ResponseWriter, r *http.Request) {
478+
contentType := "text/plain; charset=utf-8"
479+
if acceptsJSON(r) {
480+
contentType = "application/json"
481+
}
482+
w.Header().Set("Content-Type", contentType)
483+
}
484+
481485
func acceptsJSON(r *http.Request) bool {
482486
h := r.Header.Get("Accept")
483487
return strings.Contains(h, "*/*") || strings.Contains(h, "application/json")

beater/v2_handler.go

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,37 +77,48 @@ func (v *v2Handler) statusCode(sr *stream.Result) (int, *monitoring.Int) {
7777
return highestCode, monitoringCt
7878
}
7979

80-
func (v *v2Handler) sendResponse(logger *logp.Logger, w http.ResponseWriter, sr *stream.Result) {
80+
func (v *v2Handler) sendResponse(logger *logp.Logger, w http.ResponseWriter, r *http.Request, sr *stream.Result) {
8181
statusCode, counter := v.statusCode(sr)
8282
responseCounter.Inc()
8383
counter.Inc()
8484

85-
w.WriteHeader(statusCode)
8685
if statusCode != http.StatusAccepted {
8786
responseErrors.Inc()
8887
// this signals to the client that we're closing the connection
8988
// but also signals to http.Server that it should close it:
9089
// https://golang.org/src/net/http/server.go#L1254
9190
w.Header().Add("Connection", "Close")
92-
w.Header().Add("Content-Type", "application/json")
93-
buf, err := json.Marshal(sr)
94-
if err != nil {
95-
logger.Errorw("error sending response", "error", err)
91+
setContentType(w, r)
92+
w.WriteHeader(statusCode)
93+
94+
var err error
95+
var buf []byte
96+
if acceptsJSON(r) {
97+
buf, err = json.Marshal(sr)
98+
if err != nil {
99+
logger.Errorw("error sending response", "error", err)
100+
}
101+
} else {
102+
buf = []byte(sr.String())
96103
}
97-
_, err = w.Write(buf)
98-
if err != nil {
99-
logger.Errorw("error sending response", "error", err)
104+
105+
if buf != nil {
106+
_, err = w.Write(buf)
107+
if err != nil {
108+
logger.Errorw("error sending response", "error", err)
109+
}
100110
}
101111
logger.Infow("error handling request", "error", sr.String())
102112
} else {
113+
w.WriteHeader(statusCode)
103114
responseSuccesses.Inc()
104115
}
105116
}
106117

107-
func (v *v2Handler) sendError(logger *logp.Logger, w http.ResponseWriter, err *stream.Error) {
118+
func (v *v2Handler) sendError(logger *logp.Logger, w http.ResponseWriter, r *http.Request, err *stream.Error) {
108119
sr := stream.Result{}
109120
sr.Add(err)
110-
v.sendResponse(logger, w, &sr)
121+
v.sendResponse(logger, w, r, &sr)
111122
return
112123
}
113124

@@ -158,19 +169,19 @@ func (v *v2Handler) Handle(beaterConfig *Config, report publish.Reporter) http.H
158169

159170
serr := v.validateRequest(r)
160171
if serr != nil {
161-
v.sendError(logger, w, serr)
172+
v.sendError(logger, w, r, serr)
162173
return
163174
}
164175

165176
rl, serr := v.rateLimit(r)
166177
if serr != nil {
167-
v.sendError(logger, w, serr)
178+
v.sendError(logger, w, r, serr)
168179
return
169180
}
170181

171182
reader, serr := v.bodyReader(r)
172183
if serr != nil {
173-
v.sendError(logger, w, serr)
184+
v.sendError(logger, w, r, serr)
174185
return
175186
}
176187

@@ -179,11 +190,11 @@ func (v *v2Handler) Handle(beaterConfig *Config, report publish.Reporter) http.H
179190
if err != nil {
180191
sr := stream.Result{}
181192
sr.Add(err)
182-
v.sendResponse(logger, w, &sr)
193+
v.sendResponse(logger, w, r, &sr)
183194
return
184195
}
185196
res := v.streamProcessor.HandleStream(r.Context(), rl, reqMeta, reader, report)
186197

187-
v.sendResponse(logger, w, res)
198+
v.sendResponse(logger, w, r, res)
188199
})
189200
}

beater/v2_handler_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ func TestInvalidContentType(t *testing.T) {
4848
handler.ServeHTTP(w, req)
4949

5050
assert.Equal(t, http.StatusBadRequest, w.Code, w.Body.String())
51+
assert.Equal(t, "invalid content type: ''", w.Body.String())
52+
assert.Equal(t, "text/plain; charset=utf-8", w.Header().Get("Content-Type"))
5153
}
5254

5355
func TestEmptyRequest(t *testing.T) {
@@ -173,6 +175,7 @@ func sendReq(c *Config, route *v2Route, url string, p string, repErr error) (*ht
173175
}
174176
req := httptest.NewRequest("POST", url, bytes.NewBuffer(b))
175177
req.Header.Add("Content-Type", "application/x-ndjson")
178+
req.Header.Add("Accept", "application/json")
176179

177180
report := func(context.Context, publish.PendingReq) error {
178181
return repErr
@@ -233,6 +236,7 @@ func TestV2LineExceeded(t *testing.T) {
233236

234237
req = httptest.NewRequest("POST", "/v2/intake", bytes.NewBuffer(b))
235238
req.Header.Add("Content-Type", "application/x-ndjson")
239+
req.Header.Add("Accept", "*/*")
236240
w = httptest.NewRecorder()
237241

238242
ct := requestTooLargeCounter.Get()

0 commit comments

Comments
 (0)