Skip to content

Commit

Permalink
[query] Fix Content-Type for OpenAPI handler (#2403)
Browse files Browse the repository at this point in the history
  • Loading branch information
schallert authored Jun 11, 2020
1 parent 2c4f65c commit 586e72b
Show file tree
Hide file tree
Showing 15 changed files with 47 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/query/api/v1/handler/graphite/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func (h *grahiteFindHandler) ServeHTTP(
) {
ctx := context.WithValue(r.Context(), handler.HeaderKey, r.Header)
logger := logging.WithContext(ctx, h.instrumentOpts)
w.Header().Set("Content-Type", "application/json")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeJSON)

// NB: need to run two separate queries, one of which will match only the
// provided matchers, and one which will match the provided matchers with at
Expand Down
5 changes: 3 additions & 2 deletions src/query/api/v1/handler/graphite/render_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/m3db/m3/src/query/graphite/graphite"
"github.com/m3db/m3/src/query/graphite/ts"
"github.com/m3db/m3/src/query/util/json"
xhttp "github.com/m3db/m3/src/x/net/http"
)

const (
Expand All @@ -54,12 +55,12 @@ func WriteRenderResponse(
format string,
) error {
if format == pickleFormat {
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeOctetStream)
return renderResultsPickle(w, series.Values)
}

// NB: return json unless requesting specifically `pickleFormat`
w.Header().Set("Content-Type", "application/json")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeJSON)
return renderResultsJSON(w, series.Values)
}

Expand Down
1 change: 1 addition & 0 deletions src/query/api/v1/handler/openapi/openapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func (h *DocHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}

w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeHTMLUTF8)
w.Write(doc)
}

Expand Down
6 changes: 4 additions & 2 deletions src/query/api/v1/handler/prom/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
"net/http"
"time"

xhttp "github.com/m3db/m3/src/x/net/http"

jsoniter "github.com/json-iterator/go"
promql "github.com/prometheus/prometheus/promql/parser"
promstorage "github.com/prometheus/prometheus/storage"
Expand Down Expand Up @@ -100,7 +102,7 @@ func respond(w http.ResponseWriter, data interface{}, warnings promstorage.Warni
return
}

w.Header().Set("Content-Type", "application/json")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeJSON)
w.WriteHeader(http.StatusOK)
w.Write(b)
}
Expand All @@ -117,7 +119,7 @@ func respondError(w http.ResponseWriter, err error, code int) {
return
}

w.Header().Set("Content-Type", "application/json")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeJSON)
w.WriteHeader(code)
w.Write(b)
}
3 changes: 2 additions & 1 deletion src/query/api/v1/handler/prometheus/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (

"github.com/m3db/m3/src/query/models"
"github.com/m3db/m3/src/query/test"
xhttp "github.com/m3db/m3/src/x/net/http"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -93,7 +94,7 @@ func TestTimeoutParseWithPostRequestParam(t *testing.T) {
require.NoError(t, form.Close())

req := httptest.NewRequest("POST", "/dummy", buff)
req.Header.Set("Content-Type", form.FormDataContentType())
req.Header.Set(xhttp.HeaderContentType, form.FormDataContentType())

timeout, err := ParseRequestTimeout(req, time.Second)
assert.NoError(t, err)
Expand Down
2 changes: 1 addition & 1 deletion src/query/api/v1/handler/prometheus/native/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func TestParamParsing(t *testing.T) {
func TestParamParsing_POST(t *testing.T) {
params := defaultParams().Encode()
req := httptest.NewRequest("POST", PromReadURL, strings.NewReader(params))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add(xhttp.HeaderContentType, xhttp.ContentTypeFormURLEncoded)

r, err := testParseParams(req)
require.NoError(t, err, "unable to parse request")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func NewCompleteTagsHandler(opts options.HandlerOptions) http.Handler {
func (h *CompleteTagsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), handler.HeaderKey, r.Header)
logger := logging.WithContext(ctx, h.instrumentOpts)
w.Header().Set("Content-Type", "application/json")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeJSON)

tagCompletionQueries, rErr := prometheus.ParseTagCompletionParamsToQueries(r)
if rErr != nil {
Expand Down
2 changes: 1 addition & 1 deletion src/query/api/v1/handler/prometheus/native/list_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func NewListTagsHandler(opts options.HandlerOptions) http.Handler {
func (h *ListTagsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), handler.HeaderKey, r.Header)
logger := logging.WithContext(ctx, h.instrumentOpts)
w.Header().Set("Content-Type", "application/json")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeJSON)

query := &storage.CompleteTagsQuery{
CompleteNameOnly: true,
Expand Down
2 changes: 1 addition & 1 deletion src/query/api/v1/handler/prometheus/native/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func (h *promReadHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}

w.Header().Set("Content-Type", "application/json")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeJSON)
handleroptions.AddWarningHeaders(w, result.Meta)
h.promReadMetrics.fetchSuccess.Inc(1)

Expand Down
2 changes: 1 addition & 1 deletion src/query/api/v1/handler/prometheus/remote/match.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func NewPromSeriesMatchHandler(opts options.HandlerOptions) http.Handler {
func (h *PromSeriesMatchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), handler.HeaderKey, r.Header)
logger := logging.WithContext(ctx, h.instrumentOpts)
w.Header().Set("Content-Type", "application/json")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeJSON)
w.Header().Set("Access-Control-Allow-Origin", "*")

queries, err := prometheus.ParseSeriesMatchQuery(r, h.tagOptions)
Expand Down
4 changes: 2 additions & 2 deletions src/query/api/v1/handler/prometheus/remote/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func (h *promReadHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
})
}

w.Header().Set("Content-Type", "application/json")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeJSON)
handleroptions.AddWarningHeaders(w, readResult.Meta)

err = json.NewEncoder(w).Encode(result)
Expand Down Expand Up @@ -226,7 +226,7 @@ func WriteSnappyCompressed(
return err
}

w.Header().Set("Content-Type", "application/x-protobuf")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeProtobuf)
w.Header().Set("Content-Encoding", "snappy")
handleroptions.AddWarningHeaders(w, readResult.Meta)

Expand Down
7 changes: 4 additions & 3 deletions src/query/api/v1/handler/prometheus/remote/read_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import (
"github.com/m3db/m3/src/query/test/m3"
xclock "github.com/m3db/m3/src/x/clock"
"github.com/m3db/m3/src/x/instrument"
xhttp "github.com/m3db/m3/src/x/net/http"
xtest "github.com/m3db/m3/src/x/test"

"github.com/golang/mock/gomock"
Expand Down Expand Up @@ -89,7 +90,7 @@ func TestParseExpr(t *testing.T) {

start := time.Now().Truncate(time.Hour)
req := httptest.NewRequest(http.MethodPost, "/", buildBody(query, start))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add(xhttp.HeaderContentType, xhttp.ContentTypeFormURLEncoded)
readReq, err := ParseExpr(req)
require.NoError(t, err)

Expand Down Expand Up @@ -248,7 +249,7 @@ func TestQueryKillOnClientDisconnect(t *testing.T) {
Timeout: 1 * time.Millisecond,
}

_, err := c.Post(server.URL, "application/x-protobuf", test.GeneratePromReadBody(t))
_, err := c.Post(server.URL, xhttp.ContentTypeProtobuf, test.GeneratePromReadBody(t))
assert.Error(t, err)
}

Expand All @@ -257,7 +258,7 @@ func TestQueryKillOnTimeout(t *testing.T) {
defer server.Close()

req, _ := http.NewRequest("POST", server.URL, test.GeneratePromReadBody(t))
req.Header.Add("Content-Type", "application/x-protobuf")
req.Header.Add(xhttp.HeaderContentType, xhttp.ContentTypeProtobuf)
req.Header.Add("timeout", "1ms")
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
Expand Down
2 changes: 1 addition & 1 deletion src/query/api/v1/handler/prometheus/remote/tag_values.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func NewTagValuesHandler(options options.HandlerOptions) http.Handler {
func (h *TagValuesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), handler.HeaderKey, r.Header)
logger := logging.WithContext(ctx, h.instrumentOpts)
w.Header().Set("Content-Type", "application/json")
w.Header().Set(xhttp.HeaderContentType, xhttp.ContentTypeJSON)

query, err := h.parseTagValuesToQuery(r)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion src/query/api/v1/handler/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
"github.com/m3db/m3/src/query/test/m3"
"github.com/m3db/m3/src/query/test/seriesiter"
"github.com/m3db/m3/src/x/ident"
xhttp "github.com/m3db/m3/src/x/net/http"

"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -129,7 +130,7 @@ func TestSearchEndpoint(t *testing.T) {

urlWithLimit := fmt.Sprintf("%s%s", server.URL, "?limit=90")
req, _ := http.NewRequest("POST", urlWithLimit, generateSearchBody(t))
req.Header.Add("Content-Type", "application/json")
req.Header.Add(xhttp.HeaderContentType, xhttp.ContentTypeJSON)
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
defer resp.Body.Close()
Expand Down
24 changes: 22 additions & 2 deletions src/x/net/http/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,26 @@ import (
"go.uber.org/zap"
)

const (
// HeaderContentType is the HTTP Content Type header.
HeaderContentType = "Content-Type"

// ContentTypeJSON is the Content-Type value for a JSON response.
ContentTypeJSON = "application/json"

// ContentTypeFormURLEncoded is the Content-Type value for a URL-encoded form.
ContentTypeFormURLEncoded = "application/x-www-form-urlencoded"

// ContentTypeHTMLUTF8 is the Content-Type value for UTF8-encoded HTML.
ContentTypeHTMLUTF8 = "text/html; charset=utf-8"

// ContentTypeProtobuf is the Content-Type value for a Protobuf message.
ContentTypeProtobuf = "application/x-protobuf"

// ContentTypeOctetStream is the Content-Type value for binary data.
ContentTypeOctetStream = "application/octet-stream"
)

// WriteJSONResponse writes generic data to the ResponseWriter
func WriteJSONResponse(w http.ResponseWriter, data interface{}, logger *zap.Logger) {
jsonData, err := json.Marshal(data)
Expand All @@ -39,7 +59,7 @@ func WriteJSONResponse(w http.ResponseWriter, data interface{}, logger *zap.Logg
return
}

w.Header().Set("Content-Type", "application/json")
w.Header().Set(HeaderContentType, ContentTypeJSON)
w.Write(jsonData)
}

Expand All @@ -48,7 +68,7 @@ func WriteJSONResponse(w http.ResponseWriter, data interface{}, logger *zap.Logg
func WriteProtoMsgJSONResponse(w http.ResponseWriter, data proto.Message, logger *zap.Logger) {
marshaler := jsonpb.Marshaler{EmitDefaults: true}

w.Header().Set("Content-Type", "application/json")
w.Header().Set(HeaderContentType, ContentTypeJSON)
err := marshaler.Marshal(w, data)
if err != nil {
logger.Error("unable to marshal json", zap.Error(err))
Expand Down

0 comments on commit 586e72b

Please sign in to comment.