From af38cf0571bbf4e43231f764508330d818fdcc5b Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Thu, 29 Mar 2018 00:17:12 +1100 Subject: [PATCH] Support OPTIONS requests --- handler/graphql.go | 17 +++++++++++++---- handler/graphql_test.go | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/handler/graphql.go b/handler/graphql.go index 8dc768f2f63..af1f6117dab 100644 --- a/handler/graphql.go +++ b/handler/graphql.go @@ -60,15 +60,20 @@ func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc } return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodOptions { + w.Header().Set("Allow", "OPTIONS, GET, POST") + w.WriteHeader(http.StatusOK) + return + } + if strings.Contains(r.Header.Get("Upgrade"), "websocket") { connectWs(exec, w, r, cfg.upgrader, cfg.recover) return } - w.Header().Set("Content-Type", "application/json") - var reqParams params - if r.Method == "GET" { + switch r.Method { + case http.MethodGet: reqParams.Query = r.URL.Query().Get("query") reqParams.OperationName = r.URL.Query().Get("operationName") @@ -78,12 +83,16 @@ func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc return } } - } else { + case http.MethodPost: if err := json.NewDecoder(r.Body).Decode(&reqParams); err != nil { sendErrorf(w, http.StatusBadRequest, "json body could not be decoded: "+err.Error()) return } + default: + w.WriteHeader(http.StatusMethodNotAllowed) + return } + w.Header().Set("Content-Type", "application/json") doc, qErr := query.Parse(reqParams.Query) if qErr != nil { diff --git a/handler/graphql_test.go b/handler/graphql_test.go index 5aa1f238cb9..718e522cf51 100644 --- a/handler/graphql_test.go +++ b/handler/graphql_test.go @@ -65,6 +65,21 @@ func TestHandlerGET(t *testing.T) { }) } +func TestHandlerOptions(t *testing.T) { + h := GraphQL(&executableSchemaStub{}) + + resp := doRequest(h, "OPTIONS", "/graphql?query={me{name}}", ``) + assert.Equal(t, http.StatusOK, resp.Code) + assert.Equal(t, "OPTIONS, GET, POST", resp.HeaderMap.Get("Allow")) +} + +func TestHandlerHead(t *testing.T) { + h := GraphQL(&executableSchemaStub{}) + + resp := doRequest(h, "HEAD", "/graphql?query={me{name}}", ``) + assert.Equal(t, http.StatusMethodNotAllowed, resp.Code) +} + func doRequest(handler http.Handler, method string, target string, body string) *httptest.ResponseRecorder { r := httptest.NewRequest(method, target, strings.NewReader(body)) w := httptest.NewRecorder()