super-graph/serv/http.go

116 lines
2.4 KiB
Go
Raw Normal View History

2019-03-24 14:57:29 +01:00
package serv
import (
"encoding/json"
"errors"
"io"
"io/ioutil"
"net/http"
"strings"
2019-04-01 14:55:46 +02:00
"time"
2019-03-24 14:57:29 +01:00
"github.com/gorilla/websocket"
)
const (
2019-04-19 07:55:03 +02:00
maxReadBytes = 100000 // 100Kb
2019-03-24 14:57:29 +01:00
introspectionQuery = "IntrospectionQuery"
openVar = "{{"
closeVar = "}}"
)
var (
2019-04-19 07:55:03 +02:00
upgrader = websocket.Upgrader{}
errNoUserID = errors.New("no user_id available")
errUnauthorized = errors.New("not authorized")
2019-03-24 14:57:29 +01:00
)
type gqlReq struct {
2019-04-19 07:55:03 +02:00
OpName string `json:"operationName"`
Query string `json:"query"`
Vars variables `json:"variables"`
2019-03-24 14:57:29 +01:00
}
2019-04-19 07:55:03 +02:00
type variables map[string]interface{}
2019-03-24 14:57:29 +01:00
type gqlResp struct {
2019-04-01 14:55:46 +02:00
Error string `json:"error,omitempty"`
2019-04-19 07:55:03 +02:00
Data json.RawMessage `json:"data"`
2019-04-04 06:53:24 +02:00
Extensions *extensions `json:"extensions,omitempty"`
2019-04-01 14:55:46 +02:00
}
type extensions struct {
2019-04-04 06:53:24 +02:00
Tracing *trace `json:"tracing,omitempty"`
2019-04-01 14:55:46 +02:00
}
type trace struct {
Version int `json:"version"`
StartTime time.Time `json:"startTime"`
EndTime time.Time `json:"endTime"`
Duration time.Duration `json:"duration"`
Execution execution `json:"execution"`
}
type execution struct {
Resolvers []resolver `json:"resolvers"`
}
type resolver struct {
Path []string `json:"path"`
ParentType string `json:"parentType"`
FieldName string `json:"fieldName"`
ReturnType string `json:"returnType"`
StartOffset int `json:"startOffset"`
Duration time.Duration `json:"duration"`
2019-03-24 14:57:29 +01:00
}
func apiv1Http(w http.ResponseWriter, r *http.Request) {
2019-05-13 01:27:26 +02:00
ctx := &coreContext{Context: r.Context()}
2019-03-24 14:57:29 +01:00
if authFailBlock == authFailBlockAlways && authCheck(ctx) == false {
http.Error(w, "Not authorized", 401)
return
}
2019-04-19 07:55:03 +02:00
b, err := ioutil.ReadAll(io.LimitReader(r.Body, maxReadBytes))
2019-03-24 14:57:29 +01:00
defer r.Body.Close()
if err != nil {
errorResp(w, err)
return
}
2019-05-13 01:27:26 +02:00
if err := json.Unmarshal(b, &ctx.req); err != nil {
2019-03-24 14:57:29 +01:00
errorResp(w, err)
return
}
2019-05-13 01:27:26 +02:00
if strings.EqualFold(ctx.req.OpName, introspectionQuery) {
2019-03-24 14:57:29 +01:00
dat, err := ioutil.ReadFile("test.schema")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Write(dat)
return
}
2019-05-13 01:27:26 +02:00
err = ctx.handleReq(w, r)
2019-03-24 14:57:29 +01:00
2019-04-19 07:55:03 +02:00
if err == errUnauthorized {
2019-03-24 14:57:29 +01:00
http.Error(w, "Not authorized", 401)
}
if err != nil {
errorResp(w, err)
}
2019-04-01 14:55:46 +02:00
}
2019-05-13 01:27:26 +02:00
func errorResp(w http.ResponseWriter, err error) {
if conf.DebugLevel > 0 {
logger.Error(err.Error())
}
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(gqlResp{Error: err.Error()})
}