From 7e089b6bafe76506c1370c1d3640da4ccfd64916 Mon Sep 17 00:00:00 2001 From: dbemiller <27972385+dbemiller@users.noreply.github.com> Date: Mon, 4 Dec 2017 16:33:39 -0500 Subject: [PATCH] Stop encoding HTML (#236) * Fixed the encoding bug. * Added newline. --- endpoints/openrtb2/auction.go | 17 ++++++++++------- endpoints/openrtb2/auction_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 4cc7721e762..2346c0a45c2 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -11,6 +11,7 @@ import ( "errors" "github.com/prebid/prebid-server/openrtb_ext" "time" + "github.com/golang/glog" ) func NewEndpoint(ex exchange.Exchange, validator openrtb_ext.BidderParamValidator) (httprouter.Handle, error) { @@ -46,14 +47,16 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http return } - responseBytes, err := json.Marshal(response) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "Failed to marshal auction response: %v", err) - } + // Fixes #231 + enc := json.NewEncoder(w) + enc.SetEscapeHTML(false) - w.WriteHeader(200) - w.Write(responseBytes) + // If an error happens when encoding the response, there isn't much we can do. + // If we've sent _any_ bytes, then Go would have sent the 200 status code first. + // That status code can't be un-sent... so the best we can do is log the error. + if err := enc.Encode(response); err != nil { + glog.Errorf("/openrtb2/auction Error encoding response: %v", err) + } } // parseRequest turns the HTTP request into an OpenRTB request. diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index c83cd6f81eb..a2dae855d38 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -86,6 +86,19 @@ func TestExchangeError(t *testing.T) { } } + +// TestNoEncoding prevents #231. +func TestNoEncoding(t *testing.T) { + endpoint, _ := NewEndpoint(&mockExchange{}, &bidderParamValidator{}) + request := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(validRequests[0])) + recorder := httptest.NewRecorder() + endpoint(recorder, request, nil) + + if !strings.Contains(recorder.Body.String(), "") { + t.Errorf("The Response from the exchange should not be html-encoded") + } +} + // nobidExchange is a well-behaved exchange which always bids "no bid". type nobidExchange struct {} @@ -283,3 +296,15 @@ var invalidRequests = []string{ } }]}`, } + +type mockExchange struct {} + +func (*mockExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest) (*openrtb.BidResponse, error) { + return &openrtb.BidResponse{ + SeatBid: []openrtb.SeatBid{{ + Bid: []openrtb.Bid{{ + AdM: "", + }}, + }}, + }, nil +}