diff --git a/cncd/pipeline/pipec/compile.go b/cncd/pipeline/pipec/compile.go deleted file mode 100644 index a363c7fdb..000000000 --- a/cncd/pipeline/pipec/compile.go +++ /dev/null @@ -1,507 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "os" - "path" - "path/filepath" - "strings" - - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/frontend" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/frontend/yaml" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/frontend/yaml/compiler" - - "github.com/urfave/cli" -) - -var compileCommand = cli.Command{ - Name: "compile", - Usage: "compile the yaml file", - Action: compileAction, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "in", - Value: "pipeline.yml", - }, - cli.StringFlag{ - Name: "out", - Value: "pipeline.json", - }, - cli.StringSliceFlag{ - Name: "volumes", - }, - cli.StringSliceFlag{ - Name: "privileged", - Value: &cli.StringSlice{ - "plugins/docker", - "plugins/gcr", - "plugins/ecr", - }, - }, - cli.StringFlag{ - Name: "prefix", - Value: "pipeline", - }, - cli.BoolFlag{ - Name: "local", - }, - // - // volume caching - // - cli.BoolFlag{ - Name: "volume-cache", - EnvVar: "CI_VOLUME_CACHE", - }, - cli.StringFlag{ - Name: "volume-cache-base", - Value: "/var/lib/drone", - EnvVar: "CI_VOLUME_CACHE_BASE", - }, - // - // s3 caching - // - cli.BoolFlag{ - Name: "aws-cache", - EnvVar: "CI_AWS_CACHE", - }, - cli.StringFlag{ - Name: "aws-region", - EnvVar: "AWS_REGION", - }, - cli.StringFlag{ - Name: "aws-bucket", - EnvVar: "AWS_BUCKET", - }, - cli.StringFlag{ - Name: "aws-access-key-id", - EnvVar: "AWS_ACCESS_KEY_ID", - }, - cli.StringFlag{ - Name: "aws-secret-access-key", - EnvVar: "AWS_SECRET_ACCESS_KEY", - }, - // - // registry credentials - // - cli.StringFlag{ - Name: "registry-hostname", - EnvVar: "CI_REGISTRY_HOSTNAME", - }, - cli.StringFlag{ - Name: "registry-username", - EnvVar: "CI_REGISTRY_USERNAME", - }, - cli.StringFlag{ - Name: "registry-password", - EnvVar: "CI_REGISTRY_PASSWORD", - }, - // - // workspace default - // - cli.StringFlag{ - Name: "workspace-base", - Value: "/pipeline", - }, - cli.StringFlag{ - Name: "workspace-path", - Value: "src", - }, - // - // netrc parameters - // - cli.StringFlag{ - Name: "netrc-username", - EnvVar: "CI_NETRC_USERNAME", - }, - cli.StringFlag{ - Name: "netrc-password", - EnvVar: "CI_NETRC_PASSWORD", - }, - cli.StringFlag{ - Name: "netrc-machine", - EnvVar: "CI_NETRC_MACHINE", - }, - // - // resource limit parameters - // - cli.Int64Flag{ - Name: "limit-mem-swap", - EnvVar: "CI_LIMIT_MEM_SWAP", - }, - cli.Int64Flag{ - Name: "limit-mem", - EnvVar: "CI_LIMIT_MEM", - }, - cli.Int64Flag{ - Name: "limit-shm-size", - EnvVar: "CI_LIMIT_SHM_SIZE", - }, - cli.Int64Flag{ - Name: "limit-cpu-quota", - EnvVar: "CI_LIMIT_CPU_QUOTA", - }, - cli.Int64Flag{ - Name: "limit-cpu-shares", - EnvVar: "CI_LIMIT_CPU_SHARES", - }, - cli.StringFlag{ - Name: "limit-cpu-set", - EnvVar: "CI_LIMIT_CPU_SET", - }, - // - // metadata parameters - // - cli.StringFlag{ - Name: "system-arch", - Value: "linux/amd64", - EnvVar: "CI_SYSTEM_ARCH", - }, - cli.StringFlag{ - Name: "system-name", - Value: "pipec", - EnvVar: "CI_SYSTEM_NAME", - }, - cli.StringFlag{ - Name: "system-link", - Value: "https://github.com/cncd/pipec", - EnvVar: "CI_SYSTEM_LINK", - }, - cli.StringFlag{ - Name: "repo-name", - EnvVar: "CI_REPO_NAME", - }, - cli.StringFlag{ - Name: "repo-link", - EnvVar: "CI_REPO_LINK", - }, - cli.StringFlag{ - Name: "repo-remote-url", - EnvVar: "CI_REPO_REMOTE", - }, - cli.StringFlag{ - Name: "repo-private", - EnvVar: "CI_REPO_PRIVATE", - }, - cli.IntFlag{ - Name: "build-number", - EnvVar: "CI_BUILD_NUMBER", - }, - cli.Int64Flag{ - Name: "build-created", - EnvVar: "CI_BUILD_CREATED", - }, - cli.Int64Flag{ - Name: "build-started", - EnvVar: "CI_BUILD_STARTED", - }, - cli.Int64Flag{ - Name: "build-finished", - EnvVar: "CI_BUILD_FINISHED", - }, - cli.StringFlag{ - Name: "build-status", - EnvVar: "CI_BUILD_STATUS", - }, - cli.StringFlag{ - Name: "build-event", - EnvVar: "CI_BUILD_EVENT", - }, - cli.StringFlag{ - Name: "build-link", - EnvVar: "CI_BUILD_LINK", - }, - cli.StringFlag{ - Name: "build-target", - EnvVar: "CI_BUILD_TARGET", - }, - cli.StringFlag{ - Name: "commit-sha", - EnvVar: "CI_COMMIT_SHA", - }, - cli.StringFlag{ - Name: "commit-ref", - EnvVar: "CI_COMMIT_REF", - }, - cli.StringFlag{ - Name: "commit-refspec", - EnvVar: "CI_COMMIT_REFSPEC", - }, - cli.StringFlag{ - Name: "commit-branch", - EnvVar: "CI_COMMIT_BRANCH", - }, - cli.StringFlag{ - Name: "commit-message", - EnvVar: "CI_COMMIT_MESSAGE", - }, - cli.StringFlag{ - Name: "commit-author-name", - EnvVar: "CI_COMMIT_AUTHOR_NAME", - }, - cli.StringFlag{ - Name: "commit-author-avatar", - EnvVar: "CI_COMMIT_AUTHOR_AVATAR", - }, - cli.StringFlag{ - Name: "commit-author-email", - EnvVar: "CI_COMMIT_AUTHOR_EMAIL", - }, - cli.IntFlag{ - Name: "prev-build-number", - EnvVar: "CI_PREV_BUILD_NUMBER", - }, - cli.Int64Flag{ - Name: "prev-build-created", - EnvVar: "CI_PREV_BUILD_CREATED", - }, - cli.Int64Flag{ - Name: "prev-build-started", - EnvVar: "CI_PREV_BUILD_STARTED", - }, - cli.Int64Flag{ - Name: "prev-build-finished", - EnvVar: "CI_PREV_BUILD_FINISHED", - }, - cli.StringFlag{ - Name: "prev-build-status", - EnvVar: "CI_PREV_BUILD_STATUS", - }, - cli.StringFlag{ - Name: "prev-build-event", - EnvVar: "CI_PREV_BUILD_EVENT", - }, - cli.StringFlag{ - Name: "prev-build-link", - EnvVar: "CI_PREV_BUILD_LINK", - }, - cli.StringFlag{ - Name: "prev-commit-sha", - EnvVar: "CI_PREV_COMMIT_SHA", - }, - cli.StringFlag{ - Name: "prev-commit-ref", - EnvVar: "CI_PREV_COMMIT_REF", - }, - cli.StringFlag{ - Name: "prev-commit-refspec", - EnvVar: "CI_PREV_COMMIT_REFSPEC", - }, - cli.StringFlag{ - Name: "prev-commit-branch", - EnvVar: "CI_PREV_COMMIT_BRANCH", - }, - cli.StringFlag{ - Name: "prev-commit-message", - EnvVar: "CI_PREV_COMMIT_MESSAGE", - }, - cli.StringFlag{ - Name: "prev-commit-author-name", - EnvVar: "CI_PREV_COMMIT_AUTHOR_NAME", - }, - cli.StringFlag{ - Name: "prev-commit-author-avatar", - EnvVar: "CI_PREV_COMMIT_AUTHOR_AVATAR", - }, - cli.StringFlag{ - Name: "prev-commit-author-email", - EnvVar: "CI_PREV_COMMIT_AUTHOR_EMAIL", - }, - cli.IntFlag{ - Name: "job-number", - EnvVar: "CI_JOB_NUMBER", - }, - // cli.StringFlag{ - // Name: "job-matrix", - // EnvVar: "CI_JOB_MATRIX", - // }, - }, -} - -func compileAction(c *cli.Context) (err error) { - file := c.Args().First() - if file == "" { - file = c.String("in") - } - - conf, err := yaml.ParseFile(file) - if err != nil { - return err - } - - // configure volumes for local execution - volumes := c.StringSlice("volumes") - if c.Bool("local") { - var ( - workspaceBase = conf.Workspace.Base - workspacePath = conf.Workspace.Path - ) - if workspaceBase == "" { - workspaceBase = c.String("workspace-base") - } - if workspacePath == "" { - workspacePath = c.String("workspace-path") - } - dir, _ := filepath.Abs(filepath.Dir(file)) - volumes = append(volumes, dir+":"+path.Join(workspaceBase, workspacePath)) - } - - // secrets from environment variable - var secrets []compiler.Secret - for _, env := range os.Environ() { - parts := strings.Split(env, "=") - secrets = append(secrets, compiler.Secret{ - Name: parts[0], - Value: parts[1], - }) - } - - // compiles the yaml file - compiled := compiler.New( - compiler.WithResourceLimit( - c.Int64("limit-mem-swap"), - c.Int64("limit-mem"), - c.Int64("limit-shm-size"), - c.Int64("limit-cpu-quota"), - c.Int64("limit-cpu-shares"), - c.String("limit-cpu-set"), - ), - compiler.WithRegistry( - compiler.Registry{ - Hostname: c.String("registry-hostname"), - Username: c.String("registry-username"), - Password: c.String("registry-password"), - }, - ), - compiler.WithEscalated( - c.StringSlice("privileged")..., - ), - compiler.WithSecret(secrets...), - compiler.WithVolumes(volumes...), - compiler.WithWorkspace( - c.String("workspace-base"), - c.String("workspace-path"), - ), - compiler.WithPrefix( - c.String("prefix"), - ), - compiler.WithProxy(), - compiler.WithLocal( - c.Bool("local"), - ), - compiler.WithNetrc( - c.String("netrc-username"), - c.String("netrc-password"), - c.String("netrc-machine"), - ), - compiler.WithMetadata( - metadataFromContext(c), - ), - compiler.WithOption( - compiler.WithVolumeCacher( - c.String("volume-cache-base"), - ), - c.Bool("volume-cache"), - ), - compiler.WithOption( - compiler.WithS3Cacher( - c.String("aws-access-key-id"), - c.String("aws-secret-access-key"), - c.String("aws-region"), - c.String("aws-bucket"), - ), - c.Bool("aws-cache"), - ), - ).Compile(conf) - - // marshal the compiled spec to formatted yaml - out, err := json.MarshalIndent(compiled, "", " ") - if err != nil { - return err - } - - // create output file with option to dump to stdout - var writer = os.Stdout - output := c.String("out") - if output != "-" { - writer, err = os.Create(output) - if err != nil { - return err - } - } - defer writer.Close() - - _, err = writer.Write(out) - if err != nil { - return err - } - - if writer != os.Stdout { - fmt.Fprintf(os.Stdout, "Successfully compiled %s to %s\n", file, output) - } - return nil -} - -// return the metadata from the cli context. -func metadataFromContext(c *cli.Context) frontend.Metadata { - return frontend.Metadata{ - Repo: frontend.Repo{ - Name: c.String("repo-name"), - Link: c.String("repo-link"), - Remote: c.String("repo-remote-url"), - Private: c.Bool("repo-private"), - }, - Curr: frontend.Build{ - Number: c.Int("build-number"), - Created: c.Int64("build-created"), - Started: c.Int64("build-started"), - Finished: c.Int64("build-finished"), - Status: c.String("build-status"), - Event: c.String("build-event"), - Link: c.String("build-link"), - Target: c.String("build-target"), - Commit: frontend.Commit{ - Sha: c.String("commit-sha"), - Ref: c.String("commit-ref"), - Refspec: c.String("commit-refspec"), - Branch: c.String("commit-branch"), - Message: c.String("commit-message"), - Author: frontend.Author{ - Name: c.String("commit-author-name"), - Email: c.String("commit-author-email"), - Avatar: c.String("commit-author-avatar"), - }, - }, - }, - Prev: frontend.Build{ - Number: c.Int("prev-build-number"), - Created: c.Int64("prev-build-created"), - Started: c.Int64("prev-build-started"), - Finished: c.Int64("prev-build-finished"), - Status: c.String("prev-build-status"), - Event: c.String("prev-build-event"), - Link: c.String("prev-build-link"), - Commit: frontend.Commit{ - Sha: c.String("prev-commit-sha"), - Ref: c.String("prev-commit-ref"), - Refspec: c.String("prev-commit-refspec"), - Branch: c.String("prev-commit-branch"), - Message: c.String("prev-commit-message"), - Author: frontend.Author{ - Name: c.String("prev-commit-author-name"), - Email: c.String("prev-commit-author-email"), - Avatar: c.String("prev-commit-author-avatar"), - }, - }, - }, - Job: frontend.Job{ - Number: c.Int("job-number"), - // Matrix: , - }, - Sys: frontend.System{ - Name: c.String("system-name"), - Link: c.String("system-link"), - Arch: c.String("system-arch"), - }, - } -} diff --git a/cncd/pipeline/pipec/exec.go b/cncd/pipeline/pipec/exec.go deleted file mode 100644 index c731abeb1..000000000 --- a/cncd/pipeline/pipec/exec.go +++ /dev/null @@ -1,123 +0,0 @@ -package main - -import ( - "context" - "fmt" - "io" - "os" - "strconv" - "time" - - "github.com/urfave/cli" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/backend" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/backend/docker" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/backend/kubernetes" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/interrupt" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/multipart" -) - -var executeCommand = cli.Command{ - Name: "exec", - Usage: "execute the compiled file", - Action: executeAction, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "in", - Value: "pipeline.json", - }, - cli.DurationFlag{ - Name: "timeout", - EnvVar: "CI_TIMEOUT", - Value: time.Hour, - }, - cli.BoolFlag{ - Name: "kubernetes", - EnvVar: "CI_KUBERNETES", - }, - cli.StringFlag{ - Name: "kubernetes-namepsace", - EnvVar: "CI_KUBERNETES_NAMESPACE", - Value: "default", - }, - cli.StringFlag{ - Name: "kubernetes-endpoint", - EnvVar: "CI_KUBERNETES_ENDPOINT", - }, - cli.StringFlag{ - Name: "kubernetes-token", - EnvVar: "CI_KUBERNETES_TOKEN", - }, - }, -} - -func executeAction(c *cli.Context) (err error) { - path := c.Args().First() - if path == "" { - path = c.String("in") - } - - var reader io.ReadCloser - if path == "-" { - reader = os.Stdin - } else { - reader, err = os.Open(path) - if err != nil { - return err - } - } - defer reader.Close() - - config, err := pipeline.Parse(reader) - if err != nil { - return err - } - - var engine backend.Engine - if c.Bool("kubernetes") { - engine = kubernetes.New( - c.String("kubernetes-namepsace"), - c.String("kubernetes-endpoint"), - c.String("kubernetes-token"), - ) - } else { - engine, err = docker.NewEnv() - if err != nil { - return err - } - } - - ctx, cancel := context.WithTimeout(context.Background(), c.Duration("timeout")) - defer cancel() - ctx = interrupt.WithContext(ctx) - - return pipeline.New(config, - pipeline.WithContext(ctx), - pipeline.WithLogger(defaultLogger), - pipeline.WithTracer(defaultTracer), - pipeline.WithEngine(engine), - ).Run() -} - -var defaultLogger = pipeline.LogFunc(func(proc *backend.Step, rc multipart.Reader) error { - part, err := rc.NextPart() - if err != nil { - return err - } - io.Copy(os.Stderr, part) - return nil -}) - -var defaultTracer = pipeline.TraceFunc(func(state *pipeline.State) error { - if state.Process.Exited { - fmt.Printf("proc %q exited with status %d\n", state.Pipeline.Step.Name, state.Process.ExitCode) - } else { - fmt.Printf("proc %q started\n", state.Pipeline.Step.Name) - state.Pipeline.Step.Environment["CI_BUILD_STATUS"] = "success" - state.Pipeline.Step.Environment["CI_BUILD_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) - if state.Pipeline.Error != nil { - state.Pipeline.Step.Environment["CI_BUILD_STATUS"] = "failure" - } - } - return nil -}) diff --git a/cncd/pipeline/pipec/lint.go b/cncd/pipeline/pipec/lint.go deleted file mode 100644 index 9603b3e89..000000000 --- a/cncd/pipeline/pipec/lint.go +++ /dev/null @@ -1,54 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/frontend/yaml" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/frontend/yaml/linter" - - "github.com/kr/pretty" - "github.com/urfave/cli" -) - -var lintCommand = cli.Command{ - Name: "lint", - Usage: "lints the yaml file", - Action: lintAction, - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "trusted", - }, - cli.BoolFlag{ - Name: "pretty", - }, - }, -} - -func lintAction(c *cli.Context) error { - file := c.Args().First() - if file == "" { - return fmt.Errorf("Error: please provide a path the configuration file") - } - - conf, err := yaml.ParseFile(file) - if err != nil { - return err - } - - err = linter.New( - linter.WithTrusted( - c.Bool("trusted"), - ), - ).Lint(conf) - - if err != nil { - return err - } - - if c.Bool("pretty") { - pretty.Println(conf) - } - - fmt.Println("Lint complete. Yaml file is valid") - return nil -} diff --git a/cncd/pipeline/pipec/main.go b/cncd/pipeline/pipec/main.go deleted file mode 100644 index f573e2021..000000000 --- a/cncd/pipeline/pipec/main.go +++ /dev/null @@ -1,26 +0,0 @@ -package main - -import ( - "fmt" - "os" - - "github.com/urfave/cli" - - _ "github.com/joho/godotenv/autoload" -) - -func main() { - app := cli.NewApp() - app.Name = "pipec" - app.Usage = "pipec provides command line tools for the cncd runtime" - app.Commands = []cli.Command{ - compileCommand, - executeCommand, - lintCommand, - } - - if err := app.Run(os.Args); err != nil { - fmt.Println(err) - os.Exit(1) - } -} diff --git a/cncd/pipeline/piped/main.go b/cncd/pipeline/piped/main.go deleted file mode 100644 index a62164dd1..000000000 --- a/cncd/pipeline/piped/main.go +++ /dev/null @@ -1,314 +0,0 @@ -package main - -import ( - "context" - "encoding/json" - "io" - "io/ioutil" - "log" - "math" - "net/url" - "os" - "strconv" - "sync" - "time" - - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/backend" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/backend/docker" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/interrupt" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/multipart" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/rpc" - - _ "github.com/joho/godotenv/autoload" - "github.com/tevino/abool" - "github.com/urfave/cli" -) - -const ( - maxFileUpload = 5000000 - maxLogsUpload = 5000000 -) - -func main() { - app := cli.NewApp() - app.Name = "piped" - app.Usage = "piped stars a pipeline execution daemon" - app.Action = start - app.Flags = []cli.Flag{ - cli.StringFlag{ - Name: "endpoint", - EnvVar: "PIPED_ENDPOINT,PIPED_SERVER", - Value: "ws://localhost:9999", - }, - cli.StringFlag{ - Name: "token", - EnvVar: "PIPED_TOKEN,PIPED_SECRET", - }, - cli.DurationFlag{ - Name: "backoff", - EnvVar: "PIPED_BACKOFF", - Value: time.Second * 15, - }, - cli.IntFlag{ - Name: "retry-limit", - EnvVar: "PIPED_RETRY_LIMIT", - Value: math.MaxInt32, - }, - cli.StringFlag{ - Name: "platform", - EnvVar: "PIPED_PLATFORM", - Value: "linux/amd64", - }, - cli.Int64Flag{ - Name: "upload-limit", - EnvVar: "PIPED_UPLOAD_LIMIT", - Value: math.MaxInt32, - }, - } - app.Commands = []cli.Command{ - onceCommand, - } - - if err := app.Run(os.Args); err != nil { - log.Fatalln(err) - } -} - -func start(c *cli.Context) error { - endpoint, err := url.Parse( - c.String("endpoint"), - ) - if err != nil { - return err - } - filter := rpc.Filter{ - Labels: map[string]string{ - "platform": c.String("platform"), - }, - } - - client, err := rpc.NewClient( - endpoint.String(), - rpc.WithRetryLimit( - c.Int("retry-limit"), - ), - rpc.WithBackoff( - c.Duration("backoff"), - ), - rpc.WithToken( - c.String("token"), - ), - ) - if err != nil { - return err - } - defer client.Close() - - sigterm := abool.New() - ctx := context.Background() - ctx = interrupt.WithContextFunc(ctx, func() { - println("ctrl+c received, terminating process") - sigterm.Set() - }) - - for { - if sigterm.IsSet() { - return nil - } - if err := run(ctx, client, filter); err != nil { - return err - } - } -} - -func run(ctx context.Context, client rpc.Peer, filter rpc.Filter) error { - log.Println("pipeline: request next execution") - - // get the next job from the queue - work, err := client.Next(ctx, filter) - if err != nil { - return err - } - if work == nil { - return nil - } - log.Printf("pipeline: received next execution: %s", work.ID) - if os.Getenv("SUICIDE_MODE") != "" { - os.Exit(1) - } - // new docker engine - engine, err := docker.NewEnv() - if err != nil { - return err - } - - timeout := time.Hour - if minutes := work.Timeout; minutes != 0 { - timeout = time.Duration(minutes) * time.Minute - } - - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - cancelled := abool.New() - go func() { - werr := client.Wait(ctx, work.ID) - if werr != nil { - cancelled.SetTo(true) // TODO verify error is really an error - log.Printf("pipeline: cancel signal received: %s: %s", work.ID, werr) - cancel() - } else { - log.Printf("pipeline: cancel channel closed: %s", work.ID) - } - }() - - go func() { - for { - select { - case <-ctx.Done(): - log.Printf("pipeline: cancel ping loop: %s", work.ID) - return - case <-time.After(time.Minute): - log.Printf("pipeline: ping queue: %s", work.ID) - client.Extend(ctx, work.ID) - } - } - }() - - state := rpc.State{} - state.Started = time.Now().Unix() - err = client.Init(context.Background(), work.ID, state) - if err != nil { - log.Printf("pipeline: error signaling pipeline init: %s: %s", work.ID, err) - } - - var uploads sync.WaitGroup - defaultLogger := pipeline.LogFunc(func(proc *backend.Step, rc multipart.Reader) error { - part, rerr := rc.NextPart() - if rerr != nil { - return rerr - } - uploads.Add(1) - - var secrets []string - for _, secret := range work.Config.Secrets { - if secret.Mask { - secrets = append(secrets, secret.Value) - } - } - - limitedPart := io.LimitReader(part, maxLogsUpload) - logstream := rpc.NewLineWriter(client, work.ID, proc.Alias, secrets...) - io.Copy(logstream, limitedPart) - - file := &rpc.File{} - file.Mime = "application/json+logs" - file.Proc = proc.Alias - file.Name = "logs.json" - file.Data, _ = json.Marshal(logstream.Lines()) - file.Size = len(file.Data) - file.Time = time.Now().Unix() - - if serr := client.Upload(context.Background(), work.ID, file); serr != nil { - log.Printf("pipeline: cannot upload logs: %s: %s: %s", work.ID, file.Mime, serr) - } else { - log.Printf("pipeline: finish uploading logs: %s: step %s: %s", file.Mime, work.ID, proc.Alias) - } - - defer func() { - log.Printf("pipeline: finish uploading logs: %s: step %s", work.ID, proc.Alias) - uploads.Done() - }() - - part, rerr = rc.NextPart() - if rerr != nil { - return nil - } - // TODO should be configurable - limitedPart = io.LimitReader(part, maxFileUpload) - file = &rpc.File{} - file.Mime = part.Header().Get("Content-Type") - file.Proc = proc.Alias - file.Name = part.FileName() - file.Data, _ = ioutil.ReadAll(limitedPart) - file.Size = len(file.Data) - file.Time = time.Now().Unix() - - if serr := client.Upload(context.Background(), work.ID, file); serr != nil { - log.Printf("pipeline: cannot upload artifact: %s: %s: %s", work.ID, file.Mime, serr) - } else { - log.Printf("pipeline: finish uploading artifact: %s: step %s: %s", file.Mime, work.ID, proc.Alias) - } - return nil - }) - - defaultTracer := pipeline.TraceFunc(func(state *pipeline.State) error { - procState := rpc.State{ - Proc: state.Pipeline.Step.Alias, - Exited: state.Process.Exited, - ExitCode: state.Process.ExitCode, - Started: time.Now().Unix(), // TODO do not do this - Finished: time.Now().Unix(), - } - defer func() { - if uerr := client.Update(context.Background(), work.ID, procState); uerr != nil { - log.Printf("Pipeine: error updating pipeline step status: %s: %s: %s", work.ID, procState.Proc, uerr) - } - }() - if state.Process.Exited { - return nil - } - if state.Pipeline.Step.Environment == nil { - state.Pipeline.Step.Environment = map[string]string{} - } - state.Pipeline.Step.Environment["CI_BUILD_STATUS"] = "success" - state.Pipeline.Step.Environment["CI_BUILD_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) - state.Pipeline.Step.Environment["CI_BUILD_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) - - state.Pipeline.Step.Environment["CI_JOB_STATUS"] = "success" - state.Pipeline.Step.Environment["CI_JOB_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) - state.Pipeline.Step.Environment["CI_JOB_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) - - if state.Pipeline.Error != nil { - state.Pipeline.Step.Environment["CI_BUILD_STATUS"] = "failure" - state.Pipeline.Step.Environment["CI_JOB_STATUS"] = "failure" - } - return nil - }) - - err = pipeline.New(work.Config, - pipeline.WithContext(ctx), - pipeline.WithLogger(defaultLogger), - pipeline.WithTracer(defaultTracer), - pipeline.WithEngine(engine), - ).Run() - - state.Finished = time.Now().Unix() - state.Exited = true - if err != nil { - state.Error = err.Error() - if xerr, ok := err.(*pipeline.ExitError); ok { - state.ExitCode = xerr.Code - } - if xerr, ok := err.(*pipeline.OomError); ok { - state.ExitCode = xerr.Code - } - if cancelled.IsSet() { - state.ExitCode = 130 - } else if state.ExitCode == 0 { - state.ExitCode = 1 - } - } - - log.Printf("pipeline: execution complete: %s", work.ID) - - uploads.Wait() - - err = client.Done(context.Background(), work.ID, state) - if err != nil { - log.Printf("Pipeine: error signaling pipeline done: %s: %s", work.ID, err) - } - - return nil -} diff --git a/cncd/pipeline/piped/once.go b/cncd/pipeline/piped/once.go deleted file mode 100644 index 531265c90..000000000 --- a/cncd/pipeline/piped/once.go +++ /dev/null @@ -1,97 +0,0 @@ -package main - -import ( - "context" - "encoding/json" - "math" - "net/url" - "time" - - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/interrupt" - "github.com/woodpecker-ci/woodpecker/cncd/pipeline/pipeline/rpc" - - _ "github.com/joho/godotenv/autoload" - "github.com/urfave/cli" -) - -var onceCommand = cli.Command{ - Name: "once", - Usage: "execute one build", - Hidden: false, - Action: once, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "endpoint", - EnvVar: "PIPED_ENDPOINT,PIPED_SERVER", - Value: "ws://localhost:9999", - }, - cli.StringFlag{ - Name: "token", - EnvVar: "PIPED_TOKEN,PIPED_SECRET", - }, - cli.DurationFlag{ - Name: "backoff", - EnvVar: "PIPED_BACKOFF", - Value: time.Second * 15, - }, - cli.IntFlag{ - Name: "retry-limit", - EnvVar: "PIPED_RETRY_LIMIT", - Value: math.MaxInt32, - }, - cli.StringFlag{ - Name: "platform", - EnvVar: "PIPED_PLATFORM", - Value: "linux/amd64", - }, - cli.StringFlag{ - Name: "json", - EnvVar: "PIPED_JSON", - }, - }, -} - -func once(c *cli.Context) error { - endpoint, err := url.Parse( - c.String("endpoint"), - ) - if err != nil { - return err - } - - client, err := rpc.NewClient( - endpoint.String(), - rpc.WithRetryLimit( - c.Int("retry-limit"), - ), - rpc.WithBackoff( - c.Duration("backoff"), - ), - rpc.WithToken( - c.String("token"), - ), - ) - if err != nil { - return err - } - defer client.Close() - - ctx := context.Background() - ctx = interrupt.WithContextFunc(ctx, func() { - println("ctrl+c received, terminating process") - }) - - return run(ctx, &onceClient{client, c.String("json")}, rpc.NoFilter) -} - -type onceClient struct { - *rpc.Client - json string -} - -func (c *onceClient) Next(ctx context.Context, filter rpc.Filter) (*rpc.Pipeline, error) { - in := []byte(c.json) - out := new(rpc.Pipeline) - err := json.Unmarshal(in, out) - return out, err -} diff --git a/cncd/pipeline/pipeline/rpc/client.go b/cncd/pipeline/pipeline/rpc/client.go deleted file mode 100644 index 9040bc46b..000000000 --- a/cncd/pipeline/pipeline/rpc/client.go +++ /dev/null @@ -1,195 +0,0 @@ -package rpc - -import ( - "context" - "io" - "log" - "math" - "net/http" - "sync" - "time" - - "github.com/gorilla/websocket" - "github.com/sourcegraph/jsonrpc2" - websocketrpc "github.com/sourcegraph/jsonrpc2/websocket" -) - -const ( - methodNext = "next" - methodWait = "wait" - methodInit = "init" - methodDone = "done" - methodExtend = "extend" - methodUpdate = "update" - methodUpload = "upload" - methodLog = "log" -) - -type ( - uploadReq struct { - ID string `json:"id"` - File *File `json:"file"` - } - - updateReq struct { - ID string `json:"id"` - State State `json:"state"` - } - - logReq struct { - ID string `json:"id"` - Line *Line `json:"line"` - } -) - -const ( - defaultRetryClount = math.MaxInt32 - defaultBackoff = 10 * time.Second -) - -// Client represents an rpc client. -type Client struct { - sync.Mutex - - conn *jsonrpc2.Conn - done bool - retry int - backoff time.Duration - endpoint string - token string - headers map[string][]string -} - -// NewClient returns a new Client. -func NewClient(endpoint string, opts ...Option) (*Client, error) { - cli := &Client{ - endpoint: endpoint, - retry: defaultRetryClount, - backoff: defaultBackoff, - headers: map[string][]string{}, - } - for _, opt := range opts { - opt(cli) - } - err := cli.openRetry() - return cli, err -} - -// Next returns the next pipeline in the queue. -func (t *Client) Next(c context.Context, f Filter) (*Pipeline, error) { - res := new(Pipeline) - err := t.call(c, methodNext, f, res) - return res, err -} - -// Wait blocks until the pipeline is complete. -func (t *Client) Wait(c context.Context, id string) error { - // err := t.call(c, methodWait, id, nil) - // if err != nil && err.Error() == ErrCancelled.Error() { - // return ErrCancelled - // } - return t.call(c, methodWait, id, nil) -} - -// Init signals the pipeline is initialized. -func (t *Client) Init(c context.Context, id string, state State) error { - params := updateReq{id, state} - return t.call(c, methodInit, ¶ms, nil) -} - -// Done signals the pipeline is complete. -func (t *Client) Done(c context.Context, id string, state State) error { - params := updateReq{id, state} - return t.call(c, methodDone, ¶ms, nil) -} - -// Extend extends the pipeline deadline. -func (t *Client) Extend(c context.Context, id string) error { - return t.call(c, methodExtend, id, nil) -} - -// Update updates the pipeline state. -func (t *Client) Update(c context.Context, id string, state State) error { - params := updateReq{id, state} - return t.call(c, methodUpdate, ¶ms, nil) -} - -// Log writes the pipeline log entry. -func (t *Client) Log(c context.Context, id string, line *Line) error { - params := logReq{id, line} - return t.call(c, methodLog, ¶ms, nil) -} - -// Upload uploads the pipeline artifact. -func (t *Client) Upload(c context.Context, id string, file *File) error { - params := uploadReq{id, file} - return t.call(c, methodUpload, params, nil) -} - -// Close closes the client connection. -func (t *Client) Close() error { - t.Lock() - t.done = true - t.Unlock() - return t.conn.Close() -} - -// call makes the remote prodedure call. If the call fails due to connectivity -// issues the connection is re-establish and call re-attempted. -func (t *Client) call(ctx context.Context, name string, req, res interface{}) error { - if err := t.conn.Call(ctx, name, req, res); err == nil { - return nil - } else if err != jsonrpc2.ErrClosed && err != io.ErrUnexpectedEOF { - log.Printf("rpc: error making call: %s", err) - return err - } else { - log.Printf("rpc: error making call: connection closed: %s", err) - } - if err := t.openRetry(); err != nil { - return err - } - return t.conn.Call(ctx, name, req, res) -} - -// openRetry opens the connection and will retry on failure until -// the connection is successfully open, or the maximum retry count -// is exceeded. -func (t *Client) openRetry() error { - for i := 0; i < t.retry; i++ { - err := t.open() - if err == nil { - break - } - if err == io.EOF { - return err - } - - log.Printf("rpc: error re-connecting: %s", err) - <-time.After(t.backoff) - } - return nil -} - -// open creates a websocket connection to a peer and establishes a json -// rpc communication stream. -func (t *Client) open() error { - t.Lock() - defer t.Unlock() - if t.done { - return io.EOF - } - header := map[string][]string{ - "Content-Type": {"application/json-rpc"}, - "Authorization": {"Bearer " + t.token}, - } - for key, value := range t.headers { - header[key] = value - } - conn, _, err := websocket.DefaultDialer.Dial(t.endpoint, http.Header(header)) - if err != nil { - return err - } - stream := websocketrpc.NewObjectStream(conn) - t.conn = jsonrpc2.NewConn(context.Background(), stream, nil) - return nil -} diff --git a/cncd/pipeline/pipeline/rpc/client_test.go b/cncd/pipeline/pipeline/rpc/client_test.go deleted file mode 100644 index 9ab1e3e8e..000000000 --- a/cncd/pipeline/pipeline/rpc/client_test.go +++ /dev/null @@ -1 +0,0 @@ -package rpc diff --git a/cncd/pipeline/pipeline/rpc/option.go b/cncd/pipeline/pipeline/rpc/option.go deleted file mode 100644 index e08dce278..000000000 --- a/cncd/pipeline/pipeline/rpc/option.go +++ /dev/null @@ -1,36 +0,0 @@ -package rpc - -import "time" - -// Option configures a client option. -type Option func(*Client) - -// WithBackoff configures the backoff duration when attempting -// to re-connect to a server. -func WithBackoff(d time.Duration) Option { - return func(c *Client) { - c.backoff = d - } -} - -// WithRetryLimit configures the maximum number of retries when -// connecting to the server. -func WithRetryLimit(i int) Option { - return func(c *Client) { - c.retry = i - } -} - -// WithToken configures the client authorization token. -func WithToken(t string) Option { - return func(c *Client) { - c.token = t - } -} - -// WithHeader configures the client header. -func WithHeader(key, value string) Option { - return func(c *Client) { - c.headers[key] = []string{value} - } -} diff --git a/cncd/pipeline/pipeline/rpc/option_test.go b/cncd/pipeline/pipeline/rpc/option_test.go deleted file mode 100644 index 9ab1e3e8e..000000000 --- a/cncd/pipeline/pipeline/rpc/option_test.go +++ /dev/null @@ -1 +0,0 @@ -package rpc diff --git a/cncd/pipeline/pipeline/rpc/server.go b/cncd/pipeline/pipeline/rpc/server.go deleted file mode 100644 index 65eb0f438..000000000 --- a/cncd/pipeline/pipeline/rpc/server.go +++ /dev/null @@ -1,151 +0,0 @@ -package rpc - -import ( - "context" - "encoding/json" - "errors" - "net/http" - - "github.com/gorilla/websocket" - "github.com/sourcegraph/jsonrpc2" - websocketrpc "github.com/sourcegraph/jsonrpc2/websocket" -) - -// errNoSuchMethod is returned when the name rpc method does not exist. -var errNoSuchMethod = errors.New("No such rpc method") - -// noContext is an empty context used when no context is required. -var noContext = context.Background() - -// Server represents an rpc server. -type Server struct { - peer Peer -} - -// NewServer returns an rpc Server. -func NewServer(peer Peer) *Server { - return &Server{peer} -} - -// ServeHTTP implements an http.Handler that answers rpc requests. -func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { - upgrader := websocket.Upgrader{} - c, err := upgrader.Upgrade(w, r, nil) - if err != nil { - return - } - ctx, cancel := context.WithCancel(context.Background()) - conn := jsonrpc2.NewConn(ctx, - websocketrpc.NewObjectStream(c), - jsonrpc2.HandlerWithError(s.router), - ) - defer func() { - cancel() - conn.Close() - }() - <-conn.DisconnectNotify() -} - -// router implements an jsonrpc2.Handler that answers RPC requests. -func (s *Server) router(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) (interface{}, error) { - switch req.Method { - case methodNext: - return s.next(ctx, req) - case methodWait: - return s.wait(ctx, req) - case methodInit: - return s.init(ctx, req) - case methodDone: - return s.done(ctx, req) - case methodExtend: - return s.extend(ctx, req) - case methodUpdate: - return s.update(req) - case methodLog: - return s.log(req) - case methodUpload: - return s.upload(req) - default: - return nil, errNoSuchMethod - } -} - -// next unmarshals the rpc request parameters and invokes the peer.Next -// procedure. The results are retuned and written to the rpc response. -func (s *Server) next(ctx context.Context, req *jsonrpc2.Request) (interface{}, error) { - in := Filter{} - if err := json.Unmarshal([]byte(*req.Params), &in); err != nil { - return nil, err - } - return s.peer.Next(ctx, in) -} - -// wait unmarshals the rpc request parameters and invokes the peer.Wait -// procedure. The results are retuned and written to the rpc response. -func (s *Server) wait(ctx context.Context, req *jsonrpc2.Request) (interface{}, error) { - var id string - err := json.Unmarshal([]byte(*req.Params), &id) - if err != nil { - return nil, err - } - return nil, s.peer.Wait(ctx, id) -} - -// init unmarshals the rpc request parameters and invokes the peer.Init -// procedure. The results are retuned and written to the rpc response. -func (s *Server) init(ctx context.Context, req *jsonrpc2.Request) (interface{}, error) { - in := new(updateReq) - if err := json.Unmarshal([]byte(*req.Params), in); err != nil { - return nil, err - } - return nil, s.peer.Init(ctx, in.ID, in.State) -} - -// done unmarshals the rpc request parameters and invokes the peer.Done -// procedure. The results are retuned and written to the rpc response. -func (s *Server) done(ctx context.Context, req *jsonrpc2.Request) (interface{}, error) { - in := new(updateReq) - if err := json.Unmarshal([]byte(*req.Params), in); err != nil { - return nil, err - } - return nil, s.peer.Done(ctx, in.ID, in.State) -} - -// extend unmarshals the rpc request parameters and invokes the peer.Extend -// procedure. The results are retuned and written to the rpc response. -func (s *Server) extend(ctx context.Context, req *jsonrpc2.Request) (interface{}, error) { - var id string - err := json.Unmarshal([]byte(*req.Params), &id) - if err != nil { - return nil, err - } - return nil, s.peer.Extend(ctx, id) -} - -// update unmarshals the rpc request parameters and invokes the peer.Update -// procedure. The results are retuned and written to the rpc response. -func (s *Server) update(req *jsonrpc2.Request) (interface{}, error) { - in := new(updateReq) - if err := json.Unmarshal([]byte(*req.Params), in); err != nil { - return nil, err - } - return nil, s.peer.Update(noContext, in.ID, in.State) -} - -// log unmarshals the rpc request parameters and invokes the peer.Log -// procedure. The results are retuned and written to the rpc response. -func (s *Server) log(req *jsonrpc2.Request) (interface{}, error) { - in := new(logReq) - if err := json.Unmarshal([]byte(*req.Params), in); err != nil { - return nil, err - } - return nil, s.peer.Log(noContext, in.ID, in.Line) -} - -func (s *Server) upload(req *jsonrpc2.Request) (interface{}, error) { - in := new(uploadReq) - if err := json.Unmarshal([]byte(*req.Params), in); err != nil { - return nil, err - } - return nil, s.peer.Upload(noContext, in.ID, in.File) -} diff --git a/cncd/pipeline/pipeline/rpc/server_test.go b/cncd/pipeline/pipeline/rpc/server_test.go deleted file mode 100644 index 9ab1e3e8e..000000000 --- a/cncd/pipeline/pipeline/rpc/server_test.go +++ /dev/null @@ -1 +0,0 @@ -package rpc diff --git a/drone-go/drone/client.go b/drone-go/drone/client.go index 2d9f9efa2..b5c6da7d7 100644 --- a/drone-go/drone/client.go +++ b/drone-go/drone/client.go @@ -153,7 +153,7 @@ func (c *client) RepoChown(owner string, name string) (*Repo, error) { return out, err } -// RepoRepair repais the repository hooks. +// RepoRepair repairs the repository hooks. func (c *client) RepoRepair(owner string, name string) error { uri := fmt.Sprintf(pathRepair, c.addr, owner, name) return c.post(uri, nil, nil) diff --git a/go.mod b/go.mod index 4a3add9ca..5d7690d9b 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,6 @@ require ( github.com/google/go-github v0.0.0-20151120211125-47f2593dad19 github.com/google/go-querystring v1.0.0 // indirect github.com/gorilla/securecookie v1.1.1 - github.com/gorilla/websocket v1.4.2 github.com/hashicorp/go-version v1.3.0 // indirect github.com/jackspirou/syscerts v0.0.0-20160531025014-b68f5469dff1 github.com/joho/godotenv v1.3.0 @@ -52,7 +51,6 @@ require ( github.com/rs/zerolog v1.18.0 github.com/russross/meddler v1.0.0 github.com/sirupsen/logrus v1.6.0 - github.com/sourcegraph/jsonrpc2 v0.0.0-20200429184054-15c2290dcb37 github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.5.1 github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5 diff --git a/go.sum b/go.sum index 348878ce2..f87455c29 100644 --- a/go.sum +++ b/go.sum @@ -121,9 +121,6 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -212,8 +209,6 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sourcegraph/jsonrpc2 v0.0.0-20200429184054-15c2290dcb37 h1:marA1XQDC7N870zmSFIoHZpIUduK80USeY0Rkuflgp4= -github.com/sourcegraph/jsonrpc2 v0.0.0-20200429184054-15c2290dcb37/go.mod h1:ZafdZgk/axhT1cvZAPOhw+95nz2I/Ra5qMlU4gTRwIo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= diff --git a/remote/github/parse.go b/remote/github/parse.go index 8ccf47b41..0d564aa0e 100644 --- a/remote/github/parse.go +++ b/remote/github/parse.go @@ -37,7 +37,7 @@ const ( stateOpen = "open" ) -// parseHook parses a Bitbucket hook from an http.Request request and returns +// parseHook parses a GitHub hook from an http.Request request and returns // Repo and Build detail. If a hook type is unsupported nil values are returned. func parseHook(r *http.Request, merge bool) (*model.Repo, *model.Build, error) { var reader io.Reader = r.Body diff --git a/server/swagger/files/swagger.yml b/server/swagger/files/swagger.yml index efe21c2da..3394afb32 100644 --- a/server/swagger/files/swagger.yml +++ b/server/swagger/files/swagger.yml @@ -244,36 +244,6 @@ paths: description: | Unable to find the Repository in the database - /repos/{owner}/{name}/builds/{number}: - get: - parameters: - - name: owner - in: path - type: string - description: owner of the repository - - name: name - in: path - type: string - description: name of the repository - - name: number - in: path - type: integer - description: sequential build number - tags: - - Builds - summary: Get a build - description: Returns the repository build by number. - security: - - accessToken: [] - responses: - 200: - description: The build. - schema: - $ref: "#/definitions/Build" - 404: - description: | - Unable to find the Repository or Build - /repos/{owner}/{name}/builds/{number}: get: diff --git a/vendor/github.com/gorilla/websocket/.gitignore b/vendor/github.com/gorilla/websocket/.gitignore deleted file mode 100644 index cd3fcd1ef..000000000 --- a/vendor/github.com/gorilla/websocket/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe - -.idea/ -*.iml diff --git a/vendor/github.com/gorilla/websocket/AUTHORS b/vendor/github.com/gorilla/websocket/AUTHORS deleted file mode 100644 index 1931f4006..000000000 --- a/vendor/github.com/gorilla/websocket/AUTHORS +++ /dev/null @@ -1,9 +0,0 @@ -# This is the official list of Gorilla WebSocket authors for copyright -# purposes. -# -# Please keep the list sorted. - -Gary Burd -Google LLC (https://opensource.google.com/) -Joachim Bauch - diff --git a/vendor/github.com/gorilla/websocket/LICENSE b/vendor/github.com/gorilla/websocket/LICENSE deleted file mode 100644 index 9171c9722..000000000 --- a/vendor/github.com/gorilla/websocket/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gorilla/websocket/README.md b/vendor/github.com/gorilla/websocket/README.md deleted file mode 100644 index 19aa2e75c..000000000 --- a/vendor/github.com/gorilla/websocket/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# Gorilla WebSocket - -[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket) -[![CircleCI](https://circleci.com/gh/gorilla/websocket.svg?style=svg)](https://circleci.com/gh/gorilla/websocket) - -Gorilla WebSocket is a [Go](http://golang.org/) implementation of the -[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. - -### Documentation - -* [API Reference](https://pkg.go.dev/github.com/gorilla/websocket?tab=doc) -* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat) -* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command) -* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo) -* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch) - -### Status - -The Gorilla WebSocket package provides a complete and tested implementation of -the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The -package API is stable. - -### Installation - - go get github.com/gorilla/websocket - -### Protocol Compliance - -The Gorilla WebSocket package passes the server tests in the [Autobahn Test -Suite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn -subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn). - -### Gorilla WebSocket compared with other packages - - - - - - - - - - - - - - - - - - -
github.com/gorillagolang.org/x/net
RFC 6455 Features
Passes Autobahn Test SuiteYesNo
Receive fragmented messageYesNo, see note 1
Send close messageYesNo
Send pings and receive pongsYesNo
Get the type of a received data messageYesYes, see note 2
Other Features
Compression ExtensionsExperimentalNo
Read message using io.ReaderYesNo, see note 3
Write message using io.WriteCloserYesNo, see note 3
- -Notes: - -1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html). -2. The application can get the type of a received data message by implementing - a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal) - function. -3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries. - Read returns when the input buffer is full or a frame boundary is - encountered. Each call to Write sends a single frame message. The Gorilla - io.Reader and io.WriteCloser operate on a single WebSocket message. - diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go deleted file mode 100644 index 962c06a39..000000000 --- a/vendor/github.com/gorilla/websocket/client.go +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bytes" - "context" - "crypto/tls" - "errors" - "io" - "io/ioutil" - "net" - "net/http" - "net/http/httptrace" - "net/url" - "strings" - "time" -) - -// ErrBadHandshake is returned when the server response to opening handshake is -// invalid. -var ErrBadHandshake = errors.New("websocket: bad handshake") - -var errInvalidCompression = errors.New("websocket: invalid compression negotiation") - -// NewClient creates a new client connection using the given net connection. -// The URL u specifies the host and request URI. Use requestHeader to specify -// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies -// (Cookie). Use the response.Header to get the selected subprotocol -// (Sec-WebSocket-Protocol) and cookies (Set-Cookie). -// -// If the WebSocket handshake fails, ErrBadHandshake is returned along with a -// non-nil *http.Response so that callers can handle redirects, authentication, -// etc. -// -// Deprecated: Use Dialer instead. -func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) { - d := Dialer{ - ReadBufferSize: readBufSize, - WriteBufferSize: writeBufSize, - NetDial: func(net, addr string) (net.Conn, error) { - return netConn, nil - }, - } - return d.Dial(u.String(), requestHeader) -} - -// A Dialer contains options for connecting to WebSocket server. -type Dialer struct { - // NetDial specifies the dial function for creating TCP connections. If - // NetDial is nil, net.Dial is used. - NetDial func(network, addr string) (net.Conn, error) - - // NetDialContext specifies the dial function for creating TCP connections. If - // NetDialContext is nil, net.DialContext is used. - NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error) - - // Proxy specifies a function to return a proxy for a given - // Request. If the function returns a non-nil error, the - // request is aborted with the provided error. - // If Proxy is nil or returns a nil *URL, no proxy is used. - Proxy func(*http.Request) (*url.URL, error) - - // TLSClientConfig specifies the TLS configuration to use with tls.Client. - // If nil, the default configuration is used. - TLSClientConfig *tls.Config - - // HandshakeTimeout specifies the duration for the handshake to complete. - HandshakeTimeout time.Duration - - // ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer - // size is zero, then a useful default size is used. The I/O buffer sizes - // do not limit the size of the messages that can be sent or received. - ReadBufferSize, WriteBufferSize int - - // WriteBufferPool is a pool of buffers for write operations. If the value - // is not set, then write buffers are allocated to the connection for the - // lifetime of the connection. - // - // A pool is most useful when the application has a modest volume of writes - // across a large number of connections. - // - // Applications should use a single pool for each unique value of - // WriteBufferSize. - WriteBufferPool BufferPool - - // Subprotocols specifies the client's requested subprotocols. - Subprotocols []string - - // EnableCompression specifies if the client should attempt to negotiate - // per message compression (RFC 7692). Setting this value to true does not - // guarantee that compression will be supported. Currently only "no context - // takeover" modes are supported. - EnableCompression bool - - // Jar specifies the cookie jar. - // If Jar is nil, cookies are not sent in requests and ignored - // in responses. - Jar http.CookieJar -} - -// Dial creates a new client connection by calling DialContext with a background context. -func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { - return d.DialContext(context.Background(), urlStr, requestHeader) -} - -var errMalformedURL = errors.New("malformed ws or wss URL") - -func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) { - hostPort = u.Host - hostNoPort = u.Host - if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") { - hostNoPort = hostNoPort[:i] - } else { - switch u.Scheme { - case "wss": - hostPort += ":443" - case "https": - hostPort += ":443" - default: - hostPort += ":80" - } - } - return hostPort, hostNoPort -} - -// DefaultDialer is a dialer with all fields set to the default values. -var DefaultDialer = &Dialer{ - Proxy: http.ProxyFromEnvironment, - HandshakeTimeout: 45 * time.Second, -} - -// nilDialer is dialer to use when receiver is nil. -var nilDialer = *DefaultDialer - -// DialContext creates a new client connection. Use requestHeader to specify the -// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie). -// Use the response.Header to get the selected subprotocol -// (Sec-WebSocket-Protocol) and cookies (Set-Cookie). -// -// The context will be used in the request and in the Dialer. -// -// If the WebSocket handshake fails, ErrBadHandshake is returned along with a -// non-nil *http.Response so that callers can handle redirects, authentication, -// etcetera. The response body may not contain the entire response and does not -// need to be closed by the application. -func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { - if d == nil { - d = &nilDialer - } - - challengeKey, err := generateChallengeKey() - if err != nil { - return nil, nil, err - } - - u, err := url.Parse(urlStr) - if err != nil { - return nil, nil, err - } - - switch u.Scheme { - case "ws": - u.Scheme = "http" - case "wss": - u.Scheme = "https" - default: - return nil, nil, errMalformedURL - } - - if u.User != nil { - // User name and password are not allowed in websocket URIs. - return nil, nil, errMalformedURL - } - - req := &http.Request{ - Method: "GET", - URL: u, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: make(http.Header), - Host: u.Host, - } - req = req.WithContext(ctx) - - // Set the cookies present in the cookie jar of the dialer - if d.Jar != nil { - for _, cookie := range d.Jar.Cookies(u) { - req.AddCookie(cookie) - } - } - - // Set the request headers using the capitalization for names and values in - // RFC examples. Although the capitalization shouldn't matter, there are - // servers that depend on it. The Header.Set method is not used because the - // method canonicalizes the header names. - req.Header["Upgrade"] = []string{"websocket"} - req.Header["Connection"] = []string{"Upgrade"} - req.Header["Sec-WebSocket-Key"] = []string{challengeKey} - req.Header["Sec-WebSocket-Version"] = []string{"13"} - if len(d.Subprotocols) > 0 { - req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")} - } - for k, vs := range requestHeader { - switch { - case k == "Host": - if len(vs) > 0 { - req.Host = vs[0] - } - case k == "Upgrade" || - k == "Connection" || - k == "Sec-Websocket-Key" || - k == "Sec-Websocket-Version" || - k == "Sec-Websocket-Extensions" || - (k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0): - return nil, nil, errors.New("websocket: duplicate header not allowed: " + k) - case k == "Sec-Websocket-Protocol": - req.Header["Sec-WebSocket-Protocol"] = vs - default: - req.Header[k] = vs - } - } - - if d.EnableCompression { - req.Header["Sec-WebSocket-Extensions"] = []string{"permessage-deflate; server_no_context_takeover; client_no_context_takeover"} - } - - if d.HandshakeTimeout != 0 { - var cancel func() - ctx, cancel = context.WithTimeout(ctx, d.HandshakeTimeout) - defer cancel() - } - - // Get network dial function. - var netDial func(network, add string) (net.Conn, error) - - if d.NetDialContext != nil { - netDial = func(network, addr string) (net.Conn, error) { - return d.NetDialContext(ctx, network, addr) - } - } else if d.NetDial != nil { - netDial = d.NetDial - } else { - netDialer := &net.Dialer{} - netDial = func(network, addr string) (net.Conn, error) { - return netDialer.DialContext(ctx, network, addr) - } - } - - // If needed, wrap the dial function to set the connection deadline. - if deadline, ok := ctx.Deadline(); ok { - forwardDial := netDial - netDial = func(network, addr string) (net.Conn, error) { - c, err := forwardDial(network, addr) - if err != nil { - return nil, err - } - err = c.SetDeadline(deadline) - if err != nil { - c.Close() - return nil, err - } - return c, nil - } - } - - // If needed, wrap the dial function to connect through a proxy. - if d.Proxy != nil { - proxyURL, err := d.Proxy(req) - if err != nil { - return nil, nil, err - } - if proxyURL != nil { - dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial)) - if err != nil { - return nil, nil, err - } - netDial = dialer.Dial - } - } - - hostPort, hostNoPort := hostPortNoPort(u) - trace := httptrace.ContextClientTrace(ctx) - if trace != nil && trace.GetConn != nil { - trace.GetConn(hostPort) - } - - netConn, err := netDial("tcp", hostPort) - if trace != nil && trace.GotConn != nil { - trace.GotConn(httptrace.GotConnInfo{ - Conn: netConn, - }) - } - if err != nil { - return nil, nil, err - } - - defer func() { - if netConn != nil { - netConn.Close() - } - }() - - if u.Scheme == "https" { - cfg := cloneTLSConfig(d.TLSClientConfig) - if cfg.ServerName == "" { - cfg.ServerName = hostNoPort - } - tlsConn := tls.Client(netConn, cfg) - netConn = tlsConn - - var err error - if trace != nil { - err = doHandshakeWithTrace(trace, tlsConn, cfg) - } else { - err = doHandshake(tlsConn, cfg) - } - - if err != nil { - return nil, nil, err - } - } - - conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize, d.WriteBufferPool, nil, nil) - - if err := req.Write(netConn); err != nil { - return nil, nil, err - } - - if trace != nil && trace.GotFirstResponseByte != nil { - if peek, err := conn.br.Peek(1); err == nil && len(peek) == 1 { - trace.GotFirstResponseByte() - } - } - - resp, err := http.ReadResponse(conn.br, req) - if err != nil { - return nil, nil, err - } - - if d.Jar != nil { - if rc := resp.Cookies(); len(rc) > 0 { - d.Jar.SetCookies(u, rc) - } - } - - if resp.StatusCode != 101 || - !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") || - !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") || - resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) { - // Before closing the network connection on return from this - // function, slurp up some of the response to aid application - // debugging. - buf := make([]byte, 1024) - n, _ := io.ReadFull(resp.Body, buf) - resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n])) - return nil, resp, ErrBadHandshake - } - - for _, ext := range parseExtensions(resp.Header) { - if ext[""] != "permessage-deflate" { - continue - } - _, snct := ext["server_no_context_takeover"] - _, cnct := ext["client_no_context_takeover"] - if !snct || !cnct { - return nil, resp, errInvalidCompression - } - conn.newCompressionWriter = compressNoContextTakeover - conn.newDecompressionReader = decompressNoContextTakeover - break - } - - resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{})) - conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol") - - netConn.SetDeadline(time.Time{}) - netConn = nil // to avoid close in defer. - return conn, resp, nil -} - -func doHandshake(tlsConn *tls.Conn, cfg *tls.Config) error { - if err := tlsConn.Handshake(); err != nil { - return err - } - if !cfg.InsecureSkipVerify { - if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/gorilla/websocket/client_clone.go b/vendor/github.com/gorilla/websocket/client_clone.go deleted file mode 100644 index 4f0d94372..000000000 --- a/vendor/github.com/gorilla/websocket/client_clone.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.8 - -package websocket - -import "crypto/tls" - -func cloneTLSConfig(cfg *tls.Config) *tls.Config { - if cfg == nil { - return &tls.Config{} - } - return cfg.Clone() -} diff --git a/vendor/github.com/gorilla/websocket/client_clone_legacy.go b/vendor/github.com/gorilla/websocket/client_clone_legacy.go deleted file mode 100644 index babb007fb..000000000 --- a/vendor/github.com/gorilla/websocket/client_clone_legacy.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.8 - -package websocket - -import "crypto/tls" - -// cloneTLSConfig clones all public fields except the fields -// SessionTicketsDisabled and SessionTicketKey. This avoids copying the -// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a -// config in active use. -func cloneTLSConfig(cfg *tls.Config) *tls.Config { - if cfg == nil { - return &tls.Config{} - } - return &tls.Config{ - Rand: cfg.Rand, - Time: cfg.Time, - Certificates: cfg.Certificates, - NameToCertificate: cfg.NameToCertificate, - GetCertificate: cfg.GetCertificate, - RootCAs: cfg.RootCAs, - NextProtos: cfg.NextProtos, - ServerName: cfg.ServerName, - ClientAuth: cfg.ClientAuth, - ClientCAs: cfg.ClientCAs, - InsecureSkipVerify: cfg.InsecureSkipVerify, - CipherSuites: cfg.CipherSuites, - PreferServerCipherSuites: cfg.PreferServerCipherSuites, - ClientSessionCache: cfg.ClientSessionCache, - MinVersion: cfg.MinVersion, - MaxVersion: cfg.MaxVersion, - CurvePreferences: cfg.CurvePreferences, - } -} diff --git a/vendor/github.com/gorilla/websocket/compression.go b/vendor/github.com/gorilla/websocket/compression.go deleted file mode 100644 index 813ffb1e8..000000000 --- a/vendor/github.com/gorilla/websocket/compression.go +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "compress/flate" - "errors" - "io" - "strings" - "sync" -) - -const ( - minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6 - maxCompressionLevel = flate.BestCompression - defaultCompressionLevel = 1 -) - -var ( - flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool - flateReaderPool = sync.Pool{New: func() interface{} { - return flate.NewReader(nil) - }} -) - -func decompressNoContextTakeover(r io.Reader) io.ReadCloser { - const tail = - // Add four bytes as specified in RFC - "\x00\x00\xff\xff" + - // Add final block to squelch unexpected EOF error from flate reader. - "\x01\x00\x00\xff\xff" - - fr, _ := flateReaderPool.Get().(io.ReadCloser) - fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil) - return &flateReadWrapper{fr} -} - -func isValidCompressionLevel(level int) bool { - return minCompressionLevel <= level && level <= maxCompressionLevel -} - -func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser { - p := &flateWriterPools[level-minCompressionLevel] - tw := &truncWriter{w: w} - fw, _ := p.Get().(*flate.Writer) - if fw == nil { - fw, _ = flate.NewWriter(tw, level) - } else { - fw.Reset(tw) - } - return &flateWriteWrapper{fw: fw, tw: tw, p: p} -} - -// truncWriter is an io.Writer that writes all but the last four bytes of the -// stream to another io.Writer. -type truncWriter struct { - w io.WriteCloser - n int - p [4]byte -} - -func (w *truncWriter) Write(p []byte) (int, error) { - n := 0 - - // fill buffer first for simplicity. - if w.n < len(w.p) { - n = copy(w.p[w.n:], p) - p = p[n:] - w.n += n - if len(p) == 0 { - return n, nil - } - } - - m := len(p) - if m > len(w.p) { - m = len(w.p) - } - - if nn, err := w.w.Write(w.p[:m]); err != nil { - return n + nn, err - } - - copy(w.p[:], w.p[m:]) - copy(w.p[len(w.p)-m:], p[len(p)-m:]) - nn, err := w.w.Write(p[:len(p)-m]) - return n + nn, err -} - -type flateWriteWrapper struct { - fw *flate.Writer - tw *truncWriter - p *sync.Pool -} - -func (w *flateWriteWrapper) Write(p []byte) (int, error) { - if w.fw == nil { - return 0, errWriteClosed - } - return w.fw.Write(p) -} - -func (w *flateWriteWrapper) Close() error { - if w.fw == nil { - return errWriteClosed - } - err1 := w.fw.Flush() - w.p.Put(w.fw) - w.fw = nil - if w.tw.p != [4]byte{0, 0, 0xff, 0xff} { - return errors.New("websocket: internal error, unexpected bytes at end of flate stream") - } - err2 := w.tw.w.Close() - if err1 != nil { - return err1 - } - return err2 -} - -type flateReadWrapper struct { - fr io.ReadCloser -} - -func (r *flateReadWrapper) Read(p []byte) (int, error) { - if r.fr == nil { - return 0, io.ErrClosedPipe - } - n, err := r.fr.Read(p) - if err == io.EOF { - // Preemptively place the reader back in the pool. This helps with - // scenarios where the application does not call NextReader() soon after - // this final read. - r.Close() - } - return n, err -} - -func (r *flateReadWrapper) Close() error { - if r.fr == nil { - return io.ErrClosedPipe - } - err := r.fr.Close() - flateReaderPool.Put(r.fr) - r.fr = nil - return err -} diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go deleted file mode 100644 index ca46d2f79..000000000 --- a/vendor/github.com/gorilla/websocket/conn.go +++ /dev/null @@ -1,1201 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "encoding/binary" - "errors" - "io" - "io/ioutil" - "math/rand" - "net" - "strconv" - "sync" - "time" - "unicode/utf8" -) - -const ( - // Frame header byte 0 bits from Section 5.2 of RFC 6455 - finalBit = 1 << 7 - rsv1Bit = 1 << 6 - rsv2Bit = 1 << 5 - rsv3Bit = 1 << 4 - - // Frame header byte 1 bits from Section 5.2 of RFC 6455 - maskBit = 1 << 7 - - maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask - maxControlFramePayloadSize = 125 - - writeWait = time.Second - - defaultReadBufferSize = 4096 - defaultWriteBufferSize = 4096 - - continuationFrame = 0 - noFrame = -1 -) - -// Close codes defined in RFC 6455, section 11.7. -const ( - CloseNormalClosure = 1000 - CloseGoingAway = 1001 - CloseProtocolError = 1002 - CloseUnsupportedData = 1003 - CloseNoStatusReceived = 1005 - CloseAbnormalClosure = 1006 - CloseInvalidFramePayloadData = 1007 - ClosePolicyViolation = 1008 - CloseMessageTooBig = 1009 - CloseMandatoryExtension = 1010 - CloseInternalServerErr = 1011 - CloseServiceRestart = 1012 - CloseTryAgainLater = 1013 - CloseTLSHandshake = 1015 -) - -// The message types are defined in RFC 6455, section 11.8. -const ( - // TextMessage denotes a text data message. The text message payload is - // interpreted as UTF-8 encoded text data. - TextMessage = 1 - - // BinaryMessage denotes a binary data message. - BinaryMessage = 2 - - // CloseMessage denotes a close control message. The optional message - // payload contains a numeric code and text. Use the FormatCloseMessage - // function to format a close message payload. - CloseMessage = 8 - - // PingMessage denotes a ping control message. The optional message payload - // is UTF-8 encoded text. - PingMessage = 9 - - // PongMessage denotes a pong control message. The optional message payload - // is UTF-8 encoded text. - PongMessage = 10 -) - -// ErrCloseSent is returned when the application writes a message to the -// connection after sending a close message. -var ErrCloseSent = errors.New("websocket: close sent") - -// ErrReadLimit is returned when reading a message that is larger than the -// read limit set for the connection. -var ErrReadLimit = errors.New("websocket: read limit exceeded") - -// netError satisfies the net Error interface. -type netError struct { - msg string - temporary bool - timeout bool -} - -func (e *netError) Error() string { return e.msg } -func (e *netError) Temporary() bool { return e.temporary } -func (e *netError) Timeout() bool { return e.timeout } - -// CloseError represents a close message. -type CloseError struct { - // Code is defined in RFC 6455, section 11.7. - Code int - - // Text is the optional text payload. - Text string -} - -func (e *CloseError) Error() string { - s := []byte("websocket: close ") - s = strconv.AppendInt(s, int64(e.Code), 10) - switch e.Code { - case CloseNormalClosure: - s = append(s, " (normal)"...) - case CloseGoingAway: - s = append(s, " (going away)"...) - case CloseProtocolError: - s = append(s, " (protocol error)"...) - case CloseUnsupportedData: - s = append(s, " (unsupported data)"...) - case CloseNoStatusReceived: - s = append(s, " (no status)"...) - case CloseAbnormalClosure: - s = append(s, " (abnormal closure)"...) - case CloseInvalidFramePayloadData: - s = append(s, " (invalid payload data)"...) - case ClosePolicyViolation: - s = append(s, " (policy violation)"...) - case CloseMessageTooBig: - s = append(s, " (message too big)"...) - case CloseMandatoryExtension: - s = append(s, " (mandatory extension missing)"...) - case CloseInternalServerErr: - s = append(s, " (internal server error)"...) - case CloseTLSHandshake: - s = append(s, " (TLS handshake error)"...) - } - if e.Text != "" { - s = append(s, ": "...) - s = append(s, e.Text...) - } - return string(s) -} - -// IsCloseError returns boolean indicating whether the error is a *CloseError -// with one of the specified codes. -func IsCloseError(err error, codes ...int) bool { - if e, ok := err.(*CloseError); ok { - for _, code := range codes { - if e.Code == code { - return true - } - } - } - return false -} - -// IsUnexpectedCloseError returns boolean indicating whether the error is a -// *CloseError with a code not in the list of expected codes. -func IsUnexpectedCloseError(err error, expectedCodes ...int) bool { - if e, ok := err.(*CloseError); ok { - for _, code := range expectedCodes { - if e.Code == code { - return false - } - } - return true - } - return false -} - -var ( - errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true, temporary: true} - errUnexpectedEOF = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()} - errBadWriteOpCode = errors.New("websocket: bad write message type") - errWriteClosed = errors.New("websocket: write closed") - errInvalidControlFrame = errors.New("websocket: invalid control frame") -) - -func newMaskKey() [4]byte { - n := rand.Uint32() - return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)} -} - -func hideTempErr(err error) error { - if e, ok := err.(net.Error); ok && e.Temporary() { - err = &netError{msg: e.Error(), timeout: e.Timeout()} - } - return err -} - -func isControl(frameType int) bool { - return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage -} - -func isData(frameType int) bool { - return frameType == TextMessage || frameType == BinaryMessage -} - -var validReceivedCloseCodes = map[int]bool{ - // see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number - - CloseNormalClosure: true, - CloseGoingAway: true, - CloseProtocolError: true, - CloseUnsupportedData: true, - CloseNoStatusReceived: false, - CloseAbnormalClosure: false, - CloseInvalidFramePayloadData: true, - ClosePolicyViolation: true, - CloseMessageTooBig: true, - CloseMandatoryExtension: true, - CloseInternalServerErr: true, - CloseServiceRestart: true, - CloseTryAgainLater: true, - CloseTLSHandshake: false, -} - -func isValidReceivedCloseCode(code int) bool { - return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999) -} - -// BufferPool represents a pool of buffers. The *sync.Pool type satisfies this -// interface. The type of the value stored in a pool is not specified. -type BufferPool interface { - // Get gets a value from the pool or returns nil if the pool is empty. - Get() interface{} - // Put adds a value to the pool. - Put(interface{}) -} - -// writePoolData is the type added to the write buffer pool. This wrapper is -// used to prevent applications from peeking at and depending on the values -// added to the pool. -type writePoolData struct{ buf []byte } - -// The Conn type represents a WebSocket connection. -type Conn struct { - conn net.Conn - isServer bool - subprotocol string - - // Write fields - mu chan struct{} // used as mutex to protect write to conn - writeBuf []byte // frame is constructed in this buffer. - writePool BufferPool - writeBufSize int - writeDeadline time.Time - writer io.WriteCloser // the current writer returned to the application - isWriting bool // for best-effort concurrent write detection - - writeErrMu sync.Mutex - writeErr error - - enableWriteCompression bool - compressionLevel int - newCompressionWriter func(io.WriteCloser, int) io.WriteCloser - - // Read fields - reader io.ReadCloser // the current reader returned to the application - readErr error - br *bufio.Reader - // bytes remaining in current frame. - // set setReadRemaining to safely update this value and prevent overflow - readRemaining int64 - readFinal bool // true the current message has more frames. - readLength int64 // Message size. - readLimit int64 // Maximum message size. - readMaskPos int - readMaskKey [4]byte - handlePong func(string) error - handlePing func(string) error - handleClose func(int, string) error - readErrCount int - messageReader *messageReader // the current low-level reader - - readDecompress bool // whether last read frame had RSV1 set - newDecompressionReader func(io.Reader) io.ReadCloser -} - -func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn { - - if br == nil { - if readBufferSize == 0 { - readBufferSize = defaultReadBufferSize - } else if readBufferSize < maxControlFramePayloadSize { - // must be large enough for control frame - readBufferSize = maxControlFramePayloadSize - } - br = bufio.NewReaderSize(conn, readBufferSize) - } - - if writeBufferSize <= 0 { - writeBufferSize = defaultWriteBufferSize - } - writeBufferSize += maxFrameHeaderSize - - if writeBuf == nil && writeBufferPool == nil { - writeBuf = make([]byte, writeBufferSize) - } - - mu := make(chan struct{}, 1) - mu <- struct{}{} - c := &Conn{ - isServer: isServer, - br: br, - conn: conn, - mu: mu, - readFinal: true, - writeBuf: writeBuf, - writePool: writeBufferPool, - writeBufSize: writeBufferSize, - enableWriteCompression: true, - compressionLevel: defaultCompressionLevel, - } - c.SetCloseHandler(nil) - c.SetPingHandler(nil) - c.SetPongHandler(nil) - return c -} - -// setReadRemaining tracks the number of bytes remaining on the connection. If n -// overflows, an ErrReadLimit is returned. -func (c *Conn) setReadRemaining(n int64) error { - if n < 0 { - return ErrReadLimit - } - - c.readRemaining = n - return nil -} - -// Subprotocol returns the negotiated protocol for the connection. -func (c *Conn) Subprotocol() string { - return c.subprotocol -} - -// Close closes the underlying network connection without sending or waiting -// for a close message. -func (c *Conn) Close() error { - return c.conn.Close() -} - -// LocalAddr returns the local network address. -func (c *Conn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -// RemoteAddr returns the remote network address. -func (c *Conn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -// Write methods - -func (c *Conn) writeFatal(err error) error { - err = hideTempErr(err) - c.writeErrMu.Lock() - if c.writeErr == nil { - c.writeErr = err - } - c.writeErrMu.Unlock() - return err -} - -func (c *Conn) read(n int) ([]byte, error) { - p, err := c.br.Peek(n) - if err == io.EOF { - err = errUnexpectedEOF - } - c.br.Discard(len(p)) - return p, err -} - -func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error { - <-c.mu - defer func() { c.mu <- struct{}{} }() - - c.writeErrMu.Lock() - err := c.writeErr - c.writeErrMu.Unlock() - if err != nil { - return err - } - - c.conn.SetWriteDeadline(deadline) - if len(buf1) == 0 { - _, err = c.conn.Write(buf0) - } else { - err = c.writeBufs(buf0, buf1) - } - if err != nil { - return c.writeFatal(err) - } - if frameType == CloseMessage { - c.writeFatal(ErrCloseSent) - } - return nil -} - -// WriteControl writes a control message with the given deadline. The allowed -// message types are CloseMessage, PingMessage and PongMessage. -func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error { - if !isControl(messageType) { - return errBadWriteOpCode - } - if len(data) > maxControlFramePayloadSize { - return errInvalidControlFrame - } - - b0 := byte(messageType) | finalBit - b1 := byte(len(data)) - if !c.isServer { - b1 |= maskBit - } - - buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize) - buf = append(buf, b0, b1) - - if c.isServer { - buf = append(buf, data...) - } else { - key := newMaskKey() - buf = append(buf, key[:]...) - buf = append(buf, data...) - maskBytes(key, 0, buf[6:]) - } - - d := 1000 * time.Hour - if !deadline.IsZero() { - d = deadline.Sub(time.Now()) - if d < 0 { - return errWriteTimeout - } - } - - timer := time.NewTimer(d) - select { - case <-c.mu: - timer.Stop() - case <-timer.C: - return errWriteTimeout - } - defer func() { c.mu <- struct{}{} }() - - c.writeErrMu.Lock() - err := c.writeErr - c.writeErrMu.Unlock() - if err != nil { - return err - } - - c.conn.SetWriteDeadline(deadline) - _, err = c.conn.Write(buf) - if err != nil { - return c.writeFatal(err) - } - if messageType == CloseMessage { - c.writeFatal(ErrCloseSent) - } - return err -} - -// beginMessage prepares a connection and message writer for a new message. -func (c *Conn) beginMessage(mw *messageWriter, messageType int) error { - // Close previous writer if not already closed by the application. It's - // probably better to return an error in this situation, but we cannot - // change this without breaking existing applications. - if c.writer != nil { - c.writer.Close() - c.writer = nil - } - - if !isControl(messageType) && !isData(messageType) { - return errBadWriteOpCode - } - - c.writeErrMu.Lock() - err := c.writeErr - c.writeErrMu.Unlock() - if err != nil { - return err - } - - mw.c = c - mw.frameType = messageType - mw.pos = maxFrameHeaderSize - - if c.writeBuf == nil { - wpd, ok := c.writePool.Get().(writePoolData) - if ok { - c.writeBuf = wpd.buf - } else { - c.writeBuf = make([]byte, c.writeBufSize) - } - } - return nil -} - -// NextWriter returns a writer for the next message to send. The writer's Close -// method flushes the complete message to the network. -// -// There can be at most one open writer on a connection. NextWriter closes the -// previous writer if the application has not already done so. -// -// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and -// PongMessage) are supported. -func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) { - var mw messageWriter - if err := c.beginMessage(&mw, messageType); err != nil { - return nil, err - } - c.writer = &mw - if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) { - w := c.newCompressionWriter(c.writer, c.compressionLevel) - mw.compress = true - c.writer = w - } - return c.writer, nil -} - -type messageWriter struct { - c *Conn - compress bool // whether next call to flushFrame should set RSV1 - pos int // end of data in writeBuf. - frameType int // type of the current frame. - err error -} - -func (w *messageWriter) endMessage(err error) error { - if w.err != nil { - return err - } - c := w.c - w.err = err - c.writer = nil - if c.writePool != nil { - c.writePool.Put(writePoolData{buf: c.writeBuf}) - c.writeBuf = nil - } - return err -} - -// flushFrame writes buffered data and extra as a frame to the network. The -// final argument indicates that this is the last frame in the message. -func (w *messageWriter) flushFrame(final bool, extra []byte) error { - c := w.c - length := w.pos - maxFrameHeaderSize + len(extra) - - // Check for invalid control frames. - if isControl(w.frameType) && - (!final || length > maxControlFramePayloadSize) { - return w.endMessage(errInvalidControlFrame) - } - - b0 := byte(w.frameType) - if final { - b0 |= finalBit - } - if w.compress { - b0 |= rsv1Bit - } - w.compress = false - - b1 := byte(0) - if !c.isServer { - b1 |= maskBit - } - - // Assume that the frame starts at beginning of c.writeBuf. - framePos := 0 - if c.isServer { - // Adjust up if mask not included in the header. - framePos = 4 - } - - switch { - case length >= 65536: - c.writeBuf[framePos] = b0 - c.writeBuf[framePos+1] = b1 | 127 - binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length)) - case length > 125: - framePos += 6 - c.writeBuf[framePos] = b0 - c.writeBuf[framePos+1] = b1 | 126 - binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length)) - default: - framePos += 8 - c.writeBuf[framePos] = b0 - c.writeBuf[framePos+1] = b1 | byte(length) - } - - if !c.isServer { - key := newMaskKey() - copy(c.writeBuf[maxFrameHeaderSize-4:], key[:]) - maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos]) - if len(extra) > 0 { - return w.endMessage(c.writeFatal(errors.New("websocket: internal error, extra used in client mode"))) - } - } - - // Write the buffers to the connection with best-effort detection of - // concurrent writes. See the concurrency section in the package - // documentation for more info. - - if c.isWriting { - panic("concurrent write to websocket connection") - } - c.isWriting = true - - err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra) - - if !c.isWriting { - panic("concurrent write to websocket connection") - } - c.isWriting = false - - if err != nil { - return w.endMessage(err) - } - - if final { - w.endMessage(errWriteClosed) - return nil - } - - // Setup for next frame. - w.pos = maxFrameHeaderSize - w.frameType = continuationFrame - return nil -} - -func (w *messageWriter) ncopy(max int) (int, error) { - n := len(w.c.writeBuf) - w.pos - if n <= 0 { - if err := w.flushFrame(false, nil); err != nil { - return 0, err - } - n = len(w.c.writeBuf) - w.pos - } - if n > max { - n = max - } - return n, nil -} - -func (w *messageWriter) Write(p []byte) (int, error) { - if w.err != nil { - return 0, w.err - } - - if len(p) > 2*len(w.c.writeBuf) && w.c.isServer { - // Don't buffer large messages. - err := w.flushFrame(false, p) - if err != nil { - return 0, err - } - return len(p), nil - } - - nn := len(p) - for len(p) > 0 { - n, err := w.ncopy(len(p)) - if err != nil { - return 0, err - } - copy(w.c.writeBuf[w.pos:], p[:n]) - w.pos += n - p = p[n:] - } - return nn, nil -} - -func (w *messageWriter) WriteString(p string) (int, error) { - if w.err != nil { - return 0, w.err - } - - nn := len(p) - for len(p) > 0 { - n, err := w.ncopy(len(p)) - if err != nil { - return 0, err - } - copy(w.c.writeBuf[w.pos:], p[:n]) - w.pos += n - p = p[n:] - } - return nn, nil -} - -func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) { - if w.err != nil { - return 0, w.err - } - for { - if w.pos == len(w.c.writeBuf) { - err = w.flushFrame(false, nil) - if err != nil { - break - } - } - var n int - n, err = r.Read(w.c.writeBuf[w.pos:]) - w.pos += n - nn += int64(n) - if err != nil { - if err == io.EOF { - err = nil - } - break - } - } - return nn, err -} - -func (w *messageWriter) Close() error { - if w.err != nil { - return w.err - } - return w.flushFrame(true, nil) -} - -// WritePreparedMessage writes prepared message into connection. -func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error { - frameType, frameData, err := pm.frame(prepareKey{ - isServer: c.isServer, - compress: c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType), - compressionLevel: c.compressionLevel, - }) - if err != nil { - return err - } - if c.isWriting { - panic("concurrent write to websocket connection") - } - c.isWriting = true - err = c.write(frameType, c.writeDeadline, frameData, nil) - if !c.isWriting { - panic("concurrent write to websocket connection") - } - c.isWriting = false - return err -} - -// WriteMessage is a helper method for getting a writer using NextWriter, -// writing the message and closing the writer. -func (c *Conn) WriteMessage(messageType int, data []byte) error { - - if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) { - // Fast path with no allocations and single frame. - - var mw messageWriter - if err := c.beginMessage(&mw, messageType); err != nil { - return err - } - n := copy(c.writeBuf[mw.pos:], data) - mw.pos += n - data = data[n:] - return mw.flushFrame(true, data) - } - - w, err := c.NextWriter(messageType) - if err != nil { - return err - } - if _, err = w.Write(data); err != nil { - return err - } - return w.Close() -} - -// SetWriteDeadline sets the write deadline on the underlying network -// connection. After a write has timed out, the websocket state is corrupt and -// all future writes will return an error. A zero value for t means writes will -// not time out. -func (c *Conn) SetWriteDeadline(t time.Time) error { - c.writeDeadline = t - return nil -} - -// Read methods - -func (c *Conn) advanceFrame() (int, error) { - // 1. Skip remainder of previous frame. - - if c.readRemaining > 0 { - if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil { - return noFrame, err - } - } - - // 2. Read and parse first two bytes of frame header. - - p, err := c.read(2) - if err != nil { - return noFrame, err - } - - final := p[0]&finalBit != 0 - frameType := int(p[0] & 0xf) - mask := p[1]&maskBit != 0 - c.setReadRemaining(int64(p[1] & 0x7f)) - - c.readDecompress = false - if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 { - c.readDecompress = true - p[0] &^= rsv1Bit - } - - if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 { - return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16)) - } - - switch frameType { - case CloseMessage, PingMessage, PongMessage: - if c.readRemaining > maxControlFramePayloadSize { - return noFrame, c.handleProtocolError("control frame length > 125") - } - if !final { - return noFrame, c.handleProtocolError("control frame not final") - } - case TextMessage, BinaryMessage: - if !c.readFinal { - return noFrame, c.handleProtocolError("message start before final message frame") - } - c.readFinal = final - case continuationFrame: - if c.readFinal { - return noFrame, c.handleProtocolError("continuation after final message frame") - } - c.readFinal = final - default: - return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType)) - } - - // 3. Read and parse frame length as per - // https://tools.ietf.org/html/rfc6455#section-5.2 - // - // The length of the "Payload data", in bytes: if 0-125, that is the payload - // length. - // - If 126, the following 2 bytes interpreted as a 16-bit unsigned - // integer are the payload length. - // - If 127, the following 8 bytes interpreted as - // a 64-bit unsigned integer (the most significant bit MUST be 0) are the - // payload length. Multibyte length quantities are expressed in network byte - // order. - - switch c.readRemaining { - case 126: - p, err := c.read(2) - if err != nil { - return noFrame, err - } - - if err := c.setReadRemaining(int64(binary.BigEndian.Uint16(p))); err != nil { - return noFrame, err - } - case 127: - p, err := c.read(8) - if err != nil { - return noFrame, err - } - - if err := c.setReadRemaining(int64(binary.BigEndian.Uint64(p))); err != nil { - return noFrame, err - } - } - - // 4. Handle frame masking. - - if mask != c.isServer { - return noFrame, c.handleProtocolError("incorrect mask flag") - } - - if mask { - c.readMaskPos = 0 - p, err := c.read(len(c.readMaskKey)) - if err != nil { - return noFrame, err - } - copy(c.readMaskKey[:], p) - } - - // 5. For text and binary messages, enforce read limit and return. - - if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage { - - c.readLength += c.readRemaining - // Don't allow readLength to overflow in the presence of a large readRemaining - // counter. - if c.readLength < 0 { - return noFrame, ErrReadLimit - } - - if c.readLimit > 0 && c.readLength > c.readLimit { - c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait)) - return noFrame, ErrReadLimit - } - - return frameType, nil - } - - // 6. Read control frame payload. - - var payload []byte - if c.readRemaining > 0 { - payload, err = c.read(int(c.readRemaining)) - c.setReadRemaining(0) - if err != nil { - return noFrame, err - } - if c.isServer { - maskBytes(c.readMaskKey, 0, payload) - } - } - - // 7. Process control frame payload. - - switch frameType { - case PongMessage: - if err := c.handlePong(string(payload)); err != nil { - return noFrame, err - } - case PingMessage: - if err := c.handlePing(string(payload)); err != nil { - return noFrame, err - } - case CloseMessage: - closeCode := CloseNoStatusReceived - closeText := "" - if len(payload) >= 2 { - closeCode = int(binary.BigEndian.Uint16(payload)) - if !isValidReceivedCloseCode(closeCode) { - return noFrame, c.handleProtocolError("invalid close code") - } - closeText = string(payload[2:]) - if !utf8.ValidString(closeText) { - return noFrame, c.handleProtocolError("invalid utf8 payload in close frame") - } - } - if err := c.handleClose(closeCode, closeText); err != nil { - return noFrame, err - } - return noFrame, &CloseError{Code: closeCode, Text: closeText} - } - - return frameType, nil -} - -func (c *Conn) handleProtocolError(message string) error { - c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait)) - return errors.New("websocket: " + message) -} - -// NextReader returns the next data message received from the peer. The -// returned messageType is either TextMessage or BinaryMessage. -// -// There can be at most one open reader on a connection. NextReader discards -// the previous message if the application has not already consumed it. -// -// Applications must break out of the application's read loop when this method -// returns a non-nil error value. Errors returned from this method are -// permanent. Once this method returns a non-nil error, all subsequent calls to -// this method return the same error. -func (c *Conn) NextReader() (messageType int, r io.Reader, err error) { - // Close previous reader, only relevant for decompression. - if c.reader != nil { - c.reader.Close() - c.reader = nil - } - - c.messageReader = nil - c.readLength = 0 - - for c.readErr == nil { - frameType, err := c.advanceFrame() - if err != nil { - c.readErr = hideTempErr(err) - break - } - - if frameType == TextMessage || frameType == BinaryMessage { - c.messageReader = &messageReader{c} - c.reader = c.messageReader - if c.readDecompress { - c.reader = c.newDecompressionReader(c.reader) - } - return frameType, c.reader, nil - } - } - - // Applications that do handle the error returned from this method spin in - // tight loop on connection failure. To help application developers detect - // this error, panic on repeated reads to the failed connection. - c.readErrCount++ - if c.readErrCount >= 1000 { - panic("repeated read on failed websocket connection") - } - - return noFrame, nil, c.readErr -} - -type messageReader struct{ c *Conn } - -func (r *messageReader) Read(b []byte) (int, error) { - c := r.c - if c.messageReader != r { - return 0, io.EOF - } - - for c.readErr == nil { - - if c.readRemaining > 0 { - if int64(len(b)) > c.readRemaining { - b = b[:c.readRemaining] - } - n, err := c.br.Read(b) - c.readErr = hideTempErr(err) - if c.isServer { - c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n]) - } - rem := c.readRemaining - rem -= int64(n) - c.setReadRemaining(rem) - if c.readRemaining > 0 && c.readErr == io.EOF { - c.readErr = errUnexpectedEOF - } - return n, c.readErr - } - - if c.readFinal { - c.messageReader = nil - return 0, io.EOF - } - - frameType, err := c.advanceFrame() - switch { - case err != nil: - c.readErr = hideTempErr(err) - case frameType == TextMessage || frameType == BinaryMessage: - c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader") - } - } - - err := c.readErr - if err == io.EOF && c.messageReader == r { - err = errUnexpectedEOF - } - return 0, err -} - -func (r *messageReader) Close() error { - return nil -} - -// ReadMessage is a helper method for getting a reader using NextReader and -// reading from that reader to a buffer. -func (c *Conn) ReadMessage() (messageType int, p []byte, err error) { - var r io.Reader - messageType, r, err = c.NextReader() - if err != nil { - return messageType, nil, err - } - p, err = ioutil.ReadAll(r) - return messageType, p, err -} - -// SetReadDeadline sets the read deadline on the underlying network connection. -// After a read has timed out, the websocket connection state is corrupt and -// all future reads will return an error. A zero value for t means reads will -// not time out. -func (c *Conn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -// SetReadLimit sets the maximum size in bytes for a message read from the peer. If a -// message exceeds the limit, the connection sends a close message to the peer -// and returns ErrReadLimit to the application. -func (c *Conn) SetReadLimit(limit int64) { - c.readLimit = limit -} - -// CloseHandler returns the current close handler -func (c *Conn) CloseHandler() func(code int, text string) error { - return c.handleClose -} - -// SetCloseHandler sets the handler for close messages received from the peer. -// The code argument to h is the received close code or CloseNoStatusReceived -// if the close message is empty. The default close handler sends a close -// message back to the peer. -// -// The handler function is called from the NextReader, ReadMessage and message -// reader Read methods. The application must read the connection to process -// close messages as described in the section on Control Messages above. -// -// The connection read methods return a CloseError when a close message is -// received. Most applications should handle close messages as part of their -// normal error handling. Applications should only set a close handler when the -// application must perform some action before sending a close message back to -// the peer. -func (c *Conn) SetCloseHandler(h func(code int, text string) error) { - if h == nil { - h = func(code int, text string) error { - message := FormatCloseMessage(code, "") - c.WriteControl(CloseMessage, message, time.Now().Add(writeWait)) - return nil - } - } - c.handleClose = h -} - -// PingHandler returns the current ping handler -func (c *Conn) PingHandler() func(appData string) error { - return c.handlePing -} - -// SetPingHandler sets the handler for ping messages received from the peer. -// The appData argument to h is the PING message application data. The default -// ping handler sends a pong to the peer. -// -// The handler function is called from the NextReader, ReadMessage and message -// reader Read methods. The application must read the connection to process -// ping messages as described in the section on Control Messages above. -func (c *Conn) SetPingHandler(h func(appData string) error) { - if h == nil { - h = func(message string) error { - err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait)) - if err == ErrCloseSent { - return nil - } else if e, ok := err.(net.Error); ok && e.Temporary() { - return nil - } - return err - } - } - c.handlePing = h -} - -// PongHandler returns the current pong handler -func (c *Conn) PongHandler() func(appData string) error { - return c.handlePong -} - -// SetPongHandler sets the handler for pong messages received from the peer. -// The appData argument to h is the PONG message application data. The default -// pong handler does nothing. -// -// The handler function is called from the NextReader, ReadMessage and message -// reader Read methods. The application must read the connection to process -// pong messages as described in the section on Control Messages above. -func (c *Conn) SetPongHandler(h func(appData string) error) { - if h == nil { - h = func(string) error { return nil } - } - c.handlePong = h -} - -// UnderlyingConn returns the internal net.Conn. This can be used to further -// modifications to connection specific flags. -func (c *Conn) UnderlyingConn() net.Conn { - return c.conn -} - -// EnableWriteCompression enables and disables write compression of -// subsequent text and binary messages. This function is a noop if -// compression was not negotiated with the peer. -func (c *Conn) EnableWriteCompression(enable bool) { - c.enableWriteCompression = enable -} - -// SetCompressionLevel sets the flate compression level for subsequent text and -// binary messages. This function is a noop if compression was not negotiated -// with the peer. See the compress/flate package for a description of -// compression levels. -func (c *Conn) SetCompressionLevel(level int) error { - if !isValidCompressionLevel(level) { - return errors.New("websocket: invalid compression level") - } - c.compressionLevel = level - return nil -} - -// FormatCloseMessage formats closeCode and text as a WebSocket close message. -// An empty message is returned for code CloseNoStatusReceived. -func FormatCloseMessage(closeCode int, text string) []byte { - if closeCode == CloseNoStatusReceived { - // Return empty message because it's illegal to send - // CloseNoStatusReceived. Return non-nil value in case application - // checks for nil. - return []byte{} - } - buf := make([]byte, 2+len(text)) - binary.BigEndian.PutUint16(buf, uint16(closeCode)) - copy(buf[2:], text) - return buf -} diff --git a/vendor/github.com/gorilla/websocket/conn_write.go b/vendor/github.com/gorilla/websocket/conn_write.go deleted file mode 100644 index a509a21f8..000000000 --- a/vendor/github.com/gorilla/websocket/conn_write.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.8 - -package websocket - -import "net" - -func (c *Conn) writeBufs(bufs ...[]byte) error { - b := net.Buffers(bufs) - _, err := b.WriteTo(c.conn) - return err -} diff --git a/vendor/github.com/gorilla/websocket/conn_write_legacy.go b/vendor/github.com/gorilla/websocket/conn_write_legacy.go deleted file mode 100644 index 37edaff5a..000000000 --- a/vendor/github.com/gorilla/websocket/conn_write_legacy.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.8 - -package websocket - -func (c *Conn) writeBufs(bufs ...[]byte) error { - for _, buf := range bufs { - if len(buf) > 0 { - if _, err := c.conn.Write(buf); err != nil { - return err - } - } - } - return nil -} diff --git a/vendor/github.com/gorilla/websocket/doc.go b/vendor/github.com/gorilla/websocket/doc.go deleted file mode 100644 index 8db0cef95..000000000 --- a/vendor/github.com/gorilla/websocket/doc.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package websocket implements the WebSocket protocol defined in RFC 6455. -// -// Overview -// -// The Conn type represents a WebSocket connection. A server application calls -// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn: -// -// var upgrader = websocket.Upgrader{ -// ReadBufferSize: 1024, -// WriteBufferSize: 1024, -// } -// -// func handler(w http.ResponseWriter, r *http.Request) { -// conn, err := upgrader.Upgrade(w, r, nil) -// if err != nil { -// log.Println(err) -// return -// } -// ... Use conn to send and receive messages. -// } -// -// Call the connection's WriteMessage and ReadMessage methods to send and -// receive messages as a slice of bytes. This snippet of code shows how to echo -// messages using these methods: -// -// for { -// messageType, p, err := conn.ReadMessage() -// if err != nil { -// log.Println(err) -// return -// } -// if err := conn.WriteMessage(messageType, p); err != nil { -// log.Println(err) -// return -// } -// } -// -// In above snippet of code, p is a []byte and messageType is an int with value -// websocket.BinaryMessage or websocket.TextMessage. -// -// An application can also send and receive messages using the io.WriteCloser -// and io.Reader interfaces. To send a message, call the connection NextWriter -// method to get an io.WriteCloser, write the message to the writer and close -// the writer when done. To receive a message, call the connection NextReader -// method to get an io.Reader and read until io.EOF is returned. This snippet -// shows how to echo messages using the NextWriter and NextReader methods: -// -// for { -// messageType, r, err := conn.NextReader() -// if err != nil { -// return -// } -// w, err := conn.NextWriter(messageType) -// if err != nil { -// return err -// } -// if _, err := io.Copy(w, r); err != nil { -// return err -// } -// if err := w.Close(); err != nil { -// return err -// } -// } -// -// Data Messages -// -// The WebSocket protocol distinguishes between text and binary data messages. -// Text messages are interpreted as UTF-8 encoded text. The interpretation of -// binary messages is left to the application. -// -// This package uses the TextMessage and BinaryMessage integer constants to -// identify the two data message types. The ReadMessage and NextReader methods -// return the type of the received message. The messageType argument to the -// WriteMessage and NextWriter methods specifies the type of a sent message. -// -// It is the application's responsibility to ensure that text messages are -// valid UTF-8 encoded text. -// -// Control Messages -// -// The WebSocket protocol defines three types of control messages: close, ping -// and pong. Call the connection WriteControl, WriteMessage or NextWriter -// methods to send a control message to the peer. -// -// Connections handle received close messages by calling the handler function -// set with the SetCloseHandler method and by returning a *CloseError from the -// NextReader, ReadMessage or the message Read method. The default close -// handler sends a close message to the peer. -// -// Connections handle received ping messages by calling the handler function -// set with the SetPingHandler method. The default ping handler sends a pong -// message to the peer. -// -// Connections handle received pong messages by calling the handler function -// set with the SetPongHandler method. The default pong handler does nothing. -// If an application sends ping messages, then the application should set a -// pong handler to receive the corresponding pong. -// -// The control message handler functions are called from the NextReader, -// ReadMessage and message reader Read methods. The default close and ping -// handlers can block these methods for a short time when the handler writes to -// the connection. -// -// The application must read the connection to process close, ping and pong -// messages sent from the peer. If the application is not otherwise interested -// in messages from the peer, then the application should start a goroutine to -// read and discard messages from the peer. A simple example is: -// -// func readLoop(c *websocket.Conn) { -// for { -// if _, _, err := c.NextReader(); err != nil { -// c.Close() -// break -// } -// } -// } -// -// Concurrency -// -// Connections support one concurrent reader and one concurrent writer. -// -// Applications are responsible for ensuring that no more than one goroutine -// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage, -// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and -// that no more than one goroutine calls the read methods (NextReader, -// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler) -// concurrently. -// -// The Close and WriteControl methods can be called concurrently with all other -// methods. -// -// Origin Considerations -// -// Web browsers allow Javascript applications to open a WebSocket connection to -// any host. It's up to the server to enforce an origin policy using the Origin -// request header sent by the browser. -// -// The Upgrader calls the function specified in the CheckOrigin field to check -// the origin. If the CheckOrigin function returns false, then the Upgrade -// method fails the WebSocket handshake with HTTP status 403. -// -// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail -// the handshake if the Origin request header is present and the Origin host is -// not equal to the Host request header. -// -// The deprecated package-level Upgrade function does not perform origin -// checking. The application is responsible for checking the Origin header -// before calling the Upgrade function. -// -// Buffers -// -// Connections buffer network input and output to reduce the number -// of system calls when reading or writing messages. -// -// Write buffers are also used for constructing WebSocket frames. See RFC 6455, -// Section 5 for a discussion of message framing. A WebSocket frame header is -// written to the network each time a write buffer is flushed to the network. -// Decreasing the size of the write buffer can increase the amount of framing -// overhead on the connection. -// -// The buffer sizes in bytes are specified by the ReadBufferSize and -// WriteBufferSize fields in the Dialer and Upgrader. The Dialer uses a default -// size of 4096 when a buffer size field is set to zero. The Upgrader reuses -// buffers created by the HTTP server when a buffer size field is set to zero. -// The HTTP server buffers have a size of 4096 at the time of this writing. -// -// The buffer sizes do not limit the size of a message that can be read or -// written by a connection. -// -// Buffers are held for the lifetime of the connection by default. If the -// Dialer or Upgrader WriteBufferPool field is set, then a connection holds the -// write buffer only when writing a message. -// -// Applications should tune the buffer sizes to balance memory use and -// performance. Increasing the buffer size uses more memory, but can reduce the -// number of system calls to read or write the network. In the case of writing, -// increasing the buffer size can reduce the number of frame headers written to -// the network. -// -// Some guidelines for setting buffer parameters are: -// -// Limit the buffer sizes to the maximum expected message size. Buffers larger -// than the largest message do not provide any benefit. -// -// Depending on the distribution of message sizes, setting the buffer size to -// a value less than the maximum expected message size can greatly reduce memory -// use with a small impact on performance. Here's an example: If 99% of the -// messages are smaller than 256 bytes and the maximum message size is 512 -// bytes, then a buffer size of 256 bytes will result in 1.01 more system calls -// than a buffer size of 512 bytes. The memory savings is 50%. -// -// A write buffer pool is useful when the application has a modest number -// writes over a large number of connections. when buffers are pooled, a larger -// buffer size has a reduced impact on total memory use and has the benefit of -// reducing system calls and frame overhead. -// -// Compression EXPERIMENTAL -// -// Per message compression extensions (RFC 7692) are experimentally supported -// by this package in a limited capacity. Setting the EnableCompression option -// to true in Dialer or Upgrader will attempt to negotiate per message deflate -// support. -// -// var upgrader = websocket.Upgrader{ -// EnableCompression: true, -// } -// -// If compression was successfully negotiated with the connection's peer, any -// message received in compressed form will be automatically decompressed. -// All Read methods will return uncompressed bytes. -// -// Per message compression of messages written to a connection can be enabled -// or disabled by calling the corresponding Conn method: -// -// conn.EnableWriteCompression(false) -// -// Currently this package does not support compression with "context takeover". -// This means that messages must be compressed and decompressed in isolation, -// without retaining sliding window or dictionary state across messages. For -// more details refer to RFC 7692. -// -// Use of compression is experimental and may result in decreased performance. -package websocket diff --git a/vendor/github.com/gorilla/websocket/go.mod b/vendor/github.com/gorilla/websocket/go.mod deleted file mode 100644 index 1a7afd502..000000000 --- a/vendor/github.com/gorilla/websocket/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/gorilla/websocket - -go 1.12 diff --git a/vendor/github.com/gorilla/websocket/go.sum b/vendor/github.com/gorilla/websocket/go.sum deleted file mode 100644 index e69de29bb..000000000 diff --git a/vendor/github.com/gorilla/websocket/join.go b/vendor/github.com/gorilla/websocket/join.go deleted file mode 100644 index c64f8c829..000000000 --- a/vendor/github.com/gorilla/websocket/join.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2019 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "io" - "strings" -) - -// JoinMessages concatenates received messages to create a single io.Reader. -// The string term is appended to each message. The returned reader does not -// support concurrent calls to the Read method. -func JoinMessages(c *Conn, term string) io.Reader { - return &joinReader{c: c, term: term} -} - -type joinReader struct { - c *Conn - term string - r io.Reader -} - -func (r *joinReader) Read(p []byte) (int, error) { - if r.r == nil { - var err error - _, r.r, err = r.c.NextReader() - if err != nil { - return 0, err - } - if r.term != "" { - r.r = io.MultiReader(r.r, strings.NewReader(r.term)) - } - } - n, err := r.r.Read(p) - if err == io.EOF { - err = nil - r.r = nil - } - return n, err -} diff --git a/vendor/github.com/gorilla/websocket/json.go b/vendor/github.com/gorilla/websocket/json.go deleted file mode 100644 index dc2c1f641..000000000 --- a/vendor/github.com/gorilla/websocket/json.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "encoding/json" - "io" -) - -// WriteJSON writes the JSON encoding of v as a message. -// -// Deprecated: Use c.WriteJSON instead. -func WriteJSON(c *Conn, v interface{}) error { - return c.WriteJSON(v) -} - -// WriteJSON writes the JSON encoding of v as a message. -// -// See the documentation for encoding/json Marshal for details about the -// conversion of Go values to JSON. -func (c *Conn) WriteJSON(v interface{}) error { - w, err := c.NextWriter(TextMessage) - if err != nil { - return err - } - err1 := json.NewEncoder(w).Encode(v) - err2 := w.Close() - if err1 != nil { - return err1 - } - return err2 -} - -// ReadJSON reads the next JSON-encoded message from the connection and stores -// it in the value pointed to by v. -// -// Deprecated: Use c.ReadJSON instead. -func ReadJSON(c *Conn, v interface{}) error { - return c.ReadJSON(v) -} - -// ReadJSON reads the next JSON-encoded message from the connection and stores -// it in the value pointed to by v. -// -// See the documentation for the encoding/json Unmarshal function for details -// about the conversion of JSON to a Go value. -func (c *Conn) ReadJSON(v interface{}) error { - _, r, err := c.NextReader() - if err != nil { - return err - } - err = json.NewDecoder(r).Decode(v) - if err == io.EOF { - // One value is expected in the message. - err = io.ErrUnexpectedEOF - } - return err -} diff --git a/vendor/github.com/gorilla/websocket/mask.go b/vendor/github.com/gorilla/websocket/mask.go deleted file mode 100644 index 577fce9ef..000000000 --- a/vendor/github.com/gorilla/websocket/mask.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of -// this source code is governed by a BSD-style license that can be found in the -// LICENSE file. - -// +build !appengine - -package websocket - -import "unsafe" - -const wordSize = int(unsafe.Sizeof(uintptr(0))) - -func maskBytes(key [4]byte, pos int, b []byte) int { - // Mask one byte at a time for small buffers. - if len(b) < 2*wordSize { - for i := range b { - b[i] ^= key[pos&3] - pos++ - } - return pos & 3 - } - - // Mask one byte at a time to word boundary. - if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 { - n = wordSize - n - for i := range b[:n] { - b[i] ^= key[pos&3] - pos++ - } - b = b[n:] - } - - // Create aligned word size key. - var k [wordSize]byte - for i := range k { - k[i] = key[(pos+i)&3] - } - kw := *(*uintptr)(unsafe.Pointer(&k)) - - // Mask one word at a time. - n := (len(b) / wordSize) * wordSize - for i := 0; i < n; i += wordSize { - *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw - } - - // Mask one byte at a time for remaining bytes. - b = b[n:] - for i := range b { - b[i] ^= key[pos&3] - pos++ - } - - return pos & 3 -} diff --git a/vendor/github.com/gorilla/websocket/mask_safe.go b/vendor/github.com/gorilla/websocket/mask_safe.go deleted file mode 100644 index 2aac060e5..000000000 --- a/vendor/github.com/gorilla/websocket/mask_safe.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of -// this source code is governed by a BSD-style license that can be found in the -// LICENSE file. - -// +build appengine - -package websocket - -func maskBytes(key [4]byte, pos int, b []byte) int { - for i := range b { - b[i] ^= key[pos&3] - pos++ - } - return pos & 3 -} diff --git a/vendor/github.com/gorilla/websocket/prepared.go b/vendor/github.com/gorilla/websocket/prepared.go deleted file mode 100644 index c854225e9..000000000 --- a/vendor/github.com/gorilla/websocket/prepared.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bytes" - "net" - "sync" - "time" -) - -// PreparedMessage caches on the wire representations of a message payload. -// Use PreparedMessage to efficiently send a message payload to multiple -// connections. PreparedMessage is especially useful when compression is used -// because the CPU and memory expensive compression operation can be executed -// once for a given set of compression options. -type PreparedMessage struct { - messageType int - data []byte - mu sync.Mutex - frames map[prepareKey]*preparedFrame -} - -// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage. -type prepareKey struct { - isServer bool - compress bool - compressionLevel int -} - -// preparedFrame contains data in wire representation. -type preparedFrame struct { - once sync.Once - data []byte -} - -// NewPreparedMessage returns an initialized PreparedMessage. You can then send -// it to connection using WritePreparedMessage method. Valid wire -// representation will be calculated lazily only once for a set of current -// connection options. -func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) { - pm := &PreparedMessage{ - messageType: messageType, - frames: make(map[prepareKey]*preparedFrame), - data: data, - } - - // Prepare a plain server frame. - _, frameData, err := pm.frame(prepareKey{isServer: true, compress: false}) - if err != nil { - return nil, err - } - - // To protect against caller modifying the data argument, remember the data - // copied to the plain server frame. - pm.data = frameData[len(frameData)-len(data):] - return pm, nil -} - -func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) { - pm.mu.Lock() - frame, ok := pm.frames[key] - if !ok { - frame = &preparedFrame{} - pm.frames[key] = frame - } - pm.mu.Unlock() - - var err error - frame.once.Do(func() { - // Prepare a frame using a 'fake' connection. - // TODO: Refactor code in conn.go to allow more direct construction of - // the frame. - mu := make(chan struct{}, 1) - mu <- struct{}{} - var nc prepareConn - c := &Conn{ - conn: &nc, - mu: mu, - isServer: key.isServer, - compressionLevel: key.compressionLevel, - enableWriteCompression: true, - writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize), - } - if key.compress { - c.newCompressionWriter = compressNoContextTakeover - } - err = c.WriteMessage(pm.messageType, pm.data) - frame.data = nc.buf.Bytes() - }) - return pm.messageType, frame.data, err -} - -type prepareConn struct { - buf bytes.Buffer - net.Conn -} - -func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) } -func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil } diff --git a/vendor/github.com/gorilla/websocket/proxy.go b/vendor/github.com/gorilla/websocket/proxy.go deleted file mode 100644 index e87a8c9f0..000000000 --- a/vendor/github.com/gorilla/websocket/proxy.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "encoding/base64" - "errors" - "net" - "net/http" - "net/url" - "strings" -) - -type netDialerFunc func(network, addr string) (net.Conn, error) - -func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) { - return fn(network, addr) -} - -func init() { - proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) { - return &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil - }) -} - -type httpProxyDialer struct { - proxyURL *url.URL - forwardDial func(network, addr string) (net.Conn, error) -} - -func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) { - hostPort, _ := hostPortNoPort(hpd.proxyURL) - conn, err := hpd.forwardDial(network, hostPort) - if err != nil { - return nil, err - } - - connectHeader := make(http.Header) - if user := hpd.proxyURL.User; user != nil { - proxyUser := user.Username() - if proxyPassword, passwordSet := user.Password(); passwordSet { - credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword)) - connectHeader.Set("Proxy-Authorization", "Basic "+credential) - } - } - - connectReq := &http.Request{ - Method: "CONNECT", - URL: &url.URL{Opaque: addr}, - Host: addr, - Header: connectHeader, - } - - if err := connectReq.Write(conn); err != nil { - conn.Close() - return nil, err - } - - // Read response. It's OK to use and discard buffered reader here becaue - // the remote server does not speak until spoken to. - br := bufio.NewReader(conn) - resp, err := http.ReadResponse(br, connectReq) - if err != nil { - conn.Close() - return nil, err - } - - if resp.StatusCode != 200 { - conn.Close() - f := strings.SplitN(resp.Status, " ", 2) - return nil, errors.New(f[1]) - } - return conn, nil -} diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go deleted file mode 100644 index 887d55891..000000000 --- a/vendor/github.com/gorilla/websocket/server.go +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "errors" - "io" - "net/http" - "net/url" - "strings" - "time" -) - -// HandshakeError describes an error with the handshake from the peer. -type HandshakeError struct { - message string -} - -func (e HandshakeError) Error() string { return e.message } - -// Upgrader specifies parameters for upgrading an HTTP connection to a -// WebSocket connection. -type Upgrader struct { - // HandshakeTimeout specifies the duration for the handshake to complete. - HandshakeTimeout time.Duration - - // ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer - // size is zero, then buffers allocated by the HTTP server are used. The - // I/O buffer sizes do not limit the size of the messages that can be sent - // or received. - ReadBufferSize, WriteBufferSize int - - // WriteBufferPool is a pool of buffers for write operations. If the value - // is not set, then write buffers are allocated to the connection for the - // lifetime of the connection. - // - // A pool is most useful when the application has a modest volume of writes - // across a large number of connections. - // - // Applications should use a single pool for each unique value of - // WriteBufferSize. - WriteBufferPool BufferPool - - // Subprotocols specifies the server's supported protocols in order of - // preference. If this field is not nil, then the Upgrade method negotiates a - // subprotocol by selecting the first match in this list with a protocol - // requested by the client. If there's no match, then no protocol is - // negotiated (the Sec-Websocket-Protocol header is not included in the - // handshake response). - Subprotocols []string - - // Error specifies the function for generating HTTP error responses. If Error - // is nil, then http.Error is used to generate the HTTP response. - Error func(w http.ResponseWriter, r *http.Request, status int, reason error) - - // CheckOrigin returns true if the request Origin header is acceptable. If - // CheckOrigin is nil, then a safe default is used: return false if the - // Origin request header is present and the origin host is not equal to - // request Host header. - // - // A CheckOrigin function should carefully validate the request origin to - // prevent cross-site request forgery. - CheckOrigin func(r *http.Request) bool - - // EnableCompression specify if the server should attempt to negotiate per - // message compression (RFC 7692). Setting this value to true does not - // guarantee that compression will be supported. Currently only "no context - // takeover" modes are supported. - EnableCompression bool -} - -func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) { - err := HandshakeError{reason} - if u.Error != nil { - u.Error(w, r, status, err) - } else { - w.Header().Set("Sec-Websocket-Version", "13") - http.Error(w, http.StatusText(status), status) - } - return nil, err -} - -// checkSameOrigin returns true if the origin is not set or is equal to the request host. -func checkSameOrigin(r *http.Request) bool { - origin := r.Header["Origin"] - if len(origin) == 0 { - return true - } - u, err := url.Parse(origin[0]) - if err != nil { - return false - } - return equalASCIIFold(u.Host, r.Host) -} - -func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string { - if u.Subprotocols != nil { - clientProtocols := Subprotocols(r) - for _, serverProtocol := range u.Subprotocols { - for _, clientProtocol := range clientProtocols { - if clientProtocol == serverProtocol { - return clientProtocol - } - } - } - } else if responseHeader != nil { - return responseHeader.Get("Sec-Websocket-Protocol") - } - return "" -} - -// Upgrade upgrades the HTTP server connection to the WebSocket protocol. -// -// The responseHeader is included in the response to the client's upgrade -// request. Use the responseHeader to specify cookies (Set-Cookie) and the -// application negotiated subprotocol (Sec-WebSocket-Protocol). -// -// If the upgrade fails, then Upgrade replies to the client with an HTTP error -// response. -func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) { - const badHandshake = "websocket: the client is not using the websocket protocol: " - - if !tokenListContainsValue(r.Header, "Connection", "upgrade") { - return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header") - } - - if !tokenListContainsValue(r.Header, "Upgrade", "websocket") { - return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header") - } - - if r.Method != "GET" { - return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET") - } - - if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") { - return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header") - } - - if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok { - return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported") - } - - checkOrigin := u.CheckOrigin - if checkOrigin == nil { - checkOrigin = checkSameOrigin - } - if !checkOrigin(r) { - return u.returnError(w, r, http.StatusForbidden, "websocket: request origin not allowed by Upgrader.CheckOrigin") - } - - challengeKey := r.Header.Get("Sec-Websocket-Key") - if challengeKey == "" { - return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header is missing or blank") - } - - subprotocol := u.selectSubprotocol(r, responseHeader) - - // Negotiate PMCE - var compress bool - if u.EnableCompression { - for _, ext := range parseExtensions(r.Header) { - if ext[""] != "permessage-deflate" { - continue - } - compress = true - break - } - } - - h, ok := w.(http.Hijacker) - if !ok { - return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker") - } - var brw *bufio.ReadWriter - netConn, brw, err := h.Hijack() - if err != nil { - return u.returnError(w, r, http.StatusInternalServerError, err.Error()) - } - - if brw.Reader.Buffered() > 0 { - netConn.Close() - return nil, errors.New("websocket: client sent data before handshake is complete") - } - - var br *bufio.Reader - if u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 { - // Reuse hijacked buffered reader as connection reader. - br = brw.Reader - } - - buf := bufioWriterBuffer(netConn, brw.Writer) - - var writeBuf []byte - if u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 { - // Reuse hijacked write buffer as connection buffer. - writeBuf = buf - } - - c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf) - c.subprotocol = subprotocol - - if compress { - c.newCompressionWriter = compressNoContextTakeover - c.newDecompressionReader = decompressNoContextTakeover - } - - // Use larger of hijacked buffer and connection write buffer for header. - p := buf - if len(c.writeBuf) > len(p) { - p = c.writeBuf - } - p = p[:0] - - p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...) - p = append(p, computeAcceptKey(challengeKey)...) - p = append(p, "\r\n"...) - if c.subprotocol != "" { - p = append(p, "Sec-WebSocket-Protocol: "...) - p = append(p, c.subprotocol...) - p = append(p, "\r\n"...) - } - if compress { - p = append(p, "Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...) - } - for k, vs := range responseHeader { - if k == "Sec-Websocket-Protocol" { - continue - } - for _, v := range vs { - p = append(p, k...) - p = append(p, ": "...) - for i := 0; i < len(v); i++ { - b := v[i] - if b <= 31 { - // prevent response splitting. - b = ' ' - } - p = append(p, b) - } - p = append(p, "\r\n"...) - } - } - p = append(p, "\r\n"...) - - // Clear deadlines set by HTTP server. - netConn.SetDeadline(time.Time{}) - - if u.HandshakeTimeout > 0 { - netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout)) - } - if _, err = netConn.Write(p); err != nil { - netConn.Close() - return nil, err - } - if u.HandshakeTimeout > 0 { - netConn.SetWriteDeadline(time.Time{}) - } - - return c, nil -} - -// Upgrade upgrades the HTTP server connection to the WebSocket protocol. -// -// Deprecated: Use websocket.Upgrader instead. -// -// Upgrade does not perform origin checking. The application is responsible for -// checking the Origin header before calling Upgrade. An example implementation -// of the same origin policy check is: -// -// if req.Header.Get("Origin") != "http://"+req.Host { -// http.Error(w, "Origin not allowed", http.StatusForbidden) -// return -// } -// -// If the endpoint supports subprotocols, then the application is responsible -// for negotiating the protocol used on the connection. Use the Subprotocols() -// function to get the subprotocols requested by the client. Use the -// Sec-Websocket-Protocol response header to specify the subprotocol selected -// by the application. -// -// The responseHeader is included in the response to the client's upgrade -// request. Use the responseHeader to specify cookies (Set-Cookie) and the -// negotiated subprotocol (Sec-Websocket-Protocol). -// -// The connection buffers IO to the underlying network connection. The -// readBufSize and writeBufSize parameters specify the size of the buffers to -// use. Messages can be larger than the buffers. -// -// If the request is not a valid WebSocket handshake, then Upgrade returns an -// error of type HandshakeError. Applications should handle this error by -// replying to the client with an HTTP error response. -func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) { - u := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize} - u.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) { - // don't return errors to maintain backwards compatibility - } - u.CheckOrigin = func(r *http.Request) bool { - // allow all connections by default - return true - } - return u.Upgrade(w, r, responseHeader) -} - -// Subprotocols returns the subprotocols requested by the client in the -// Sec-Websocket-Protocol header. -func Subprotocols(r *http.Request) []string { - h := strings.TrimSpace(r.Header.Get("Sec-Websocket-Protocol")) - if h == "" { - return nil - } - protocols := strings.Split(h, ",") - for i := range protocols { - protocols[i] = strings.TrimSpace(protocols[i]) - } - return protocols -} - -// IsWebSocketUpgrade returns true if the client requested upgrade to the -// WebSocket protocol. -func IsWebSocketUpgrade(r *http.Request) bool { - return tokenListContainsValue(r.Header, "Connection", "upgrade") && - tokenListContainsValue(r.Header, "Upgrade", "websocket") -} - -// bufioReaderSize size returns the size of a bufio.Reader. -func bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int { - // This code assumes that peek on a reset reader returns - // bufio.Reader.buf[:0]. - // TODO: Use bufio.Reader.Size() after Go 1.10 - br.Reset(originalReader) - if p, err := br.Peek(0); err == nil { - return cap(p) - } - return 0 -} - -// writeHook is an io.Writer that records the last slice passed to it vio -// io.Writer.Write. -type writeHook struct { - p []byte -} - -func (wh *writeHook) Write(p []byte) (int, error) { - wh.p = p - return len(p), nil -} - -// bufioWriterBuffer grabs the buffer from a bufio.Writer. -func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte { - // This code assumes that bufio.Writer.buf[:1] is passed to the - // bufio.Writer's underlying writer. - var wh writeHook - bw.Reset(&wh) - bw.WriteByte(0) - bw.Flush() - - bw.Reset(originalWriter) - - return wh.p[:cap(wh.p)] -} diff --git a/vendor/github.com/gorilla/websocket/trace.go b/vendor/github.com/gorilla/websocket/trace.go deleted file mode 100644 index 834f122a0..000000000 --- a/vendor/github.com/gorilla/websocket/trace.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build go1.8 - -package websocket - -import ( - "crypto/tls" - "net/http/httptrace" -) - -func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { - if trace.TLSHandshakeStart != nil { - trace.TLSHandshakeStart() - } - err := doHandshake(tlsConn, cfg) - if trace.TLSHandshakeDone != nil { - trace.TLSHandshakeDone(tlsConn.ConnectionState(), err) - } - return err -} diff --git a/vendor/github.com/gorilla/websocket/trace_17.go b/vendor/github.com/gorilla/websocket/trace_17.go deleted file mode 100644 index 77d05a0b5..000000000 --- a/vendor/github.com/gorilla/websocket/trace_17.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build !go1.8 - -package websocket - -import ( - "crypto/tls" - "net/http/httptrace" -) - -func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { - return doHandshake(tlsConn, cfg) -} diff --git a/vendor/github.com/gorilla/websocket/util.go b/vendor/github.com/gorilla/websocket/util.go deleted file mode 100644 index 7bf2f66c6..000000000 --- a/vendor/github.com/gorilla/websocket/util.go +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "crypto/rand" - "crypto/sha1" - "encoding/base64" - "io" - "net/http" - "strings" - "unicode/utf8" -) - -var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11") - -func computeAcceptKey(challengeKey string) string { - h := sha1.New() - h.Write([]byte(challengeKey)) - h.Write(keyGUID) - return base64.StdEncoding.EncodeToString(h.Sum(nil)) -} - -func generateChallengeKey() (string, error) { - p := make([]byte, 16) - if _, err := io.ReadFull(rand.Reader, p); err != nil { - return "", err - } - return base64.StdEncoding.EncodeToString(p), nil -} - -// Token octets per RFC 2616. -var isTokenOctet = [256]bool{ - '!': true, - '#': true, - '$': true, - '%': true, - '&': true, - '\'': true, - '*': true, - '+': true, - '-': true, - '.': true, - '0': true, - '1': true, - '2': true, - '3': true, - '4': true, - '5': true, - '6': true, - '7': true, - '8': true, - '9': true, - 'A': true, - 'B': true, - 'C': true, - 'D': true, - 'E': true, - 'F': true, - 'G': true, - 'H': true, - 'I': true, - 'J': true, - 'K': true, - 'L': true, - 'M': true, - 'N': true, - 'O': true, - 'P': true, - 'Q': true, - 'R': true, - 'S': true, - 'T': true, - 'U': true, - 'W': true, - 'V': true, - 'X': true, - 'Y': true, - 'Z': true, - '^': true, - '_': true, - '`': true, - 'a': true, - 'b': true, - 'c': true, - 'd': true, - 'e': true, - 'f': true, - 'g': true, - 'h': true, - 'i': true, - 'j': true, - 'k': true, - 'l': true, - 'm': true, - 'n': true, - 'o': true, - 'p': true, - 'q': true, - 'r': true, - 's': true, - 't': true, - 'u': true, - 'v': true, - 'w': true, - 'x': true, - 'y': true, - 'z': true, - '|': true, - '~': true, -} - -// skipSpace returns a slice of the string s with all leading RFC 2616 linear -// whitespace removed. -func skipSpace(s string) (rest string) { - i := 0 - for ; i < len(s); i++ { - if b := s[i]; b != ' ' && b != '\t' { - break - } - } - return s[i:] -} - -// nextToken returns the leading RFC 2616 token of s and the string following -// the token. -func nextToken(s string) (token, rest string) { - i := 0 - for ; i < len(s); i++ { - if !isTokenOctet[s[i]] { - break - } - } - return s[:i], s[i:] -} - -// nextTokenOrQuoted returns the leading token or quoted string per RFC 2616 -// and the string following the token or quoted string. -func nextTokenOrQuoted(s string) (value string, rest string) { - if !strings.HasPrefix(s, "\"") { - return nextToken(s) - } - s = s[1:] - for i := 0; i < len(s); i++ { - switch s[i] { - case '"': - return s[:i], s[i+1:] - case '\\': - p := make([]byte, len(s)-1) - j := copy(p, s[:i]) - escape := true - for i = i + 1; i < len(s); i++ { - b := s[i] - switch { - case escape: - escape = false - p[j] = b - j++ - case b == '\\': - escape = true - case b == '"': - return string(p[:j]), s[i+1:] - default: - p[j] = b - j++ - } - } - return "", "" - } - } - return "", "" -} - -// equalASCIIFold returns true if s is equal to t with ASCII case folding as -// defined in RFC 4790. -func equalASCIIFold(s, t string) bool { - for s != "" && t != "" { - sr, size := utf8.DecodeRuneInString(s) - s = s[size:] - tr, size := utf8.DecodeRuneInString(t) - t = t[size:] - if sr == tr { - continue - } - if 'A' <= sr && sr <= 'Z' { - sr = sr + 'a' - 'A' - } - if 'A' <= tr && tr <= 'Z' { - tr = tr + 'a' - 'A' - } - if sr != tr { - return false - } - } - return s == t -} - -// tokenListContainsValue returns true if the 1#token header with the given -// name contains a token equal to value with ASCII case folding. -func tokenListContainsValue(header http.Header, name string, value string) bool { -headers: - for _, s := range header[name] { - for { - var t string - t, s = nextToken(skipSpace(s)) - if t == "" { - continue headers - } - s = skipSpace(s) - if s != "" && s[0] != ',' { - continue headers - } - if equalASCIIFold(t, value) { - return true - } - if s == "" { - continue headers - } - s = s[1:] - } - } - return false -} - -// parseExtensions parses WebSocket extensions from a header. -func parseExtensions(header http.Header) []map[string]string { - // From RFC 6455: - // - // Sec-WebSocket-Extensions = extension-list - // extension-list = 1#extension - // extension = extension-token *( ";" extension-param ) - // extension-token = registered-token - // registered-token = token - // extension-param = token [ "=" (token | quoted-string) ] - // ;When using the quoted-string syntax variant, the value - // ;after quoted-string unescaping MUST conform to the - // ;'token' ABNF. - - var result []map[string]string -headers: - for _, s := range header["Sec-Websocket-Extensions"] { - for { - var t string - t, s = nextToken(skipSpace(s)) - if t == "" { - continue headers - } - ext := map[string]string{"": t} - for { - s = skipSpace(s) - if !strings.HasPrefix(s, ";") { - break - } - var k string - k, s = nextToken(skipSpace(s[1:])) - if k == "" { - continue headers - } - s = skipSpace(s) - var v string - if strings.HasPrefix(s, "=") { - v, s = nextTokenOrQuoted(skipSpace(s[1:])) - s = skipSpace(s) - } - if s != "" && s[0] != ',' && s[0] != ';' { - continue headers - } - ext[k] = v - } - if s != "" && s[0] != ',' { - continue headers - } - result = append(result, ext) - if s == "" { - continue headers - } - s = s[1:] - } - } - return result -} diff --git a/vendor/github.com/gorilla/websocket/x_net_proxy.go b/vendor/github.com/gorilla/websocket/x_net_proxy.go deleted file mode 100644 index 2e668f6b8..000000000 --- a/vendor/github.com/gorilla/websocket/x_net_proxy.go +++ /dev/null @@ -1,473 +0,0 @@ -// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. -//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy - -// Package proxy provides support for a variety of protocols to proxy network -// data. -// - -package websocket - -import ( - "errors" - "io" - "net" - "net/url" - "os" - "strconv" - "strings" - "sync" -) - -type proxy_direct struct{} - -// Direct is a direct proxy: one that makes network connections directly. -var proxy_Direct = proxy_direct{} - -func (proxy_direct) Dial(network, addr string) (net.Conn, error) { - return net.Dial(network, addr) -} - -// A PerHost directs connections to a default Dialer unless the host name -// requested matches one of a number of exceptions. -type proxy_PerHost struct { - def, bypass proxy_Dialer - - bypassNetworks []*net.IPNet - bypassIPs []net.IP - bypassZones []string - bypassHosts []string -} - -// NewPerHost returns a PerHost Dialer that directs connections to either -// defaultDialer or bypass, depending on whether the connection matches one of -// the configured rules. -func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost { - return &proxy_PerHost{ - def: defaultDialer, - bypass: bypass, - } -} - -// Dial connects to the address addr on the given network through either -// defaultDialer or bypass. -func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) { - host, _, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } - - return p.dialerForRequest(host).Dial(network, addr) -} - -func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer { - if ip := net.ParseIP(host); ip != nil { - for _, net := range p.bypassNetworks { - if net.Contains(ip) { - return p.bypass - } - } - for _, bypassIP := range p.bypassIPs { - if bypassIP.Equal(ip) { - return p.bypass - } - } - return p.def - } - - for _, zone := range p.bypassZones { - if strings.HasSuffix(host, zone) { - return p.bypass - } - if host == zone[1:] { - // For a zone ".example.com", we match "example.com" - // too. - return p.bypass - } - } - for _, bypassHost := range p.bypassHosts { - if bypassHost == host { - return p.bypass - } - } - return p.def -} - -// AddFromString parses a string that contains comma-separated values -// specifying hosts that should use the bypass proxy. Each value is either an -// IP address, a CIDR range, a zone (*.example.com) or a host name -// (localhost). A best effort is made to parse the string and errors are -// ignored. -func (p *proxy_PerHost) AddFromString(s string) { - hosts := strings.Split(s, ",") - for _, host := range hosts { - host = strings.TrimSpace(host) - if len(host) == 0 { - continue - } - if strings.Contains(host, "/") { - // We assume that it's a CIDR address like 127.0.0.0/8 - if _, net, err := net.ParseCIDR(host); err == nil { - p.AddNetwork(net) - } - continue - } - if ip := net.ParseIP(host); ip != nil { - p.AddIP(ip) - continue - } - if strings.HasPrefix(host, "*.") { - p.AddZone(host[1:]) - continue - } - p.AddHost(host) - } -} - -// AddIP specifies an IP address that will use the bypass proxy. Note that -// this will only take effect if a literal IP address is dialed. A connection -// to a named host will never match an IP. -func (p *proxy_PerHost) AddIP(ip net.IP) { - p.bypassIPs = append(p.bypassIPs, ip) -} - -// AddNetwork specifies an IP range that will use the bypass proxy. Note that -// this will only take effect if a literal IP address is dialed. A connection -// to a named host will never match. -func (p *proxy_PerHost) AddNetwork(net *net.IPNet) { - p.bypassNetworks = append(p.bypassNetworks, net) -} - -// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of -// "example.com" matches "example.com" and all of its subdomains. -func (p *proxy_PerHost) AddZone(zone string) { - if strings.HasSuffix(zone, ".") { - zone = zone[:len(zone)-1] - } - if !strings.HasPrefix(zone, ".") { - zone = "." + zone - } - p.bypassZones = append(p.bypassZones, zone) -} - -// AddHost specifies a host name that will use the bypass proxy. -func (p *proxy_PerHost) AddHost(host string) { - if strings.HasSuffix(host, ".") { - host = host[:len(host)-1] - } - p.bypassHosts = append(p.bypassHosts, host) -} - -// A Dialer is a means to establish a connection. -type proxy_Dialer interface { - // Dial connects to the given address via the proxy. - Dial(network, addr string) (c net.Conn, err error) -} - -// Auth contains authentication parameters that specific Dialers may require. -type proxy_Auth struct { - User, Password string -} - -// FromEnvironment returns the dialer specified by the proxy related variables in -// the environment. -func proxy_FromEnvironment() proxy_Dialer { - allProxy := proxy_allProxyEnv.Get() - if len(allProxy) == 0 { - return proxy_Direct - } - - proxyURL, err := url.Parse(allProxy) - if err != nil { - return proxy_Direct - } - proxy, err := proxy_FromURL(proxyURL, proxy_Direct) - if err != nil { - return proxy_Direct - } - - noProxy := proxy_noProxyEnv.Get() - if len(noProxy) == 0 { - return proxy - } - - perHost := proxy_NewPerHost(proxy, proxy_Direct) - perHost.AddFromString(noProxy) - return perHost -} - -// proxySchemes is a map from URL schemes to a function that creates a Dialer -// from a URL with such a scheme. -var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error) - -// RegisterDialerType takes a URL scheme and a function to generate Dialers from -// a URL with that scheme and a forwarding Dialer. Registered schemes are used -// by FromURL. -func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) { - if proxy_proxySchemes == nil { - proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) - } - proxy_proxySchemes[scheme] = f -} - -// FromURL returns a Dialer given a URL specification and an underlying -// Dialer for it to make network requests. -func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) { - var auth *proxy_Auth - if u.User != nil { - auth = new(proxy_Auth) - auth.User = u.User.Username() - if p, ok := u.User.Password(); ok { - auth.Password = p - } - } - - switch u.Scheme { - case "socks5": - return proxy_SOCKS5("tcp", u.Host, auth, forward) - } - - // If the scheme doesn't match any of the built-in schemes, see if it - // was registered by another package. - if proxy_proxySchemes != nil { - if f, ok := proxy_proxySchemes[u.Scheme]; ok { - return f(u, forward) - } - } - - return nil, errors.New("proxy: unknown scheme: " + u.Scheme) -} - -var ( - proxy_allProxyEnv = &proxy_envOnce{ - names: []string{"ALL_PROXY", "all_proxy"}, - } - proxy_noProxyEnv = &proxy_envOnce{ - names: []string{"NO_PROXY", "no_proxy"}, - } -) - -// envOnce looks up an environment variable (optionally by multiple -// names) once. It mitigates expensive lookups on some platforms -// (e.g. Windows). -// (Borrowed from net/http/transport.go) -type proxy_envOnce struct { - names []string - once sync.Once - val string -} - -func (e *proxy_envOnce) Get() string { - e.once.Do(e.init) - return e.val -} - -func (e *proxy_envOnce) init() { - for _, n := range e.names { - e.val = os.Getenv(n) - if e.val != "" { - return - } - } -} - -// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address -// with an optional username and password. See RFC 1928 and RFC 1929. -func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) { - s := &proxy_socks5{ - network: network, - addr: addr, - forward: forward, - } - if auth != nil { - s.user = auth.User - s.password = auth.Password - } - - return s, nil -} - -type proxy_socks5 struct { - user, password string - network, addr string - forward proxy_Dialer -} - -const proxy_socks5Version = 5 - -const ( - proxy_socks5AuthNone = 0 - proxy_socks5AuthPassword = 2 -) - -const proxy_socks5Connect = 1 - -const ( - proxy_socks5IP4 = 1 - proxy_socks5Domain = 3 - proxy_socks5IP6 = 4 -) - -var proxy_socks5Errors = []string{ - "", - "general failure", - "connection forbidden", - "network unreachable", - "host unreachable", - "connection refused", - "TTL expired", - "command not supported", - "address type not supported", -} - -// Dial connects to the address addr on the given network via the SOCKS5 proxy. -func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) { - switch network { - case "tcp", "tcp6", "tcp4": - default: - return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) - } - - conn, err := s.forward.Dial(s.network, s.addr) - if err != nil { - return nil, err - } - if err := s.connect(conn, addr); err != nil { - conn.Close() - return nil, err - } - return conn, nil -} - -// connect takes an existing connection to a socks5 proxy server, -// and commands the server to extend that connection to target, -// which must be a canonical address with a host and port. -func (s *proxy_socks5) connect(conn net.Conn, target string) error { - host, portStr, err := net.SplitHostPort(target) - if err != nil { - return err - } - - port, err := strconv.Atoi(portStr) - if err != nil { - return errors.New("proxy: failed to parse port number: " + portStr) - } - if port < 1 || port > 0xffff { - return errors.New("proxy: port number out of range: " + portStr) - } - - // the size here is just an estimate - buf := make([]byte, 0, 6+len(host)) - - buf = append(buf, proxy_socks5Version) - if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { - buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword) - } else { - buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone) - } - - if _, err := conn.Write(buf); err != nil { - return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - if buf[0] != 5 { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) - } - if buf[1] == 0xff { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") - } - - // See RFC 1929 - if buf[1] == proxy_socks5AuthPassword { - buf = buf[:0] - buf = append(buf, 1 /* password protocol version */) - buf = append(buf, uint8(len(s.user))) - buf = append(buf, s.user...) - buf = append(buf, uint8(len(s.password))) - buf = append(buf, s.password...) - - if _, err := conn.Write(buf); err != nil { - return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if buf[1] != 0 { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") - } - } - - buf = buf[:0] - buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */) - - if ip := net.ParseIP(host); ip != nil { - if ip4 := ip.To4(); ip4 != nil { - buf = append(buf, proxy_socks5IP4) - ip = ip4 - } else { - buf = append(buf, proxy_socks5IP6) - } - buf = append(buf, ip...) - } else { - if len(host) > 255 { - return errors.New("proxy: destination host name too long: " + host) - } - buf = append(buf, proxy_socks5Domain) - buf = append(buf, byte(len(host))) - buf = append(buf, host...) - } - buf = append(buf, byte(port>>8), byte(port)) - - if _, err := conn.Write(buf); err != nil { - return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err := io.ReadFull(conn, buf[:4]); err != nil { - return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - failure := "unknown error" - if int(buf[1]) < len(proxy_socks5Errors) { - failure = proxy_socks5Errors[buf[1]] - } - - if len(failure) > 0 { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) - } - - bytesToDiscard := 0 - switch buf[3] { - case proxy_socks5IP4: - bytesToDiscard = net.IPv4len - case proxy_socks5IP6: - bytesToDiscard = net.IPv6len - case proxy_socks5Domain: - _, err := io.ReadFull(conn, buf[:1]) - if err != nil { - return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - bytesToDiscard = int(buf[0]) - default: - return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) - } - - if cap(buf) < bytesToDiscard { - buf = make([]byte, bytesToDiscard) - } else { - buf = buf[:bytesToDiscard] - } - if _, err := io.ReadFull(conn, buf); err != nil { - return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - // Also need to discard the port number - if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - return nil -} diff --git a/vendor/github.com/sourcegraph/jsonrpc2/.travis.yml b/vendor/github.com/sourcegraph/jsonrpc2/.travis.yml deleted file mode 100644 index 7b2f9de0f..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: go -go: - - 1.x - -script: - - go test -race -v ./... diff --git a/vendor/github.com/sourcegraph/jsonrpc2/LICENSE b/vendor/github.com/sourcegraph/jsonrpc2/LICENSE deleted file mode 100644 index 89d864bd8..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (c) 2016 Sourcegraph Inc - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/sourcegraph/jsonrpc2/README.md b/vendor/github.com/sourcegraph/jsonrpc2/README.md deleted file mode 100644 index d2406ab07..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# jsonrpc2: JSON-RPC 2.0 implementation for Go [![Build Status](https://travis-ci.org/sourcegraph/jsonrpc2.svg)](https://travis-ci.org/sourcegraph/jsonrpc2) [![Sourcegraph](https://sourcegraph.com/github.com/sourcegraph/jsonrpc2/-/badge.svg)](https://sourcegraph.com/github.com/sourcegraph/jsonrpc2?badge) [![GoDoc](https://godoc.org/github.com/sourcegraph/jsonrpc2?status.svg)](https://godoc.org/github.com/sourcegraph/jsonrpc2) - - -Package jsonrpc2 provides a [Go](https://golang.org) implementation of [JSON-RPC 2.0](http://www.jsonrpc.org/specification). - -This package is **experimental** until further notice. - -[**Open the code in Sourcegraph**](https://sourcegraph.com/github.com/sourcegraph/jsonrpc2) - -## Known issues - -* Batch requests and responses are not yet supported. diff --git a/vendor/github.com/sourcegraph/jsonrpc2/async.go b/vendor/github.com/sourcegraph/jsonrpc2/async.go deleted file mode 100644 index bc8a3708a..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/async.go +++ /dev/null @@ -1,17 +0,0 @@ -package jsonrpc2 - -import "context" - -// AsyncHandler wraps a Handler such that each request is handled in its own -// goroutine. It is a convenience wrapper. -func AsyncHandler(h Handler) Handler { - return asyncHandler{h} -} - -type asyncHandler struct { - Handler -} - -func (h asyncHandler) Handle(ctx context.Context, conn *Conn, req *Request) { - go h.Handler.Handle(ctx, conn, req) -} diff --git a/vendor/github.com/sourcegraph/jsonrpc2/call_opt.go b/vendor/github.com/sourcegraph/jsonrpc2/call_opt.go deleted file mode 100644 index b554baca8..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/call_opt.go +++ /dev/null @@ -1,30 +0,0 @@ -package jsonrpc2 - -// CallOption is an option that can be provided to (*Conn).Call to -// configure custom behavior. See Meta. -type CallOption interface { - apply(r *Request) error -} - -type callOptionFunc func(r *Request) error - -func (c callOptionFunc) apply(r *Request) error { return c(r) } - -// Meta returns a call option which attaches the given meta object to -// the JSON-RPC 2.0 request (this is a Sourcegraph extension to JSON -// RPC 2.0 for carrying metadata). -func Meta(meta interface{}) CallOption { - return callOptionFunc(func(r *Request) error { - return r.SetMeta(meta) - }) -} - -// PickID returns a call option which sets the ID on a request. Care must be -// taken to ensure there are no conflicts with any previously picked ID, nor -// with the default sequence ID. -func PickID(id ID) CallOption { - return callOptionFunc(func(r *Request) error { - r.ID = id - return nil - }) -} diff --git a/vendor/github.com/sourcegraph/jsonrpc2/conn_opt.go b/vendor/github.com/sourcegraph/jsonrpc2/conn_opt.go deleted file mode 100644 index 3779d7f0f..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/conn_opt.go +++ /dev/null @@ -1,104 +0,0 @@ -package jsonrpc2 - -import ( - "encoding/json" - "sync" -) - -// Logger interface implements one method - Printf. -// You can use the stdlib logger *log.Logger -type Logger interface { - Printf(format string, v ...interface{}) -} - -// ConnOpt is the type of function that can be passed to NewConn to -// customize the Conn before it is created. -type ConnOpt func(*Conn) - -// OnRecv causes all requests received on conn to invoke f(req, nil) -// and all responses to invoke f(req, resp), -func OnRecv(f func(*Request, *Response)) ConnOpt { - return func(c *Conn) { c.onRecv = append(c.onRecv, f) } -} - -// OnSend causes all requests sent on conn to invoke f(req, nil) and -// all responses to invoke f(nil, resp), -func OnSend(f func(*Request, *Response)) ConnOpt { - return func(c *Conn) { c.onSend = append(c.onSend, f) } -} - -// LogMessages causes all messages sent and received on conn to be -// logged using the provided logger. -func LogMessages(logger Logger) ConnOpt { - return func(c *Conn) { - // Remember reqs we have received so we can helpfully show the - // request method in OnSend for responses. - var ( - mu sync.Mutex - reqMethods = map[ID]string{} - ) - - // Set custom logger from provided input - c.logger = logger - - OnRecv(func(req *Request, resp *Response) { - switch { - case req != nil: - mu.Lock() - reqMethods[req.ID] = req.Method - mu.Unlock() - - params, _ := json.Marshal(req.Params) - if req.Notif { - logger.Printf("jsonrpc2: --> notif: %s: %s\n", req.Method, params) - } else { - logger.Printf("jsonrpc2: --> request #%s: %s: %s\n", req.ID, req.Method, params) - } - - case resp != nil: - var method string - if req != nil { - method = req.Method - } else { - method = "(no matching request)" - } - switch { - case resp.Result != nil: - result, _ := json.Marshal(resp.Result) - logger.Printf("jsonrpc2: --> result #%s: %s: %s\n", resp.ID, method, result) - case resp.Error != nil: - err, _ := json.Marshal(resp.Error) - logger.Printf("jsonrpc2: --> error #%s: %s: %s\n", resp.ID, method, err) - } - } - })(c) - OnSend(func(req *Request, resp *Response) { - switch { - case req != nil: - params, _ := json.Marshal(req.Params) - if req.Notif { - logger.Printf("jsonrpc2: <-- notif: %s: %s\n", req.Method, params) - } else { - logger.Printf("jsonrpc2: <-- request #%s: %s: %s\n", req.ID, req.Method, params) - } - - case resp != nil: - mu.Lock() - method := reqMethods[resp.ID] - delete(reqMethods, resp.ID) - mu.Unlock() - if method == "" { - method = "(no previous request)" - } - - if resp.Result != nil { - result, _ := json.Marshal(resp.Result) - logger.Printf("jsonrpc2: <-- result #%s: %s: %s\n", resp.ID, method, result) - } else { - err, _ := json.Marshal(resp.Error) - logger.Printf("jsonrpc2: <-- error #%s: %s: %s\n", resp.ID, method, err) - } - } - })(c) - } -} diff --git a/vendor/github.com/sourcegraph/jsonrpc2/go.mod b/vendor/github.com/sourcegraph/jsonrpc2/go.mod deleted file mode 100644 index 95cca53ca..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/sourcegraph/jsonrpc2 - -go 1.12 - -require github.com/gorilla/websocket v1.4.1 diff --git a/vendor/github.com/sourcegraph/jsonrpc2/go.sum b/vendor/github.com/sourcegraph/jsonrpc2/go.sum deleted file mode 100644 index 1f9b923e9..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= diff --git a/vendor/github.com/sourcegraph/jsonrpc2/handler_with_error.go b/vendor/github.com/sourcegraph/jsonrpc2/handler_with_error.go deleted file mode 100644 index 2bd5c1d90..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/handler_with_error.go +++ /dev/null @@ -1,64 +0,0 @@ -package jsonrpc2 - -import ( - "context" -) - -// HandlerWithError implements Handler by calling the func for each -// request and handling returned errors and results. -func HandlerWithError(handleFunc func(context.Context, *Conn, *Request) (result interface{}, err error)) *HandlerWithErrorConfigurer { - return &HandlerWithErrorConfigurer{handleFunc: handleFunc} -} - -// HandlerWithErrorConfigurer is a handler created by HandlerWithError. -type HandlerWithErrorConfigurer struct { - handleFunc func(context.Context, *Conn, *Request) (result interface{}, err error) - suppressErrClosed bool -} - -// Handle implements Handler. -func (h *HandlerWithErrorConfigurer) Handle(ctx context.Context, conn *Conn, req *Request) { - result, err := h.handleFunc(ctx, conn, req) - if req.Notif { - if err != nil { - conn.logger.Printf("jsonrpc2 handler: notification %q handling error: %v\n", req.Method, err) - } - return - } - - resp := &Response{ID: req.ID} - if err == nil { - err = resp.SetResult(result) - } - if err != nil { - if e, ok := err.(*Error); ok { - resp.Error = e - } else { - resp.Error = &Error{Message: err.Error()} - } - } - - if !req.Notif { - if err := conn.SendResponse(ctx, resp); err != nil { - if err != ErrClosed || !h.suppressErrClosed { - conn.logger.Printf("jsonrpc2 handler: sending response %s: %v\n", resp.ID, err) - } - } - } -} - -// SuppressErrClosed makes the handler suppress jsonrpc2.ErrClosed errors from -// being logged. The original handler `h` is returned. -// -// This is optional because only in some cases is this behavior desired. For -// example, a handler that serves end-user connections may not want to log -// ErrClosed because it just indicates the end-user connection has gone away -// for any reason (they could have lost wifi connection, are no longer -// interested in the request and closed the connection, etc) and as such it -// would be log spam, whereas a handler that serves internal connections would -// never expect connections to go away unexpectedly (which could indicate -// service degradation, etc) and as such ErrClosed should always be logged. -func (h *HandlerWithErrorConfigurer) SuppressErrClosed() Handler { - h.suppressErrClosed = true - return h -} diff --git a/vendor/github.com/sourcegraph/jsonrpc2/jsonrpc2.go b/vendor/github.com/sourcegraph/jsonrpc2/jsonrpc2.go deleted file mode 100644 index 54e012f9e..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/jsonrpc2.go +++ /dev/null @@ -1,702 +0,0 @@ -// Package jsonrpc2 provides a client and server implementation of -// [JSON-RPC 2.0](http://www.jsonrpc.org/specification). -package jsonrpc2 - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "log" - "os" - "strconv" - "sync" -) - -// JSONRPC2 describes an interface for issuing requests that speak the -// JSON-RPC 2 protocol. It isn't really necessary for this package -// itself, but is useful for external users that use the interface as -// an API boundary. -type JSONRPC2 interface { - // Call issues a standard request (http://www.jsonrpc.org/specification#request_object). - Call(ctx context.Context, method string, params, result interface{}, opt ...CallOption) error - - // Notify issues a notification request (http://www.jsonrpc.org/specification#notification). - Notify(ctx context.Context, method string, params interface{}, opt ...CallOption) error - - // Close closes the underlying connection, if it exists. - Close() error -} - -// Request represents a JSON-RPC request or -// notification. See -// http://www.jsonrpc.org/specification#request_object and -// http://www.jsonrpc.org/specification#notification. -type Request struct { - Method string `json:"method"` - Params *json.RawMessage `json:"params,omitempty"` - ID ID `json:"id"` - Notif bool `json:"-"` - - // Meta optionally provides metadata to include in the request. - // - // NOTE: It is not part of spec. However, it is useful for propogating - // tracing context, etc. - Meta *json.RawMessage `json:"meta,omitempty"` -} - -// MarshalJSON implements json.Marshaler and adds the "jsonrpc":"2.0" -// property. -func (r Request) MarshalJSON() ([]byte, error) { - r2 := struct { - Method string `json:"method"` - Params *json.RawMessage `json:"params,omitempty"` - ID *ID `json:"id,omitempty"` - Meta *json.RawMessage `json:"meta,omitempty"` - JSONRPC string `json:"jsonrpc"` - }{ - Method: r.Method, - Params: r.Params, - Meta: r.Meta, - JSONRPC: "2.0", - } - if !r.Notif { - r2.ID = &r.ID - } - return json.Marshal(r2) -} - -// UnmarshalJSON implements json.Unmarshaler. -func (r *Request) UnmarshalJSON(data []byte) error { - var r2 struct { - Method string `json:"method"` - Params *json.RawMessage `json:"params,omitempty"` - Meta *json.RawMessage `json:"meta,omitempty"` - ID *ID `json:"id"` - } - - // Detect if the "params" field is JSON "null" or just not present - // by seeing if the field gets overwritten to nil. - r2.Params = &json.RawMessage{} - - if err := json.Unmarshal(data, &r2); err != nil { - return err - } - r.Method = r2.Method - switch { - case r2.Params == nil: - r.Params = &jsonNull - case len(*r2.Params) == 0: - r.Params = nil - default: - r.Params = r2.Params - } - r.Meta = r2.Meta - if r2.ID == nil { - r.ID = ID{} - r.Notif = true - } else { - r.ID = *r2.ID - r.Notif = false - } - return nil -} - -// SetParams sets r.Params to the JSON representation of v. If JSON -// marshaling fails, it returns an error. -func (r *Request) SetParams(v interface{}) error { - b, err := json.Marshal(v) - if err != nil { - return err - } - r.Params = (*json.RawMessage)(&b) - return nil -} - -// SetMeta sets r.Meta to the JSON representation of v. If JSON -// marshaling fails, it returns an error. -func (r *Request) SetMeta(v interface{}) error { - b, err := json.Marshal(v) - if err != nil { - return err - } - r.Meta = (*json.RawMessage)(&b) - return nil -} - -// Response represents a JSON-RPC response. See -// http://www.jsonrpc.org/specification#response_object. -type Response struct { - ID ID `json:"id"` - Result *json.RawMessage `json:"result,omitempty"` - Error *Error `json:"error,omitempty"` - - // Meta optionally provides metadata to include in the response. - // - // NOTE: It is not part of spec. However, it is useful for propogating - // tracing context, etc. - Meta *json.RawMessage `json:"meta,omitempty"` - - // SPEC NOTE: The spec says "If there was an error in detecting - // the id in the Request object (e.g. Parse error/Invalid - // Request), it MUST be Null." If we made the ID field nullable, - // then we'd have to make it a pointer type. For simplicity, we're - // ignoring the case where there was an error in detecting the ID - // in the Request object. -} - -// MarshalJSON implements json.Marshaler and adds the "jsonrpc":"2.0" -// property. -func (r Response) MarshalJSON() ([]byte, error) { - if (r.Result == nil || len(*r.Result) == 0) && r.Error == nil { - return nil, errors.New("can't marshal *jsonrpc2.Response (must have result or error)") - } - type tmpType Response // avoid infinite MarshalJSON recursion - b, err := json.Marshal(tmpType(r)) - if err != nil { - return nil, err - } - b = append(b[:len(b)-1], []byte(`,"jsonrpc":"2.0"}`)...) - return b, nil -} - -// UnmarshalJSON implements json.Unmarshaler. -func (r *Response) UnmarshalJSON(data []byte) error { - type tmpType Response - - // Detect if the "result" field is JSON "null" or just not present - // by seeing if the field gets overwritten to nil. - *r = Response{Result: &json.RawMessage{}} - - if err := json.Unmarshal(data, (*tmpType)(r)); err != nil { - return err - } - if r.Result == nil { // JSON "null" - r.Result = &jsonNull - } else if len(*r.Result) == 0 { - r.Result = nil - } - return nil -} - -// SetResult sets r.Result to the JSON representation of v. If JSON -// marshaling fails, it returns an error. -func (r *Response) SetResult(v interface{}) error { - b, err := json.Marshal(v) - if err != nil { - return err - } - r.Result = (*json.RawMessage)(&b) - return nil -} - -// Error represents a JSON-RPC response error. -type Error struct { - Code int64 `json:"code"` - Message string `json:"message"` - Data *json.RawMessage `json:"data"` -} - -// SetError sets e.Error to the JSON representation of v. If JSON -// marshaling fails, it panics. -func (e *Error) SetError(v interface{}) { - b, err := json.Marshal(v) - if err != nil { - panic("Error.SetData: " + err.Error()) - } - e.Data = (*json.RawMessage)(&b) -} - -// Error implements the Go error interface. -func (e *Error) Error() string { - return fmt.Sprintf("jsonrpc2: code %v message: %s", e.Code, e.Message) -} - -// Errors defined in the JSON-RPC spec. See -// http://www.jsonrpc.org/specification#error_object. -const ( - CodeParseError = -32700 - CodeInvalidRequest = -32600 - CodeMethodNotFound = -32601 - CodeInvalidParams = -32602 - CodeInternalError = -32603 -) - -// Handler handles JSON-RPC requests and notifications. -type Handler interface { - // Handle is called to handle a request. No other requests are handled - // until it returns. If you do not require strict ordering behavior - // of received RPCs, it is suggested to wrap your handler in - // AsyncHandler. - Handle(context.Context, *Conn, *Request) -} - -// ID represents a JSON-RPC 2.0 request ID, which may be either a -// string or number (or null, which is unsupported). -type ID struct { - // At most one of Num or Str may be nonzero. If both are zero - // valued, then IsNum specifies which field's value is to be used - // as the ID. - Num uint64 - Str string - - // IsString controls whether the Num or Str field's value should be - // used as the ID, when both are zero valued. It must always be - // set to true if the request ID is a string. - IsString bool -} - -func (id ID) String() string { - if id.IsString { - return strconv.Quote(id.Str) - } - return strconv.FormatUint(id.Num, 10) -} - -// MarshalJSON implements json.Marshaler. -func (id ID) MarshalJSON() ([]byte, error) { - if id.IsString { - return json.Marshal(id.Str) - } - return json.Marshal(id.Num) -} - -// UnmarshalJSON implements json.Unmarshaler. -func (id *ID) UnmarshalJSON(data []byte) error { - // Support both uint64 and string IDs. - var v uint64 - if err := json.Unmarshal(data, &v); err == nil { - *id = ID{Num: v} - return nil - } - var v2 string - if err := json.Unmarshal(data, &v2); err != nil { - return err - } - *id = ID{Str: v2, IsString: true} - return nil -} - -// Conn is a JSON-RPC client/server connection. The JSON-RPC protocol -// is symmetric, so a Conn runs on both ends of a client-server -// connection. -type Conn struct { - stream ObjectStream - - h Handler - - mu sync.Mutex - shutdown bool - closing bool - seq uint64 - pending map[ID]*call - - sending sync.Mutex - - disconnect chan struct{} - - logger Logger - - // Set by ConnOpt funcs. - onRecv []func(*Request, *Response) - onSend []func(*Request, *Response) -} - -var _ JSONRPC2 = (*Conn)(nil) - -// ErrClosed indicates that the JSON-RPC connection is closed (or in -// the process of closing). -var ErrClosed = errors.New("jsonrpc2: connection is closed") - -// NewConn creates a new JSON-RPC client/server connection using the -// given ReadWriteCloser (typically a TCP connection or stdio). The -// JSON-RPC protocol is symmetric, so a Conn runs on both ends of a -// client-server connection. -// -// NewClient consumes conn, so you should call Close on the returned -// client not on the given conn. -func NewConn(ctx context.Context, stream ObjectStream, h Handler, opts ...ConnOpt) *Conn { - c := &Conn{ - stream: stream, - h: h, - pending: map[ID]*call{}, - disconnect: make(chan struct{}), - logger: log.New(os.Stderr, "", log.LstdFlags), - } - for _, opt := range opts { - if opt == nil { - continue - } - opt(c) - } - go c.readMessages(ctx) - return c -} - -// Close closes the JSON-RPC connection. The connection may not be -// used after it has been closed. -func (c *Conn) Close() error { - c.mu.Lock() - if c.shutdown || c.closing { - c.mu.Unlock() - return ErrClosed - } - c.closing = true - c.mu.Unlock() - return c.stream.Close() -} - -func (c *Conn) send(_ context.Context, m *anyMessage, wait bool) (cc *call, err error) { - c.sending.Lock() - defer c.sending.Unlock() - - // m.request.ID could be changed, so we store a copy to correctly - // clean up pending - var id ID - - c.mu.Lock() - if c.shutdown || c.closing { - c.mu.Unlock() - return nil, ErrClosed - } - - // Store requests so we can later associate them with incoming - // responses. - if m.request != nil && wait { - cc = &call{request: m.request, seq: c.seq, done: make(chan error, 1)} - if !m.request.ID.IsString && m.request.ID.Num == 0 { - // unset, use next seq as call ID - m.request.ID.Num = c.seq - } - id = m.request.ID - c.pending[id] = cc - c.seq++ - } - c.mu.Unlock() - - if len(c.onSend) > 0 { - var ( - req *Request - resp *Response - ) - switch { - case m.request != nil: - req = m.request - case m.response != nil: - resp = m.response - } - for _, onSend := range c.onSend { - onSend(req, resp) - } - } - - // From here on, if we fail to send this, then we need to remove - // this from the pending map so we don't block on it or pile up - // pending entries for unsent messages. - defer func() { - if err != nil { - if cc != nil { - c.mu.Lock() - delete(c.pending, id) - c.mu.Unlock() - } - } - }() - - if err := c.stream.WriteObject(m); err != nil { - return nil, err - } - return cc, nil -} - -// Call initiates a JSON-RPC call using the specified method and -// params, and waits for the response. If the response is successful, -// its result is stored in result (a pointer to a value that can be -// JSON-unmarshaled into); otherwise, a non-nil error is returned. -func (c *Conn) Call(ctx context.Context, method string, params, result interface{}, opts ...CallOption) error { - req := &Request{Method: method} - if err := req.SetParams(params); err != nil { - return err - } - for _, opt := range opts { - if opt == nil { - continue - } - if err := opt.apply(req); err != nil { - return err - } - } - call, err := c.send(ctx, &anyMessage{request: req}, true) - if err != nil { - return err - } - select { - case err, ok := <-call.done: - if !ok { - err = ErrClosed - } - if err != nil { - return err - } - if result != nil { - if call.response.Result == nil { - call.response.Result = &jsonNull - } - if err := json.Unmarshal(*call.response.Result, result); err != nil { - return err - } - } - return nil - - case <-ctx.Done(): - return ctx.Err() - } -} - -var jsonNull = json.RawMessage("null") - -// Notify is like Call, but it returns when the notification request -// is sent (without waiting for a response, because JSON-RPC -// notifications do not have responses). -func (c *Conn) Notify(ctx context.Context, method string, params interface{}, opts ...CallOption) error { - req := &Request{Method: method, Notif: true} - if err := req.SetParams(params); err != nil { - return err - } - for _, opt := range opts { - if opt == nil { - continue - } - if err := opt.apply(req); err != nil { - return err - } - } - _, err := c.send(ctx, &anyMessage{request: req}, false) - return err -} - -// Reply sends a successful response with a result. -func (c *Conn) Reply(ctx context.Context, id ID, result interface{}) error { - resp := &Response{ID: id} - if err := resp.SetResult(result); err != nil { - return err - } - _, err := c.send(ctx, &anyMessage{response: resp}, false) - return err -} - -// ReplyWithError sends a response with an error. -func (c *Conn) ReplyWithError(ctx context.Context, id ID, respErr *Error) error { - _, err := c.send(ctx, &anyMessage{response: &Response{ID: id, Error: respErr}}, false) - return err -} - -// SendResponse sends resp to the peer. It is lower level than (*Conn).Reply. -func (c *Conn) SendResponse(ctx context.Context, resp *Response) error { - _, err := c.send(ctx, &anyMessage{response: resp}, false) - return err -} - -// DisconnectNotify returns a channel that is closed when the -// underlying connection is disconnected. -func (c *Conn) DisconnectNotify() <-chan struct{} { - return c.disconnect -} - -func (c *Conn) readMessages(ctx context.Context) { - var err error - for err == nil { - var m anyMessage - err = c.stream.ReadObject(&m) - if err != nil { - break - } - - switch { - case m.request != nil: - for _, onRecv := range c.onRecv { - onRecv(m.request, nil) - } - c.h.Handle(ctx, c, m.request) - - case m.response != nil: - resp := m.response - if resp != nil { - id := resp.ID - c.mu.Lock() - call := c.pending[id] - delete(c.pending, id) - c.mu.Unlock() - - if call != nil { - call.response = resp - } - - if len(c.onRecv) > 0 { - var req *Request - if call != nil { - req = call.request - } - for _, onRecv := range c.onRecv { - onRecv(req, resp) - } - } - - switch { - case call == nil: - c.logger.Printf("jsonrpc2: ignoring response #%s with no corresponding request\n", id) - - case resp.Error != nil: - call.done <- resp.Error - close(call.done) - - default: - call.done <- nil - close(call.done) - } - } - } - } - - c.sending.Lock() - c.mu.Lock() - c.shutdown = true - closing := c.closing - if err == io.EOF { - if closing { - err = ErrClosed - } else { - err = io.ErrUnexpectedEOF - } - } - for _, call := range c.pending { - call.done <- err - close(call.done) - } - c.mu.Unlock() - c.sending.Unlock() - if err != io.ErrUnexpectedEOF && !closing { - c.logger.Printf("jsonrpc2: protocol error: %v\n", err) - } - close(c.disconnect) -} - -// call represents a JSON-RPC call over its entire lifecycle. -type call struct { - request *Request - response *Response - seq uint64 // the seq of the request - done chan error -} - -// anyMessage represents either a JSON Request or Response. -type anyMessage struct { - request *Request - response *Response -} - -func (m anyMessage) MarshalJSON() ([]byte, error) { - var v interface{} - switch { - case m.request != nil && m.response == nil: - v = m.request - case m.request == nil && m.response != nil: - v = m.response - } - if v != nil { - return json.Marshal(v) - } - return nil, errors.New("jsonrpc2: message must have exactly one of the request or response fields set") -} - -func (m *anyMessage) UnmarshalJSON(data []byte) error { - // The presence of these fields distinguishes between the 2 - // message types. - type msg struct { - ID interface{} `json:"id"` - Method *string `json:"method"` - Result anyValueWithExplicitNull `json:"result"` - Error interface{} `json:"error"` - } - - var isRequest, isResponse bool - checkType := func(m *msg) error { - mIsRequest := m.Method != nil - mIsResponse := m.Result.null || m.Result.value != nil || m.Error != nil - if (!mIsRequest && !mIsResponse) || (mIsRequest && mIsResponse) { - return errors.New("jsonrpc2: unable to determine message type (request or response)") - } - if (mIsRequest && isResponse) || (mIsResponse && isRequest) { - return errors.New("jsonrpc2: batch message type mismatch (must be all requests or all responses)") - } - isRequest = mIsRequest - isResponse = mIsResponse - return nil - } - - if isArray := len(data) > 0 && data[0] == '['; isArray { - var msgs []msg - if err := json.Unmarshal(data, &msgs); err != nil { - return err - } - if len(msgs) == 0 { - return errors.New("jsonrpc2: invalid empty batch") - } - for i := range msgs { - if err := checkType(&msg{ - ID: msgs[i].ID, - Method: msgs[i].Method, - Result: msgs[i].Result, - Error: msgs[i].Error, - }); err != nil { - return err - } - } - } else { - var m msg - if err := json.Unmarshal(data, &m); err != nil { - return err - } - if err := checkType(&m); err != nil { - return err - } - } - - var v interface{} - switch { - case isRequest && !isResponse: - v = &m.request - case !isRequest && isResponse: - v = &m.response - } - if err := json.Unmarshal(data, v); err != nil { - return err - } - if !isRequest && isResponse && m.response.Error == nil && m.response.Result == nil { - m.response.Result = &jsonNull - } - return nil -} - -// anyValueWithExplicitNull is used to distinguish {} from -// {"result":null} by anyMessage's JSON unmarshaler. -type anyValueWithExplicitNull struct { - null bool // JSON "null" - value interface{} -} - -func (v anyValueWithExplicitNull) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *anyValueWithExplicitNull) UnmarshalJSON(data []byte) error { - data = bytes.TrimSpace(data) - if string(data) == "null" { - *v = anyValueWithExplicitNull{null: true} - return nil - } - *v = anyValueWithExplicitNull{} - return json.Unmarshal(data, &v.value) -} diff --git a/vendor/github.com/sourcegraph/jsonrpc2/stream.go b/vendor/github.com/sourcegraph/jsonrpc2/stream.go deleted file mode 100644 index f38c026ac..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/stream.go +++ /dev/null @@ -1,164 +0,0 @@ -package jsonrpc2 - -import ( - "bufio" - "encoding/binary" - "encoding/json" - "fmt" - "io" - "strconv" - "strings" - "sync" -) - -// An ObjectStream is a bidirectional stream of JSON-RPC 2.0 objects. -type ObjectStream interface { - // WriteObject writes a JSON-RPC 2.0 object to the stream. - WriteObject(obj interface{}) error - - // ReadObject reads the next JSON-RPC 2.0 object from the stream - // and stores it in the value pointed to by v. - ReadObject(v interface{}) error - - io.Closer -} - -// A bufferedObjectStream is an ObjectStream that uses a buffered -// io.ReadWriteCloser to send and receive objects. -type bufferedObjectStream struct { - conn io.Closer // all writes should go through w, all reads through r - w *bufio.Writer - r *bufio.Reader - - codec ObjectCodec - - mu sync.Mutex -} - -// NewBufferedStream creates a buffered stream from a network -// connection (or other similar interface). The underlying -// objectStream is used to produce the bytes to write to the stream -// for the JSON-RPC 2.0 objects. -func NewBufferedStream(conn io.ReadWriteCloser, codec ObjectCodec) ObjectStream { - return &bufferedObjectStream{ - conn: conn, - w: bufio.NewWriter(conn), - r: bufio.NewReader(conn), - codec: codec, - } -} - -// WriteObject implements ObjectStream. -func (t *bufferedObjectStream) WriteObject(obj interface{}) error { - t.mu.Lock() - defer t.mu.Unlock() - if err := t.codec.WriteObject(t.w, obj); err != nil { - return err - } - return t.w.Flush() -} - -// ReadObject implements ObjectStream. -func (t *bufferedObjectStream) ReadObject(v interface{}) error { - return t.codec.ReadObject(t.r, v) -} - -// Close implements ObjectStream. -func (t *bufferedObjectStream) Close() error { - return t.conn.Close() -} - -// An ObjectCodec specifies how to encoed and decode a JSON-RPC 2.0 -// object in a stream. -type ObjectCodec interface { - // WriteObject writes a JSON-RPC 2.0 object to the stream. - WriteObject(stream io.Writer, obj interface{}) error - - // ReadObject reads the next JSON-RPC 2.0 object from the stream - // and stores it in the value pointed to by v. - ReadObject(stream *bufio.Reader, v interface{}) error -} - -// VarintObjectCodec reads/writes JSON-RPC 2.0 objects with a varint -// header that encodes the byte length. -type VarintObjectCodec struct{} - -// WriteObject implements ObjectCodec. -func (VarintObjectCodec) WriteObject(stream io.Writer, obj interface{}) error { - data, err := json.Marshal(obj) - if err != nil { - return err - } - var buf [binary.MaxVarintLen64]byte - b := binary.PutUvarint(buf[:], uint64(len(data))) - if _, err := stream.Write(buf[:b]); err != nil { - return err - } - if _, err := stream.Write(data); err != nil { - return err - } - return nil -} - -// ReadObject implements ObjectCodec. -func (VarintObjectCodec) ReadObject(stream *bufio.Reader, v interface{}) error { - b, err := binary.ReadUvarint(stream) - if err != nil { - return err - } - return json.NewDecoder(io.LimitReader(stream, int64(b))).Decode(v) -} - -// VSCodeObjectCodec reads/writes JSON-RPC 2.0 objects with -// Content-Length and Content-Type headers, as specified by -// https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#base-protocol. -type VSCodeObjectCodec struct{} - -// WriteObject implements ObjectCodec. -func (VSCodeObjectCodec) WriteObject(stream io.Writer, obj interface{}) error { - data, err := json.Marshal(obj) - if err != nil { - return err - } - if _, err := fmt.Fprintf(stream, "Content-Length: %d\r\n\r\n", len(data)); err != nil { - return err - } - if _, err := stream.Write(data); err != nil { - return err - } - return nil -} - -// ReadObject implements ObjectCodec. -func (VSCodeObjectCodec) ReadObject(stream *bufio.Reader, v interface{}) error { - var contentLength uint64 - for { - line, err := stream.ReadString('\r') - if err != nil { - return err - } - b, err := stream.ReadByte() - if err != nil { - return err - } - if b != '\n' { - return fmt.Errorf(`jsonrpc2: line endings must be \r\n`) - } - if line == "\r" { - break - } - if strings.HasPrefix(line, "Content-Length: ") { - line = strings.TrimPrefix(line, "Content-Length: ") - line = strings.TrimSpace(line) - var err error - contentLength, err = strconv.ParseUint(line, 10, 32) - if err != nil { - return err - } - } - } - if contentLength == 0 { - return fmt.Errorf("jsonrpc2: no Content-Length header found") - } - return json.NewDecoder(io.LimitReader(stream, int64(contentLength))).Decode(v) -} diff --git a/vendor/github.com/sourcegraph/jsonrpc2/websocket/stream.go b/vendor/github.com/sourcegraph/jsonrpc2/websocket/stream.go deleted file mode 100644 index 193363ce9..000000000 --- a/vendor/github.com/sourcegraph/jsonrpc2/websocket/stream.go +++ /dev/null @@ -1,44 +0,0 @@ -// Package websocket provides WebSocket transport support for JSON-RPC -// 2.0. -package websocket - -import ( - "io" - - ws "github.com/gorilla/websocket" -) - -// A ObjectStream is a jsonrpc2.ObjectStream that uses a WebSocket to -// send and receive JSON-RPC 2.0 objects. -type ObjectStream struct { - conn *ws.Conn -} - -// NewObjectStream creates a new jsonrpc2.ObjectStream for sending and -// receiving JSON-RPC 2.0 objects over a WebSocket. -func NewObjectStream(conn *ws.Conn) ObjectStream { - return ObjectStream{conn: conn} -} - -// WriteObject implements jsonrpc2.ObjectStream. -func (t ObjectStream) WriteObject(obj interface{}) error { - return t.conn.WriteJSON(obj) -} - -// ReadObject implements jsonrpc2.ObjectStream. -func (t ObjectStream) ReadObject(v interface{}) error { - err := t.conn.ReadJSON(v) - if e, ok := err.(*ws.CloseError); ok { - if e.Code == ws.CloseAbnormalClosure && e.Text == io.ErrUnexpectedEOF.Error() { - // Suppress a noisy (but harmless) log message by - // unwrapping this error. - err = io.ErrUnexpectedEOF - } - } - return err -} - -// Close implements jsonrpc2.ObjectStream. -func (t ObjectStream) Close() error { - return t.conn.Close() -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 90d643a76..30d3e5561 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -142,9 +142,6 @@ github.com/google/go-querystring/query # github.com/gorilla/securecookie v1.1.1 ## explicit github.com/gorilla/securecookie -# github.com/gorilla/websocket v1.4.2 -## explicit -github.com/gorilla/websocket # github.com/hashicorp/go-version v1.3.0 ## explicit github.com/hashicorp/go-version @@ -238,10 +235,6 @@ github.com/shurcooL/sanitized_anchor_name # github.com/sirupsen/logrus v1.6.0 ## explicit github.com/sirupsen/logrus -# github.com/sourcegraph/jsonrpc2 v0.0.0-20200429184054-15c2290dcb37 -## explicit -github.com/sourcegraph/jsonrpc2 -github.com/sourcegraph/jsonrpc2/websocket # github.com/stretchr/objx v0.2.0 ## explicit github.com/stretchr/objx