diff options
Diffstat (limited to 'vendor/github.com/vektah/gqlgen/handler')
-rw-r--r-- | vendor/github.com/vektah/gqlgen/handler/graphql.go | 235 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/handler/playground.go | 51 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/handler/stub.go | 45 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/handler/websocket.go | 245 |
4 files changed, 0 insertions, 576 deletions
diff --git a/vendor/github.com/vektah/gqlgen/handler/graphql.go b/vendor/github.com/vektah/gqlgen/handler/graphql.go deleted file mode 100644 index 4a5c61f5..00000000 --- a/vendor/github.com/vektah/gqlgen/handler/graphql.go +++ /dev/null @@ -1,235 +0,0 @@ -package handler - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "strings" - - "github.com/gorilla/websocket" - "github.com/vektah/gqlgen/graphql" - "github.com/vektah/gqlgen/neelance/errors" - "github.com/vektah/gqlgen/neelance/query" - "github.com/vektah/gqlgen/neelance/validation" -) - -type params struct { - Query string `json:"query"` - OperationName string `json:"operationName"` - Variables map[string]interface{} `json:"variables"` -} - -type Config struct { - upgrader websocket.Upgrader - recover graphql.RecoverFunc - errorPresenter graphql.ErrorPresenterFunc - resolverHook graphql.ResolverMiddleware - requestHook graphql.RequestMiddleware -} - -func (c *Config) newRequestContext(doc *query.Document, query string, variables map[string]interface{}) *graphql.RequestContext { - reqCtx := graphql.NewRequestContext(doc, query, variables) - if hook := c.recover; hook != nil { - reqCtx.Recover = hook - } - - if hook := c.errorPresenter; hook != nil { - reqCtx.ErrorPresenter = hook - } - - if hook := c.resolverHook; hook != nil { - reqCtx.ResolverMiddleware = hook - } - - if hook := c.requestHook; hook != nil { - reqCtx.RequestMiddleware = hook - } - - return reqCtx -} - -type Option func(cfg *Config) - -func WebsocketUpgrader(upgrader websocket.Upgrader) Option { - return func(cfg *Config) { - cfg.upgrader = upgrader - } -} - -func RecoverFunc(recover graphql.RecoverFunc) Option { - return func(cfg *Config) { - cfg.recover = recover - } -} - -// ErrorPresenter transforms errors found while resolving into errors that will be returned to the user. It provides -// a good place to add any extra fields, like error.type, that might be desired by your frontend. Check the default -// implementation in graphql.DefaultErrorPresenter for an example. -func ErrorPresenter(f graphql.ErrorPresenterFunc) Option { - return func(cfg *Config) { - cfg.errorPresenter = f - } -} - -// ResolverMiddleware allows you to define a function that will be called around every resolver, -// useful for tracing and logging. -// It will only be called for user defined resolvers, any direct binding to models is assumed -// to cost nothing. -func ResolverMiddleware(middleware graphql.ResolverMiddleware) Option { - return func(cfg *Config) { - if cfg.resolverHook == nil { - cfg.resolverHook = middleware - return - } - - lastResolve := cfg.resolverHook - cfg.resolverHook = func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { - return lastResolve(ctx, func(ctx context.Context) (res interface{}, err error) { - return middleware(ctx, next) - }) - } - } -} - -// RequestMiddleware allows you to define a function that will be called around the root request, -// after the query has been parsed. This is useful for logging and tracing -func RequestMiddleware(middleware graphql.RequestMiddleware) Option { - return func(cfg *Config) { - if cfg.requestHook == nil { - cfg.requestHook = middleware - return - } - - lastResolve := cfg.requestHook - cfg.requestHook = func(ctx context.Context, next func(ctx context.Context) []byte) []byte { - return lastResolve(ctx, func(ctx context.Context) []byte { - return middleware(ctx, next) - }) - } - } -} - -func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc { - cfg := Config{ - upgrader: websocket.Upgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - }, - } - - for _, option := range options { - option(&cfg) - } - - 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) - return - } - - var reqParams params - switch r.Method { - case http.MethodGet: - reqParams.Query = r.URL.Query().Get("query") - reqParams.OperationName = r.URL.Query().Get("operationName") - - if variables := r.URL.Query().Get("variables"); variables != "" { - if err := json.Unmarshal([]byte(variables), &reqParams.Variables); err != nil { - sendErrorf(w, http.StatusBadRequest, "variables could not be decoded") - return - } - } - 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 { - sendError(w, http.StatusUnprocessableEntity, qErr) - return - } - - errs := validation.Validate(exec.Schema(), doc) - if len(errs) != 0 { - sendError(w, http.StatusUnprocessableEntity, errs...) - return - } - - op, err := doc.GetOperation(reqParams.OperationName) - if err != nil { - sendErrorf(w, http.StatusUnprocessableEntity, err.Error()) - return - } - - reqCtx := cfg.newRequestContext(doc, reqParams.Query, reqParams.Variables) - ctx := graphql.WithRequestContext(r.Context(), reqCtx) - - defer func() { - if err := recover(); err != nil { - userErr := reqCtx.Recover(ctx, err) - sendErrorf(w, http.StatusUnprocessableEntity, userErr.Error()) - } - }() - - switch op.Type { - case query.Query: - b, err := json.Marshal(exec.Query(ctx, op)) - if err != nil { - panic(err) - } - w.Write(b) - case query.Mutation: - b, err := json.Marshal(exec.Mutation(ctx, op)) - if err != nil { - panic(err) - } - w.Write(b) - default: - sendErrorf(w, http.StatusBadRequest, "unsupported operation type") - } - }) -} - -func sendError(w http.ResponseWriter, code int, errors ...*errors.QueryError) { - w.WriteHeader(code) - var errs []*graphql.Error - for _, err := range errors { - var locations []graphql.ErrorLocation - for _, l := range err.Locations { - fmt.Println(graphql.ErrorLocation(l)) - locations = append(locations, graphql.ErrorLocation{ - Line: l.Line, - Column: l.Column, - }) - } - - errs = append(errs, &graphql.Error{ - Message: err.Message, - Path: err.Path, - Locations: locations, - }) - } - b, err := json.Marshal(&graphql.Response{Errors: errs}) - if err != nil { - panic(err) - } - w.Write(b) -} - -func sendErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) { - sendError(w, code, &errors.QueryError{Message: fmt.Sprintf(format, args...)}) -} diff --git a/vendor/github.com/vektah/gqlgen/handler/playground.go b/vendor/github.com/vektah/gqlgen/handler/playground.go deleted file mode 100644 index 44533590..00000000 --- a/vendor/github.com/vektah/gqlgen/handler/playground.go +++ /dev/null @@ -1,51 +0,0 @@ -package handler - -import ( - "html/template" - "net/http" -) - -var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html> -<html> -<head> - <meta charset=utf-8/> - <meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui"> - <link rel="shortcut icon" href="https://graphcool-playground.netlify.com/favicon.png"> - <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/static/css/index.css"/> - <link rel="shortcut icon" href="//cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/favicon.png"/> - <script src="//cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/static/js/middleware.js"></script> - <title>{{.title}}</title> -</head> -<body> -<style type="text/css"> - html { font-family: "Open Sans", sans-serif; overflow: hidden; } - body { margin: 0; background: #172a3a; } -</style> -<div id="root"/> -<script type="text/javascript"> - window.addEventListener('load', function (event) { - const root = document.getElementById('root'); - root.classList.add('playgroundIn'); - const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:' - GraphQLPlayground.init(root, { - endpoint: location.protocol + '//' + location.host + '{{.endpoint}}', - subscriptionsEndpoint: wsProto + '//' + location.host + '{{.endpoint }}', - }) - }) -</script> -</body> -</html> -`)) - -func Playground(title string, endpoint string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - err := page.Execute(w, map[string]string{ - "title": title, - "endpoint": endpoint, - "version": "1.4.3", - }) - if err != nil { - panic(err) - } - } -} diff --git a/vendor/github.com/vektah/gqlgen/handler/stub.go b/vendor/github.com/vektah/gqlgen/handler/stub.go deleted file mode 100644 index 46b27e46..00000000 --- a/vendor/github.com/vektah/gqlgen/handler/stub.go +++ /dev/null @@ -1,45 +0,0 @@ -package handler - -import ( - "context" - "time" - - "github.com/vektah/gqlgen/graphql" - "github.com/vektah/gqlgen/neelance/query" - "github.com/vektah/gqlgen/neelance/schema" -) - -type executableSchemaStub struct { -} - -var _ graphql.ExecutableSchema = &executableSchemaStub{} - -func (e *executableSchemaStub) Schema() *schema.Schema { - return schema.MustParse(` - schema { query: Query } - type Query { me: User! } - type User { name: String! } - `) -} - -func (e *executableSchemaStub) Query(ctx context.Context, op *query.Operation) *graphql.Response { - return &graphql.Response{Data: []byte(`{"name":"test"}`)} -} - -func (e *executableSchemaStub) Mutation(ctx context.Context, op *query.Operation) *graphql.Response { - return graphql.ErrorResponse(ctx, "mutations are not supported") -} - -func (e *executableSchemaStub) Subscription(ctx context.Context, op *query.Operation) func() *graphql.Response { - return func() *graphql.Response { - time.Sleep(50 * time.Millisecond) - select { - case <-ctx.Done(): - return nil - default: - return &graphql.Response{ - Data: []byte(`{"name":"test"}`), - } - } - } -} diff --git a/vendor/github.com/vektah/gqlgen/handler/websocket.go b/vendor/github.com/vektah/gqlgen/handler/websocket.go deleted file mode 100644 index e80748ca..00000000 --- a/vendor/github.com/vektah/gqlgen/handler/websocket.go +++ /dev/null @@ -1,245 +0,0 @@ -package handler - -import ( - "context" - "encoding/json" - "fmt" - "log" - "net/http" - "sync" - - "github.com/gorilla/websocket" - "github.com/vektah/gqlgen/graphql" - "github.com/vektah/gqlgen/neelance/errors" - "github.com/vektah/gqlgen/neelance/query" - "github.com/vektah/gqlgen/neelance/validation" -) - -const ( - connectionInitMsg = "connection_init" // Client -> Server - connectionTerminateMsg = "connection_terminate" // Client -> Server - startMsg = "start" // Client -> Server - stopMsg = "stop" // Client -> Server - connectionAckMsg = "connection_ack" // Server -> Client - connectionErrorMsg = "connection_error" // Server -> Client - dataMsg = "data" // Server -> Client - errorMsg = "error" // Server -> Client - completeMsg = "complete" // Server -> Client - //connectionKeepAliveMsg = "ka" // Server -> Client TODO: keepalives -) - -type operationMessage struct { - Payload json.RawMessage `json:"payload,omitempty"` - ID string `json:"id,omitempty"` - Type string `json:"type"` -} - -type wsConnection struct { - ctx context.Context - conn *websocket.Conn - exec graphql.ExecutableSchema - active map[string]context.CancelFunc - mu sync.Mutex - cfg *Config -} - -func connectWs(exec graphql.ExecutableSchema, w http.ResponseWriter, r *http.Request, cfg *Config) { - ws, err := cfg.upgrader.Upgrade(w, r, http.Header{ - "Sec-Websocket-Protocol": []string{"graphql-ws"}, - }) - if err != nil { - log.Printf("unable to upgrade %T to websocket %s: ", w, err.Error()) - sendErrorf(w, http.StatusBadRequest, "unable to upgrade") - return - } - - conn := wsConnection{ - active: map[string]context.CancelFunc{}, - exec: exec, - conn: ws, - ctx: r.Context(), - cfg: cfg, - } - - if !conn.init() { - return - } - - conn.run() -} - -func (c *wsConnection) init() bool { - message := c.readOp() - if message == nil { - c.close(websocket.CloseProtocolError, "decoding error") - return false - } - - switch message.Type { - case connectionInitMsg: - c.write(&operationMessage{Type: connectionAckMsg}) - case connectionTerminateMsg: - c.close(websocket.CloseNormalClosure, "terminated") - return false - default: - c.sendConnectionError("unexpected message %s", message.Type) - c.close(websocket.CloseProtocolError, "unexpected message") - return false - } - - return true -} - -func (c *wsConnection) write(msg *operationMessage) { - c.mu.Lock() - c.conn.WriteJSON(msg) - c.mu.Unlock() -} - -func (c *wsConnection) run() { - for { - message := c.readOp() - if message == nil { - return - } - - switch message.Type { - case startMsg: - if !c.subscribe(message) { - return - } - case stopMsg: - c.mu.Lock() - closer := c.active[message.ID] - c.mu.Unlock() - if closer == nil { - c.sendError(message.ID, errors.Errorf("%s is not running, cannot stop", message.ID)) - continue - } - - closer() - case connectionTerminateMsg: - c.close(websocket.CloseNormalClosure, "terminated") - return - default: - c.sendConnectionError("unexpected message %s", message.Type) - c.close(websocket.CloseProtocolError, "unexpected message") - return - } - } -} - -func (c *wsConnection) subscribe(message *operationMessage) bool { - var reqParams params - if err := json.Unmarshal(message.Payload, &reqParams); err != nil { - c.sendConnectionError("invalid json") - return false - } - - doc, qErr := query.Parse(reqParams.Query) - if qErr != nil { - c.sendError(message.ID, qErr) - return true - } - - errs := validation.Validate(c.exec.Schema(), doc) - if len(errs) != 0 { - c.sendError(message.ID, errs...) - return true - } - - op, err := doc.GetOperation(reqParams.OperationName) - if err != nil { - c.sendError(message.ID, errors.Errorf("%s", err.Error())) - return true - } - - reqCtx := c.cfg.newRequestContext(doc, reqParams.Query, reqParams.Variables) - ctx := graphql.WithRequestContext(c.ctx, reqCtx) - - if op.Type != query.Subscription { - var result *graphql.Response - if op.Type == query.Query { - result = c.exec.Query(ctx, op) - } else { - result = c.exec.Mutation(ctx, op) - } - - c.sendData(message.ID, result) - c.write(&operationMessage{ID: message.ID, Type: completeMsg}) - return true - } - - ctx, cancel := context.WithCancel(ctx) - c.mu.Lock() - c.active[message.ID] = cancel - c.mu.Unlock() - go func() { - defer func() { - if r := recover(); r != nil { - userErr := reqCtx.Recover(ctx, r) - c.sendError(message.ID, &errors.QueryError{Message: userErr.Error()}) - } - }() - next := c.exec.Subscription(ctx, op) - for result := next(); result != nil; result = next() { - c.sendData(message.ID, result) - } - - c.write(&operationMessage{ID: message.ID, Type: completeMsg}) - - c.mu.Lock() - delete(c.active, message.ID) - c.mu.Unlock() - cancel() - }() - - return true -} - -func (c *wsConnection) sendData(id string, response *graphql.Response) { - b, err := json.Marshal(response) - if err != nil { - c.sendError(id, errors.Errorf("unable to encode json response: %s", err.Error())) - return - } - - c.write(&operationMessage{Type: dataMsg, ID: id, Payload: b}) -} - -func (c *wsConnection) sendError(id string, errors ...*errors.QueryError) { - var errs []error - for _, err := range errors { - errs = append(errs, err) - } - b, err := json.Marshal(errs) - if err != nil { - panic(err) - } - c.write(&operationMessage{Type: errorMsg, ID: id, Payload: b}) -} - -func (c *wsConnection) sendConnectionError(format string, args ...interface{}) { - b, err := json.Marshal(&graphql.Error{Message: fmt.Sprintf(format, args...)}) - if err != nil { - panic(err) - } - - c.write(&operationMessage{Type: connectionErrorMsg, Payload: b}) -} - -func (c *wsConnection) readOp() *operationMessage { - message := operationMessage{} - if err := c.conn.ReadJSON(&message); err != nil { - c.sendConnectionError("invalid json") - return nil - } - return &message -} - -func (c *wsConnection) close(closeCode int, message string) { - c.mu.Lock() - _ = c.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(closeCode, message)) - c.mu.Unlock() - _ = c.conn.Close() -} |