aboutsummaryrefslogtreecommitdiffstats
path: root/kube2msb/src/vendor/golang.org/x
diff options
context:
space:
mode:
authorHuabingZhao <zhao.huabing@zte.com.cn>2017-09-04 15:00:54 +0800
committerHuabingZhao <zhao.huabing@zte.com.cn>2017-09-04 15:06:21 +0800
commit43dac0bc4302fed79eaeb661723ca584a9c0496a (patch)
treea78f60300d73f0a69ed12e946d3fe4580455d8ba /kube2msb/src/vendor/golang.org/x
parenta7837a0ac51704003c6aacba2dacb8e64f681622 (diff)
restructure the source directory
Issue-ID: OOM-61 Change-Id: Ib6f633d517ad197bfdbca59b374cdad2f1ed897e Signed-off-by: HuabingZhao <zhao.huabing@zte.com.cn>
Diffstat (limited to 'kube2msb/src/vendor/golang.org/x')
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/LICENSE27
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/PATENTS22
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/context/context.go447
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/cancelreq.go19
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/cancelreq_go14.go23
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go140
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/Dockerfile51
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/Makefile3
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/README20
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/client_conn_pool.go225
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/configure_transport.go89
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/errors.go90
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/fixed_buffer.go60
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/flow.go50
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/frame.go1269
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/go15.go11
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/gotrack.go170
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/headermap.go78
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/hpack/encode.go251
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/hpack/hpack.go533
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/hpack/huffman.go190
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/hpack/tables.go352
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/http2.go429
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/not_go15.go11
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/not_go16.go13
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/pipe.go147
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/server.go2308
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/transport.go1750
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/write.go263
-rw-r--r--kube2msb/src/vendor/golang.org/x/net/http2/writesched.go283
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/AUTHORS3
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/CONTRIBUTING.md31
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/CONTRIBUTORS3
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/LICENSE27
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/README.md64
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/client_appengine.go25
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/google/appengine.go83
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/google/appengine_hook.go13
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/google/default.go154
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/google/google.go145
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/google/sdk.go168
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/internal/oauth2.go76
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/internal/token.go213
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/internal/transport.go67
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/jws/jws.go160
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/jwt/jwt.go147
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/oauth2.go325
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/token.go143
-rw-r--r--kube2msb/src/vendor/golang.org/x/oauth2/transport.go132
49 files changed, 0 insertions, 11303 deletions
diff --git a/kube2msb/src/vendor/golang.org/x/net/LICENSE b/kube2msb/src/vendor/golang.org/x/net/LICENSE
deleted file mode 100644
index 6a66aea..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2009 The Go 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.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-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
-OWNER 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/kube2msb/src/vendor/golang.org/x/net/PATENTS b/kube2msb/src/vendor/golang.org/x/net/PATENTS
deleted file mode 100644
index 7330990..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/PATENTS
+++ /dev/null
@@ -1,22 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Go project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Go, where such license applies only to those patent
-claims, both currently owned or controlled by Google and acquired in
-the future, licensable by Google that are necessarily infringed by this
-implementation of Go. This grant does not include claims that would be
-infringed only as a consequence of further modification of this
-implementation. If you or your agent or exclusive licensee institute or
-order or agree to the institution of patent litigation against any
-entity (including a cross-claim or counterclaim in a lawsuit) alleging
-that this implementation of Go or any code incorporated within this
-implementation of Go constitutes direct or contributory patent
-infringement, or inducement of patent infringement, then any patent
-rights granted to you under this License for this implementation of Go
-shall terminate as of the date such litigation is filed.
diff --git a/kube2msb/src/vendor/golang.org/x/net/context/context.go b/kube2msb/src/vendor/golang.org/x/net/context/context.go
deleted file mode 100644
index 11bd8d3..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/context/context.go
+++ /dev/null
@@ -1,447 +0,0 @@
-// Copyright 2014 The Go 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 context defines the Context type, which carries deadlines,
-// cancelation signals, and other request-scoped values across API boundaries
-// and between processes.
-//
-// Incoming requests to a server should create a Context, and outgoing calls to
-// servers should accept a Context. The chain of function calls between must
-// propagate the Context, optionally replacing it with a modified copy created
-// using WithDeadline, WithTimeout, WithCancel, or WithValue.
-//
-// Programs that use Contexts should follow these rules to keep interfaces
-// consistent across packages and enable static analysis tools to check context
-// propagation:
-//
-// Do not store Contexts inside a struct type; instead, pass a Context
-// explicitly to each function that needs it. The Context should be the first
-// parameter, typically named ctx:
-//
-// func DoSomething(ctx context.Context, arg Arg) error {
-// // ... use ctx ...
-// }
-//
-// Do not pass a nil Context, even if a function permits it. Pass context.TODO
-// if you are unsure about which Context to use.
-//
-// Use context Values only for request-scoped data that transits processes and
-// APIs, not for passing optional parameters to functions.
-//
-// The same Context may be passed to functions running in different goroutines;
-// Contexts are safe for simultaneous use by multiple goroutines.
-//
-// See http://blog.golang.org/context for example code for a server that uses
-// Contexts.
-package context
-
-import (
- "errors"
- "fmt"
- "sync"
- "time"
-)
-
-// A Context carries a deadline, a cancelation signal, and other values across
-// API boundaries.
-//
-// Context's methods may be called by multiple goroutines simultaneously.
-type Context interface {
- // Deadline returns the time when work done on behalf of this context
- // should be canceled. Deadline returns ok==false when no deadline is
- // set. Successive calls to Deadline return the same results.
- Deadline() (deadline time.Time, ok bool)
-
- // Done returns a channel that's closed when work done on behalf of this
- // context should be canceled. Done may return nil if this context can
- // never be canceled. Successive calls to Done return the same value.
- //
- // WithCancel arranges for Done to be closed when cancel is called;
- // WithDeadline arranges for Done to be closed when the deadline
- // expires; WithTimeout arranges for Done to be closed when the timeout
- // elapses.
- //
- // Done is provided for use in select statements:
- //
- // // Stream generates values with DoSomething and sends them to out
- // // until DoSomething returns an error or ctx.Done is closed.
- // func Stream(ctx context.Context, out <-chan Value) error {
- // for {
- // v, err := DoSomething(ctx)
- // if err != nil {
- // return err
- // }
- // select {
- // case <-ctx.Done():
- // return ctx.Err()
- // case out <- v:
- // }
- // }
- // }
- //
- // See http://blog.golang.org/pipelines for more examples of how to use
- // a Done channel for cancelation.
- Done() <-chan struct{}
-
- // Err returns a non-nil error value after Done is closed. Err returns
- // Canceled if the context was canceled or DeadlineExceeded if the
- // context's deadline passed. No other values for Err are defined.
- // After Done is closed, successive calls to Err return the same value.
- Err() error
-
- // Value returns the value associated with this context for key, or nil
- // if no value is associated with key. Successive calls to Value with
- // the same key returns the same result.
- //
- // Use context values only for request-scoped data that transits
- // processes and API boundaries, not for passing optional parameters to
- // functions.
- //
- // A key identifies a specific value in a Context. Functions that wish
- // to store values in Context typically allocate a key in a global
- // variable then use that key as the argument to context.WithValue and
- // Context.Value. A key can be any type that supports equality;
- // packages should define keys as an unexported type to avoid
- // collisions.
- //
- // Packages that define a Context key should provide type-safe accessors
- // for the values stores using that key:
- //
- // // Package user defines a User type that's stored in Contexts.
- // package user
- //
- // import "golang.org/x/net/context"
- //
- // // User is the type of value stored in the Contexts.
- // type User struct {...}
- //
- // // key is an unexported type for keys defined in this package.
- // // This prevents collisions with keys defined in other packages.
- // type key int
- //
- // // userKey is the key for user.User values in Contexts. It is
- // // unexported; clients use user.NewContext and user.FromContext
- // // instead of using this key directly.
- // var userKey key = 0
- //
- // // NewContext returns a new Context that carries value u.
- // func NewContext(ctx context.Context, u *User) context.Context {
- // return context.WithValue(ctx, userKey, u)
- // }
- //
- // // FromContext returns the User value stored in ctx, if any.
- // func FromContext(ctx context.Context) (*User, bool) {
- // u, ok := ctx.Value(userKey).(*User)
- // return u, ok
- // }
- Value(key interface{}) interface{}
-}
-
-// Canceled is the error returned by Context.Err when the context is canceled.
-var Canceled = errors.New("context canceled")
-
-// DeadlineExceeded is the error returned by Context.Err when the context's
-// deadline passes.
-var DeadlineExceeded = errors.New("context deadline exceeded")
-
-// An emptyCtx is never canceled, has no values, and has no deadline. It is not
-// struct{}, since vars of this type must have distinct addresses.
-type emptyCtx int
-
-func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
- return
-}
-
-func (*emptyCtx) Done() <-chan struct{} {
- return nil
-}
-
-func (*emptyCtx) Err() error {
- return nil
-}
-
-func (*emptyCtx) Value(key interface{}) interface{} {
- return nil
-}
-
-func (e *emptyCtx) String() string {
- switch e {
- case background:
- return "context.Background"
- case todo:
- return "context.TODO"
- }
- return "unknown empty Context"
-}
-
-var (
- background = new(emptyCtx)
- todo = new(emptyCtx)
-)
-
-// Background returns a non-nil, empty Context. It is never canceled, has no
-// values, and has no deadline. It is typically used by the main function,
-// initialization, and tests, and as the top-level Context for incoming
-// requests.
-func Background() Context {
- return background
-}
-
-// TODO returns a non-nil, empty Context. Code should use context.TODO when
-// it's unclear which Context to use or it is not yet available (because the
-// surrounding function has not yet been extended to accept a Context
-// parameter). TODO is recognized by static analysis tools that determine
-// whether Contexts are propagated correctly in a program.
-func TODO() Context {
- return todo
-}
-
-// A CancelFunc tells an operation to abandon its work.
-// A CancelFunc does not wait for the work to stop.
-// After the first call, subsequent calls to a CancelFunc do nothing.
-type CancelFunc func()
-
-// WithCancel returns a copy of parent with a new Done channel. The returned
-// context's Done channel is closed when the returned cancel function is called
-// or when the parent context's Done channel is closed, whichever happens first.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
- c := newCancelCtx(parent)
- propagateCancel(parent, &c)
- return &c, func() { c.cancel(true, Canceled) }
-}
-
-// newCancelCtx returns an initialized cancelCtx.
-func newCancelCtx(parent Context) cancelCtx {
- return cancelCtx{
- Context: parent,
- done: make(chan struct{}),
- }
-}
-
-// propagateCancel arranges for child to be canceled when parent is.
-func propagateCancel(parent Context, child canceler) {
- if parent.Done() == nil {
- return // parent is never canceled
- }
- if p, ok := parentCancelCtx(parent); ok {
- p.mu.Lock()
- if p.err != nil {
- // parent has already been canceled
- child.cancel(false, p.err)
- } else {
- if p.children == nil {
- p.children = make(map[canceler]bool)
- }
- p.children[child] = true
- }
- p.mu.Unlock()
- } else {
- go func() {
- select {
- case <-parent.Done():
- child.cancel(false, parent.Err())
- case <-child.Done():
- }
- }()
- }
-}
-
-// parentCancelCtx follows a chain of parent references until it finds a
-// *cancelCtx. This function understands how each of the concrete types in this
-// package represents its parent.
-func parentCancelCtx(parent Context) (*cancelCtx, bool) {
- for {
- switch c := parent.(type) {
- case *cancelCtx:
- return c, true
- case *timerCtx:
- return &c.cancelCtx, true
- case *valueCtx:
- parent = c.Context
- default:
- return nil, false
- }
- }
-}
-
-// removeChild removes a context from its parent.
-func removeChild(parent Context, child canceler) {
- p, ok := parentCancelCtx(parent)
- if !ok {
- return
- }
- p.mu.Lock()
- if p.children != nil {
- delete(p.children, child)
- }
- p.mu.Unlock()
-}
-
-// A canceler is a context type that can be canceled directly. The
-// implementations are *cancelCtx and *timerCtx.
-type canceler interface {
- cancel(removeFromParent bool, err error)
- Done() <-chan struct{}
-}
-
-// A cancelCtx can be canceled. When canceled, it also cancels any children
-// that implement canceler.
-type cancelCtx struct {
- Context
-
- done chan struct{} // closed by the first cancel call.
-
- mu sync.Mutex
- children map[canceler]bool // set to nil by the first cancel call
- err error // set to non-nil by the first cancel call
-}
-
-func (c *cancelCtx) Done() <-chan struct{} {
- return c.done
-}
-
-func (c *cancelCtx) Err() error {
- c.mu.Lock()
- defer c.mu.Unlock()
- return c.err
-}
-
-func (c *cancelCtx) String() string {
- return fmt.Sprintf("%v.WithCancel", c.Context)
-}
-
-// cancel closes c.done, cancels each of c's children, and, if
-// removeFromParent is true, removes c from its parent's children.
-func (c *cancelCtx) cancel(removeFromParent bool, err error) {
- if err == nil {
- panic("context: internal error: missing cancel error")
- }
- c.mu.Lock()
- if c.err != nil {
- c.mu.Unlock()
- return // already canceled
- }
- c.err = err
- close(c.done)
- for child := range c.children {
- // NOTE: acquiring the child's lock while holding parent's lock.
- child.cancel(false, err)
- }
- c.children = nil
- c.mu.Unlock()
-
- if removeFromParent {
- removeChild(c.Context, c)
- }
-}
-
-// WithDeadline returns a copy of the parent context with the deadline adjusted
-// to be no later than d. If the parent's deadline is already earlier than d,
-// WithDeadline(parent, d) is semantically equivalent to parent. The returned
-// context's Done channel is closed when the deadline expires, when the returned
-// cancel function is called, or when the parent context's Done channel is
-// closed, whichever happens first.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
- if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
- // The current deadline is already sooner than the new one.
- return WithCancel(parent)
- }
- c := &timerCtx{
- cancelCtx: newCancelCtx(parent),
- deadline: deadline,
- }
- propagateCancel(parent, c)
- d := deadline.Sub(time.Now())
- if d <= 0 {
- c.cancel(true, DeadlineExceeded) // deadline has already passed
- return c, func() { c.cancel(true, Canceled) }
- }
- c.mu.Lock()
- defer c.mu.Unlock()
- if c.err == nil {
- c.timer = time.AfterFunc(d, func() {
- c.cancel(true, DeadlineExceeded)
- })
- }
- return c, func() { c.cancel(true, Canceled) }
-}
-
-// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
-// implement Done and Err. It implements cancel by stopping its timer then
-// delegating to cancelCtx.cancel.
-type timerCtx struct {
- cancelCtx
- timer *time.Timer // Under cancelCtx.mu.
-
- deadline time.Time
-}
-
-func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
- return c.deadline, true
-}
-
-func (c *timerCtx) String() string {
- return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
-}
-
-func (c *timerCtx) cancel(removeFromParent bool, err error) {
- c.cancelCtx.cancel(false, err)
- if removeFromParent {
- // Remove this timerCtx from its parent cancelCtx's children.
- removeChild(c.cancelCtx.Context, c)
- }
- c.mu.Lock()
- if c.timer != nil {
- c.timer.Stop()
- c.timer = nil
- }
- c.mu.Unlock()
-}
-
-// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete:
-//
-// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
-// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
-// defer cancel() // releases resources if slowOperation completes before timeout elapses
-// return slowOperation(ctx)
-// }
-func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
- return WithDeadline(parent, time.Now().Add(timeout))
-}
-
-// WithValue returns a copy of parent in which the value associated with key is
-// val.
-//
-// Use context Values only for request-scoped data that transits processes and
-// APIs, not for passing optional parameters to functions.
-func WithValue(parent Context, key interface{}, val interface{}) Context {
- return &valueCtx{parent, key, val}
-}
-
-// A valueCtx carries a key-value pair. It implements Value for that key and
-// delegates all other calls to the embedded Context.
-type valueCtx struct {
- Context
- key, val interface{}
-}
-
-func (c *valueCtx) String() string {
- return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
-}
-
-func (c *valueCtx) Value(key interface{}) interface{} {
- if c.key == key {
- return c.val
- }
- return c.Context.Value(key)
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/cancelreq.go b/kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/cancelreq.go
deleted file mode 100644
index e3170e3..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/cancelreq.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2015 The Go 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.5
-
-package ctxhttp
-
-import "net/http"
-
-func canceler(client *http.Client, req *http.Request) func() {
- // TODO(djd): Respect any existing value of req.Cancel.
- ch := make(chan struct{})
- req.Cancel = ch
-
- return func() {
- close(ch)
- }
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/cancelreq_go14.go b/kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/cancelreq_go14.go
deleted file mode 100644
index 56bcbad..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/cancelreq_go14.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2015 The Go 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.5
-
-package ctxhttp
-
-import "net/http"
-
-type requestCanceler interface {
- CancelRequest(*http.Request)
-}
-
-func canceler(client *http.Client, req *http.Request) func() {
- rc, ok := client.Transport.(requestCanceler)
- if !ok {
- return func() {}
- }
- return func() {
- rc.CancelRequest(req)
- }
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go b/kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
deleted file mode 100644
index 26a5e19..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2015 The Go 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 ctxhttp provides helper functions for performing context-aware HTTP requests.
-package ctxhttp
-
-import (
- "io"
- "net/http"
- "net/url"
- "strings"
-
- "golang.org/x/net/context"
-)
-
-func nop() {}
-
-var (
- testHookContextDoneBeforeHeaders = nop
- testHookDoReturned = nop
- testHookDidBodyClose = nop
-)
-
-// Do sends an HTTP request with the provided http.Client and returns an HTTP response.
-// If the client is nil, http.DefaultClient is used.
-// If the context is canceled or times out, ctx.Err() will be returned.
-func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
- if client == nil {
- client = http.DefaultClient
- }
-
- // Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go.
- cancel := canceler(client, req)
-
- type responseAndError struct {
- resp *http.Response
- err error
- }
- result := make(chan responseAndError, 1)
-
- go func() {
- resp, err := client.Do(req)
- testHookDoReturned()
- result <- responseAndError{resp, err}
- }()
-
- var resp *http.Response
-
- select {
- case <-ctx.Done():
- testHookContextDoneBeforeHeaders()
- cancel()
- // Clean up after the goroutine calling client.Do:
- go func() {
- if r := <-result; r.resp != nil {
- testHookDidBodyClose()
- r.resp.Body.Close()
- }
- }()
- return nil, ctx.Err()
- case r := <-result:
- var err error
- resp, err = r.resp, r.err
- if err != nil {
- return resp, err
- }
- }
-
- c := make(chan struct{})
- go func() {
- select {
- case <-ctx.Done():
- cancel()
- case <-c:
- // The response's Body is closed.
- }
- }()
- resp.Body = &notifyingReader{resp.Body, c}
-
- return resp, nil
-}
-
-// Get issues a GET request via the Do function.
-func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
- req, err := http.NewRequest("GET", url, nil)
- if err != nil {
- return nil, err
- }
- return Do(ctx, client, req)
-}
-
-// Head issues a HEAD request via the Do function.
-func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
- req, err := http.NewRequest("HEAD", url, nil)
- if err != nil {
- return nil, err
- }
- return Do(ctx, client, req)
-}
-
-// Post issues a POST request via the Do function.
-func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
- req, err := http.NewRequest("POST", url, body)
- if err != nil {
- return nil, err
- }
- req.Header.Set("Content-Type", bodyType)
- return Do(ctx, client, req)
-}
-
-// PostForm issues a POST request via the Do function.
-func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
- return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
-}
-
-// notifyingReader is an io.ReadCloser that closes the notify channel after
-// Close is called or a Read fails on the underlying ReadCloser.
-type notifyingReader struct {
- io.ReadCloser
- notify chan<- struct{}
-}
-
-func (r *notifyingReader) Read(p []byte) (int, error) {
- n, err := r.ReadCloser.Read(p)
- if err != nil && r.notify != nil {
- close(r.notify)
- r.notify = nil
- }
- return n, err
-}
-
-func (r *notifyingReader) Close() error {
- err := r.ReadCloser.Close()
- if r.notify != nil {
- close(r.notify)
- r.notify = nil
- }
- return err
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/Dockerfile b/kube2msb/src/vendor/golang.org/x/net/http2/Dockerfile
deleted file mode 100644
index 53fc525..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/Dockerfile
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# This Dockerfile builds a recent curl with HTTP/2 client support, using
-# a recent nghttp2 build.
-#
-# See the Makefile for how to tag it. If Docker and that image is found, the
-# Go tests use this curl binary for integration tests.
-#
-
-FROM ubuntu:trusty
-
-RUN apt-get update && \
- apt-get upgrade -y && \
- apt-get install -y git-core build-essential wget
-
-RUN apt-get install -y --no-install-recommends \
- autotools-dev libtool pkg-config zlib1g-dev \
- libcunit1-dev libssl-dev libxml2-dev libevent-dev \
- automake autoconf
-
-# The list of packages nghttp2 recommends for h2load:
-RUN apt-get install -y --no-install-recommends make binutils \
- autoconf automake autotools-dev \
- libtool pkg-config zlib1g-dev libcunit1-dev libssl-dev libxml2-dev \
- libev-dev libevent-dev libjansson-dev libjemalloc-dev \
- cython python3.4-dev python-setuptools
-
-# Note: setting NGHTTP2_VER before the git clone, so an old git clone isn't cached:
-ENV NGHTTP2_VER 895da9a
-RUN cd /root && git clone https://github.com/tatsuhiro-t/nghttp2.git
-
-WORKDIR /root/nghttp2
-RUN git reset --hard $NGHTTP2_VER
-RUN autoreconf -i
-RUN automake
-RUN autoconf
-RUN ./configure
-RUN make
-RUN make install
-
-WORKDIR /root
-RUN wget http://curl.haxx.se/download/curl-7.45.0.tar.gz
-RUN tar -zxvf curl-7.45.0.tar.gz
-WORKDIR /root/curl-7.45.0
-RUN ./configure --with-ssl --with-nghttp2=/usr/local
-RUN make
-RUN make install
-RUN ldconfig
-
-CMD ["-h"]
-ENTRYPOINT ["/usr/local/bin/curl"]
-
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/Makefile b/kube2msb/src/vendor/golang.org/x/net/http2/Makefile
deleted file mode 100644
index 55fd826..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-curlimage:
- docker build -t gohttp2/curl .
-
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/README b/kube2msb/src/vendor/golang.org/x/net/http2/README
deleted file mode 100644
index 360d5aa..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/README
+++ /dev/null
@@ -1,20 +0,0 @@
-This is a work-in-progress HTTP/2 implementation for Go.
-
-It will eventually live in the Go standard library and won't require
-any changes to your code to use. It will just be automatic.
-
-Status:
-
-* The server support is pretty good. A few things are missing
- but are being worked on.
-* The client work has just started but shares a lot of code
- is coming along much quicker.
-
-Docs are at https://godoc.org/golang.org/x/net/http2
-
-Demo test server at https://http2.golang.org/
-
-Help & bug reports welcome!
-
-Contributing: https://golang.org/doc/contribute.html
-Bugs: https://golang.org/issue/new?title=x/net/http2:+
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/client_conn_pool.go b/kube2msb/src/vendor/golang.org/x/net/http2/client_conn_pool.go
deleted file mode 100644
index 772ea5e..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/client_conn_pool.go
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Transport code's client connection pooling.
-
-package http2
-
-import (
- "crypto/tls"
- "net/http"
- "sync"
-)
-
-// ClientConnPool manages a pool of HTTP/2 client connections.
-type ClientConnPool interface {
- GetClientConn(req *http.Request, addr string) (*ClientConn, error)
- MarkDead(*ClientConn)
-}
-
-// TODO: use singleflight for dialing and addConnCalls?
-type clientConnPool struct {
- t *Transport
-
- mu sync.Mutex // TODO: maybe switch to RWMutex
- // TODO: add support for sharing conns based on cert names
- // (e.g. share conn for googleapis.com and appspot.com)
- conns map[string][]*ClientConn // key is host:port
- dialing map[string]*dialCall // currently in-flight dials
- keys map[*ClientConn][]string
- addConnCalls map[string]*addConnCall // in-flight addConnIfNeede calls
-}
-
-func (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
- return p.getClientConn(req, addr, dialOnMiss)
-}
-
-const (
- dialOnMiss = true
- noDialOnMiss = false
-)
-
-func (p *clientConnPool) getClientConn(_ *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
- p.mu.Lock()
- for _, cc := range p.conns[addr] {
- if cc.CanTakeNewRequest() {
- p.mu.Unlock()
- return cc, nil
- }
- }
- if !dialOnMiss {
- p.mu.Unlock()
- return nil, ErrNoCachedConn
- }
- call := p.getStartDialLocked(addr)
- p.mu.Unlock()
- <-call.done
- return call.res, call.err
-}
-
-// dialCall is an in-flight Transport dial call to a host.
-type dialCall struct {
- p *clientConnPool
- done chan struct{} // closed when done
- res *ClientConn // valid after done is closed
- err error // valid after done is closed
-}
-
-// requires p.mu is held.
-func (p *clientConnPool) getStartDialLocked(addr string) *dialCall {
- if call, ok := p.dialing[addr]; ok {
- // A dial is already in-flight. Don't start another.
- return call
- }
- call := &dialCall{p: p, done: make(chan struct{})}
- if p.dialing == nil {
- p.dialing = make(map[string]*dialCall)
- }
- p.dialing[addr] = call
- go call.dial(addr)
- return call
-}
-
-// run in its own goroutine.
-func (c *dialCall) dial(addr string) {
- c.res, c.err = c.p.t.dialClientConn(addr)
- close(c.done)
-
- c.p.mu.Lock()
- delete(c.p.dialing, addr)
- if c.err == nil {
- c.p.addConnLocked(addr, c.res)
- }
- c.p.mu.Unlock()
-}
-
-// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't
-// already exist. It coalesces concurrent calls with the same key.
-// This is used by the http1 Transport code when it creates a new connection. Because
-// the http1 Transport doesn't de-dup TCP dials to outbound hosts (because it doesn't know
-// the protocol), it can get into a situation where it has multiple TLS connections.
-// This code decides which ones live or die.
-// The return value used is whether c was used.
-// c is never closed.
-func (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c *tls.Conn) (used bool, err error) {
- p.mu.Lock()
- for _, cc := range p.conns[key] {
- if cc.CanTakeNewRequest() {
- p.mu.Unlock()
- return false, nil
- }
- }
- call, dup := p.addConnCalls[key]
- if !dup {
- if p.addConnCalls == nil {
- p.addConnCalls = make(map[string]*addConnCall)
- }
- call = &addConnCall{
- p: p,
- done: make(chan struct{}),
- }
- p.addConnCalls[key] = call
- go call.run(t, key, c)
- }
- p.mu.Unlock()
-
- <-call.done
- if call.err != nil {
- return false, call.err
- }
- return !dup, nil
-}
-
-type addConnCall struct {
- p *clientConnPool
- done chan struct{} // closed when done
- err error
-}
-
-func (c *addConnCall) run(t *Transport, key string, tc *tls.Conn) {
- cc, err := t.NewClientConn(tc)
-
- p := c.p
- p.mu.Lock()
- if err != nil {
- c.err = err
- } else {
- p.addConnLocked(key, cc)
- }
- delete(p.addConnCalls, key)
- p.mu.Unlock()
- close(c.done)
-}
-
-func (p *clientConnPool) addConn(key string, cc *ClientConn) {
- p.mu.Lock()
- p.addConnLocked(key, cc)
- p.mu.Unlock()
-}
-
-// p.mu must be held
-func (p *clientConnPool) addConnLocked(key string, cc *ClientConn) {
- for _, v := range p.conns[key] {
- if v == cc {
- return
- }
- }
- if p.conns == nil {
- p.conns = make(map[string][]*ClientConn)
- }
- if p.keys == nil {
- p.keys = make(map[*ClientConn][]string)
- }
- p.conns[key] = append(p.conns[key], cc)
- p.keys[cc] = append(p.keys[cc], key)
-}
-
-func (p *clientConnPool) MarkDead(cc *ClientConn) {
- p.mu.Lock()
- defer p.mu.Unlock()
- for _, key := range p.keys[cc] {
- vv, ok := p.conns[key]
- if !ok {
- continue
- }
- newList := filterOutClientConn(vv, cc)
- if len(newList) > 0 {
- p.conns[key] = newList
- } else {
- delete(p.conns, key)
- }
- }
- delete(p.keys, cc)
-}
-
-func (p *clientConnPool) closeIdleConnections() {
- p.mu.Lock()
- defer p.mu.Unlock()
- // TODO: don't close a cc if it was just added to the pool
- // milliseconds ago and has never been used. There's currently
- // a small race window with the HTTP/1 Transport's integration
- // where it can add an idle conn just before using it, and
- // somebody else can concurrently call CloseIdleConns and
- // break some caller's RoundTrip.
- for _, vv := range p.conns {
- for _, cc := range vv {
- cc.closeIfIdle()
- }
- }
-}
-
-func filterOutClientConn(in []*ClientConn, exclude *ClientConn) []*ClientConn {
- out := in[:0]
- for _, v := range in {
- if v != exclude {
- out = append(out, v)
- }
- }
- // If we filtered it out, zero out the last item to prevent
- // the GC from seeing it.
- if len(in) != len(out) {
- in[len(in)-1] = nil
- }
- return out
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/configure_transport.go b/kube2msb/src/vendor/golang.org/x/net/http2/configure_transport.go
deleted file mode 100644
index daa17f5..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/configure_transport.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2015 The Go 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.6
-
-package http2
-
-import (
- "crypto/tls"
- "fmt"
- "net/http"
-)
-
-func configureTransport(t1 *http.Transport) (*Transport, error) {
- connPool := new(clientConnPool)
- t2 := &Transport{
- ConnPool: noDialClientConnPool{connPool},
- t1: t1,
- }
- connPool.t = t2
- if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil {
- return nil, err
- }
- if t1.TLSClientConfig == nil {
- t1.TLSClientConfig = new(tls.Config)
- }
- if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") {
- t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...)
- }
- if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") {
- t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
- }
- upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper {
- addr := authorityAddr(authority)
- if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
- go c.Close()
- return erringRoundTripper{err}
- } else if !used {
- // Turns out we don't need this c.
- // For example, two goroutines made requests to the same host
- // at the same time, both kicking off TCP dials. (since protocol
- // was unknown)
- go c.Close()
- }
- return t2
- }
- if m := t1.TLSNextProto; len(m) == 0 {
- t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{
- "h2": upgradeFn,
- }
- } else {
- m["h2"] = upgradeFn
- }
- return t2, nil
-}
-
-// registerHTTPSProtocol calls Transport.RegisterProtocol but
-// convering panics into errors.
-func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error) {
- defer func() {
- if e := recover(); e != nil {
- err = fmt.Errorf("%v", e)
- }
- }()
- t.RegisterProtocol("https", rt)
- return nil
-}
-
-// noDialClientConnPool is an implementation of http2.ClientConnPool
-// which never dials. We let the HTTP/1.1 client dial and use its TLS
-// connection instead.
-type noDialClientConnPool struct{ *clientConnPool }
-
-func (p noDialClientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
- return p.getClientConn(req, addr, noDialOnMiss)
-}
-
-// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
-// if there's already has a cached connection to the host.
-type noDialH2RoundTripper struct{ t *Transport }
-
-func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
- res, err := rt.t.RoundTrip(req)
- if err == ErrNoCachedConn {
- return nil, http.ErrSkipAltProtocol
- }
- return res, err
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/errors.go b/kube2msb/src/vendor/golang.org/x/net/http2/errors.go
deleted file mode 100644
index f320b2c..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/errors.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2014 The Go 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 http2
-
-import "fmt"
-
-// An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.
-type ErrCode uint32
-
-const (
- ErrCodeNo ErrCode = 0x0
- ErrCodeProtocol ErrCode = 0x1
- ErrCodeInternal ErrCode = 0x2
- ErrCodeFlowControl ErrCode = 0x3
- ErrCodeSettingsTimeout ErrCode = 0x4
- ErrCodeStreamClosed ErrCode = 0x5
- ErrCodeFrameSize ErrCode = 0x6
- ErrCodeRefusedStream ErrCode = 0x7
- ErrCodeCancel ErrCode = 0x8
- ErrCodeCompression ErrCode = 0x9
- ErrCodeConnect ErrCode = 0xa
- ErrCodeEnhanceYourCalm ErrCode = 0xb
- ErrCodeInadequateSecurity ErrCode = 0xc
- ErrCodeHTTP11Required ErrCode = 0xd
-)
-
-var errCodeName = map[ErrCode]string{
- ErrCodeNo: "NO_ERROR",
- ErrCodeProtocol: "PROTOCOL_ERROR",
- ErrCodeInternal: "INTERNAL_ERROR",
- ErrCodeFlowControl: "FLOW_CONTROL_ERROR",
- ErrCodeSettingsTimeout: "SETTINGS_TIMEOUT",
- ErrCodeStreamClosed: "STREAM_CLOSED",
- ErrCodeFrameSize: "FRAME_SIZE_ERROR",
- ErrCodeRefusedStream: "REFUSED_STREAM",
- ErrCodeCancel: "CANCEL",
- ErrCodeCompression: "COMPRESSION_ERROR",
- ErrCodeConnect: "CONNECT_ERROR",
- ErrCodeEnhanceYourCalm: "ENHANCE_YOUR_CALM",
- ErrCodeInadequateSecurity: "INADEQUATE_SECURITY",
- ErrCodeHTTP11Required: "HTTP_1_1_REQUIRED",
-}
-
-func (e ErrCode) String() string {
- if s, ok := errCodeName[e]; ok {
- return s
- }
- return fmt.Sprintf("unknown error code 0x%x", uint32(e))
-}
-
-// ConnectionError is an error that results in the termination of the
-// entire connection.
-type ConnectionError ErrCode
-
-func (e ConnectionError) Error() string { return fmt.Sprintf("connection error: %s", ErrCode(e)) }
-
-// StreamError is an error that only affects one stream within an
-// HTTP/2 connection.
-type StreamError struct {
- StreamID uint32
- Code ErrCode
-}
-
-func (e StreamError) Error() string {
- return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code)
-}
-
-// 6.9.1 The Flow Control Window
-// "If a sender receives a WINDOW_UPDATE that causes a flow control
-// window to exceed this maximum it MUST terminate either the stream
-// or the connection, as appropriate. For streams, [...]; for the
-// connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code."
-type goAwayFlowError struct{}
-
-func (goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
-
-// connErrorReason wraps a ConnectionError with an informative error about why it occurs.
-
-// Errors of this type are only returned by the frame parser functions
-// and converted into ConnectionError(ErrCodeProtocol).
-type connError struct {
- Code ErrCode
- Reason string
-}
-
-func (e connError) Error() string {
- return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason)
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/fixed_buffer.go b/kube2msb/src/vendor/golang.org/x/net/http2/fixed_buffer.go
deleted file mode 100644
index 47da0f0..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/fixed_buffer.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2014 The Go 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 http2
-
-import (
- "errors"
-)
-
-// fixedBuffer is an io.ReadWriter backed by a fixed size buffer.
-// It never allocates, but moves old data as new data is written.
-type fixedBuffer struct {
- buf []byte
- r, w int
-}
-
-var (
- errReadEmpty = errors.New("read from empty fixedBuffer")
- errWriteFull = errors.New("write on full fixedBuffer")
-)
-
-// Read copies bytes from the buffer into p.
-// It is an error to read when no data is available.
-func (b *fixedBuffer) Read(p []byte) (n int, err error) {
- if b.r == b.w {
- return 0, errReadEmpty
- }
- n = copy(p, b.buf[b.r:b.w])
- b.r += n
- if b.r == b.w {
- b.r = 0
- b.w = 0
- }
- return n, nil
-}
-
-// Len returns the number of bytes of the unread portion of the buffer.
-func (b *fixedBuffer) Len() int {
- return b.w - b.r
-}
-
-// Write copies bytes from p into the buffer.
-// It is an error to write more data than the buffer can hold.
-func (b *fixedBuffer) Write(p []byte) (n int, err error) {
- // Slide existing data to beginning.
- if b.r > 0 && len(p) > len(b.buf)-b.w {
- copy(b.buf, b.buf[b.r:b.w])
- b.w -= b.r
- b.r = 0
- }
-
- // Write new data.
- n = copy(b.buf[b.w:], p)
- b.w += n
- if n < len(p) {
- err = errWriteFull
- }
- return n, err
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/flow.go b/kube2msb/src/vendor/golang.org/x/net/http2/flow.go
deleted file mode 100644
index 957de25..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/flow.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Flow control
-
-package http2
-
-// flow is the flow control window's size.
-type flow struct {
- // n is the number of DATA bytes we're allowed to send.
- // A flow is kept both on a conn and a per-stream.
- n int32
-
- // conn points to the shared connection-level flow that is
- // shared by all streams on that conn. It is nil for the flow
- // that's on the conn directly.
- conn *flow
-}
-
-func (f *flow) setConnFlow(cf *flow) { f.conn = cf }
-
-func (f *flow) available() int32 {
- n := f.n
- if f.conn != nil && f.conn.n < n {
- n = f.conn.n
- }
- return n
-}
-
-func (f *flow) take(n int32) {
- if n > f.available() {
- panic("internal error: took too much")
- }
- f.n -= n
- if f.conn != nil {
- f.conn.n -= n
- }
-}
-
-// add adds n bytes (positive or negative) to the flow control window.
-// It returns false if the sum would exceed 2^31-1.
-func (f *flow) add(n int32) bool {
- remain := (1<<31 - 1) - f.n
- if n > remain {
- return false
- }
- f.n += n
- return true
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/frame.go b/kube2msb/src/vendor/golang.org/x/net/http2/frame.go
deleted file mode 100644
index e1e837c..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/frame.go
+++ /dev/null
@@ -1,1269 +0,0 @@
-// Copyright 2014 The Go 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 http2
-
-import (
- "bytes"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "log"
- "sync"
-)
-
-const frameHeaderLen = 9
-
-var padZeros = make([]byte, 255) // zeros for padding
-
-// A FrameType is a registered frame type as defined in
-// http://http2.github.io/http2-spec/#rfc.section.11.2
-type FrameType uint8
-
-const (
- FrameData FrameType = 0x0
- FrameHeaders FrameType = 0x1
- FramePriority FrameType = 0x2
- FrameRSTStream FrameType = 0x3
- FrameSettings FrameType = 0x4
- FramePushPromise FrameType = 0x5
- FramePing FrameType = 0x6
- FrameGoAway FrameType = 0x7
- FrameWindowUpdate FrameType = 0x8
- FrameContinuation FrameType = 0x9
-)
-
-var frameName = map[FrameType]string{
- FrameData: "DATA",
- FrameHeaders: "HEADERS",
- FramePriority: "PRIORITY",
- FrameRSTStream: "RST_STREAM",
- FrameSettings: "SETTINGS",
- FramePushPromise: "PUSH_PROMISE",
- FramePing: "PING",
- FrameGoAway: "GOAWAY",
- FrameWindowUpdate: "WINDOW_UPDATE",
- FrameContinuation: "CONTINUATION",
-}
-
-func (t FrameType) String() string {
- if s, ok := frameName[t]; ok {
- return s
- }
- return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t))
-}
-
-// Flags is a bitmask of HTTP/2 flags.
-// The meaning of flags varies depending on the frame type.
-type Flags uint8
-
-// Has reports whether f contains all (0 or more) flags in v.
-func (f Flags) Has(v Flags) bool {
- return (f & v) == v
-}
-
-// Frame-specific FrameHeader flag bits.
-const (
- // Data Frame
- FlagDataEndStream Flags = 0x1
- FlagDataPadded Flags = 0x8
-
- // Headers Frame
- FlagHeadersEndStream Flags = 0x1
- FlagHeadersEndHeaders Flags = 0x4
- FlagHeadersPadded Flags = 0x8
- FlagHeadersPriority Flags = 0x20
-
- // Settings Frame
- FlagSettingsAck Flags = 0x1
-
- // Ping Frame
- FlagPingAck Flags = 0x1
-
- // Continuation Frame
- FlagContinuationEndHeaders Flags = 0x4
-
- FlagPushPromiseEndHeaders Flags = 0x4
- FlagPushPromisePadded Flags = 0x8
-)
-
-var flagName = map[FrameType]map[Flags]string{
- FrameData: {
- FlagDataEndStream: "END_STREAM",
- FlagDataPadded: "PADDED",
- },
- FrameHeaders: {
- FlagHeadersEndStream: "END_STREAM",
- FlagHeadersEndHeaders: "END_HEADERS",
- FlagHeadersPadded: "PADDED",
- FlagHeadersPriority: "PRIORITY",
- },
- FrameSettings: {
- FlagSettingsAck: "ACK",
- },
- FramePing: {
- FlagPingAck: "ACK",
- },
- FrameContinuation: {
- FlagContinuationEndHeaders: "END_HEADERS",
- },
- FramePushPromise: {
- FlagPushPromiseEndHeaders: "END_HEADERS",
- FlagPushPromisePadded: "PADDED",
- },
-}
-
-// a frameParser parses a frame given its FrameHeader and payload
-// bytes. The length of payload will always equal fh.Length (which
-// might be 0).
-type frameParser func(fh FrameHeader, payload []byte) (Frame, error)
-
-var frameParsers = map[FrameType]frameParser{
- FrameData: parseDataFrame,
- FrameHeaders: parseHeadersFrame,
- FramePriority: parsePriorityFrame,
- FrameRSTStream: parseRSTStreamFrame,
- FrameSettings: parseSettingsFrame,
- FramePushPromise: parsePushPromise,
- FramePing: parsePingFrame,
- FrameGoAway: parseGoAwayFrame,
- FrameWindowUpdate: parseWindowUpdateFrame,
- FrameContinuation: parseContinuationFrame,
-}
-
-func typeFrameParser(t FrameType) frameParser {
- if f := frameParsers[t]; f != nil {
- return f
- }
- return parseUnknownFrame
-}
-
-// A FrameHeader is the 9 byte header of all HTTP/2 frames.
-//
-// See http://http2.github.io/http2-spec/#FrameHeader
-type FrameHeader struct {
- valid bool // caller can access []byte fields in the Frame
-
- // Type is the 1 byte frame type. There are ten standard frame
- // types, but extension frame types may be written by WriteRawFrame
- // and will be returned by ReadFrame (as UnknownFrame).
- Type FrameType
-
- // Flags are the 1 byte of 8 potential bit flags per frame.
- // They are specific to the frame type.
- Flags Flags
-
- // Length is the length of the frame, not including the 9 byte header.
- // The maximum size is one byte less than 16MB (uint24), but only
- // frames up to 16KB are allowed without peer agreement.
- Length uint32
-
- // StreamID is which stream this frame is for. Certain frames
- // are not stream-specific, in which case this field is 0.
- StreamID uint32
-}
-
-// Header returns h. It exists so FrameHeaders can be embedded in other
-// specific frame types and implement the Frame interface.
-func (h FrameHeader) Header() FrameHeader { return h }
-
-func (h FrameHeader) String() string {
- var buf bytes.Buffer
- buf.WriteString("[FrameHeader ")
- h.writeDebug(&buf)
- buf.WriteByte(']')
- return buf.String()
-}
-
-func (h FrameHeader) writeDebug(buf *bytes.Buffer) {
- buf.WriteString(h.Type.String())
- if h.Flags != 0 {
- buf.WriteString(" flags=")
- set := 0
- for i := uint8(0); i < 8; i++ {
- if h.Flags&(1<<i) == 0 {
- continue
- }
- set++
- if set > 1 {
- buf.WriteByte('|')
- }
- name := flagName[h.Type][Flags(1<<i)]
- if name != "" {
- buf.WriteString(name)
- } else {
- fmt.Fprintf(buf, "0x%x", 1<<i)
- }
- }
- }
- if h.StreamID != 0 {
- fmt.Fprintf(buf, " stream=%d", h.StreamID)
- }
- fmt.Fprintf(buf, " len=%d", h.Length)
-}
-
-func (h *FrameHeader) checkValid() {
- if !h.valid {
- panic("Frame accessor called on non-owned Frame")
- }
-}
-
-func (h *FrameHeader) invalidate() { h.valid = false }
-
-// frame header bytes.
-// Used only by ReadFrameHeader.
-var fhBytes = sync.Pool{
- New: func() interface{} {
- buf := make([]byte, frameHeaderLen)
- return &buf
- },
-}
-
-// ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.
-// Most users should use Framer.ReadFrame instead.
-func ReadFrameHeader(r io.Reader) (FrameHeader, error) {
- bufp := fhBytes.Get().(*[]byte)
- defer fhBytes.Put(bufp)
- return readFrameHeader(*bufp, r)
-}
-
-func readFrameHeader(buf []byte, r io.Reader) (FrameHeader, error) {
- _, err := io.ReadFull(r, buf[:frameHeaderLen])
- if err != nil {
- return FrameHeader{}, err
- }
- return FrameHeader{
- Length: (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])),
- Type: FrameType(buf[3]),
- Flags: Flags(buf[4]),
- StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1),
- valid: true,
- }, nil
-}
-
-// A Frame is the base interface implemented by all frame types.
-// Callers will generally type-assert the specific frame type:
-// *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc.
-//
-// Frames are only valid until the next call to Framer.ReadFrame.
-type Frame interface {
- Header() FrameHeader
-
- // invalidate is called by Framer.ReadFrame to make this
- // frame's buffers as being invalid, since the subsequent
- // frame will reuse them.
- invalidate()
-}
-
-// A Framer reads and writes Frames.
-type Framer struct {
- r io.Reader
- lastFrame Frame
- errReason string
-
- // lastHeaderStream is non-zero if the last frame was an
- // unfinished HEADERS/CONTINUATION.
- lastHeaderStream uint32
-
- maxReadSize uint32
- headerBuf [frameHeaderLen]byte
-
- // TODO: let getReadBuf be configurable, and use a less memory-pinning
- // allocator in server.go to minimize memory pinned for many idle conns.
- // Will probably also need to make frame invalidation have a hook too.
- getReadBuf func(size uint32) []byte
- readBuf []byte // cache for default getReadBuf
-
- maxWriteSize uint32 // zero means unlimited; TODO: implement
-
- w io.Writer
- wbuf []byte
-
- // AllowIllegalWrites permits the Framer's Write methods to
- // write frames that do not conform to the HTTP/2 spec. This
- // permits using the Framer to test other HTTP/2
- // implementations' conformance to the spec.
- // If false, the Write methods will prefer to return an error
- // rather than comply.
- AllowIllegalWrites bool
-
- // AllowIllegalReads permits the Framer's ReadFrame method
- // to return non-compliant frames or frame orders.
- // This is for testing and permits using the Framer to test
- // other HTTP/2 implementations' conformance to the spec.
- AllowIllegalReads bool
-
- // TODO: track which type of frame & with which flags was sent
- // last. Then return an error (unless AllowIllegalWrites) if
- // we're in the middle of a header block and a
- // non-Continuation or Continuation on a different stream is
- // attempted to be written.
-
- logReads bool
-
- debugFramer *Framer // only use for logging written writes
- debugFramerBuf *bytes.Buffer
-}
-
-func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
- // Write the FrameHeader.
- f.wbuf = append(f.wbuf[:0],
- 0, // 3 bytes of length, filled in in endWrite
- 0,
- 0,
- byte(ftype),
- byte(flags),
- byte(streamID>>24),
- byte(streamID>>16),
- byte(streamID>>8),
- byte(streamID))
-}
-
-func (f *Framer) endWrite() error {
- // Now that we know the final size, fill in the FrameHeader in
- // the space previously reserved for it. Abuse append.
- length := len(f.wbuf) - frameHeaderLen
- if length >= (1 << 24) {
- return ErrFrameTooLarge
- }
- _ = append(f.wbuf[:0],
- byte(length>>16),
- byte(length>>8),
- byte(length))
- if logFrameWrites {
- f.logWrite()
- }
-
- n, err := f.w.Write(f.wbuf)
- if err == nil && n != len(f.wbuf) {
- err = io.ErrShortWrite
- }
- return err
-}
-
-func (f *Framer) logWrite() {
- if f.debugFramer == nil {
- f.debugFramerBuf = new(bytes.Buffer)
- f.debugFramer = NewFramer(nil, f.debugFramerBuf)
- f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below
- // Let us read anything, even if we accidentally wrote it
- // in the wrong order:
- f.debugFramer.AllowIllegalReads = true
- }
- f.debugFramerBuf.Write(f.wbuf)
- fr, err := f.debugFramer.ReadFrame()
- if err != nil {
- log.Printf("http2: Framer %p: failed to decode just-written frame", f)
- return
- }
- log.Printf("http2: Framer %p: wrote %v", f, summarizeFrame(fr))
-}
-
-func (f *Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) }
-func (f *Framer) writeBytes(v []byte) { f.wbuf = append(f.wbuf, v...) }
-func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
-func (f *Framer) writeUint32(v uint32) {
- f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
-}
-
-const (
- minMaxFrameSize = 1 << 14
- maxFrameSize = 1<<24 - 1
-)
-
-// NewFramer returns a Framer that writes frames to w and reads them from r.
-func NewFramer(w io.Writer, r io.Reader) *Framer {
- fr := &Framer{
- w: w,
- r: r,
- logReads: logFrameReads,
- }
- fr.getReadBuf = func(size uint32) []byte {
- if cap(fr.readBuf) >= int(size) {
- return fr.readBuf[:size]
- }
- fr.readBuf = make([]byte, size)
- return fr.readBuf
- }
- fr.SetMaxReadFrameSize(maxFrameSize)
- return fr
-}
-
-// SetMaxReadFrameSize sets the maximum size of a frame
-// that will be read by a subsequent call to ReadFrame.
-// It is the caller's responsibility to advertise this
-// limit with a SETTINGS frame.
-func (fr *Framer) SetMaxReadFrameSize(v uint32) {
- if v > maxFrameSize {
- v = maxFrameSize
- }
- fr.maxReadSize = v
-}
-
-// ErrFrameTooLarge is returned from Framer.ReadFrame when the peer
-// sends a frame that is larger than declared with SetMaxReadFrameSize.
-var ErrFrameTooLarge = errors.New("http2: frame too large")
-
-// terminalReadFrameError reports whether err is an unrecoverable
-// error from ReadFrame and no other frames should be read.
-func terminalReadFrameError(err error) bool {
- if _, ok := err.(StreamError); ok {
- return false
- }
- return err != nil
-}
-
-// ReadFrame reads a single frame. The returned Frame is only valid
-// until the next call to ReadFrame.
-//
-// If the frame is larger than previously set with SetMaxReadFrameSize, the
-// returned error is ErrFrameTooLarge. Other errors may be of type
-// ConnectionError, StreamError, or anything else from from the underlying
-// reader.
-func (fr *Framer) ReadFrame() (Frame, error) {
- if fr.lastFrame != nil {
- fr.lastFrame.invalidate()
- }
- fh, err := readFrameHeader(fr.headerBuf[:], fr.r)
- if err != nil {
- return nil, err
- }
- if fh.Length > fr.maxReadSize {
- return nil, ErrFrameTooLarge
- }
- payload := fr.getReadBuf(fh.Length)
- if _, err := io.ReadFull(fr.r, payload); err != nil {
- return nil, err
- }
- f, err := typeFrameParser(fh.Type)(fh, payload)
- if err != nil {
- if ce, ok := err.(connError); ok {
- return nil, fr.connError(ce.Code, ce.Reason)
- }
- return nil, err
- }
- if err := fr.checkFrameOrder(f); err != nil {
- return nil, err
- }
- if fr.logReads {
- log.Printf("http2: Framer %p: read %v", fr, summarizeFrame(f))
- }
- return f, nil
-}
-
-// connError returns ConnectionError(code) but first
-// stashes away a public reason to the caller can optionally relay it
-// to the peer before hanging up on them. This might help others debug
-// their implementations.
-func (fr *Framer) connError(code ErrCode, reason string) error {
- fr.errReason = reason
- return ConnectionError(code)
-}
-
-// checkFrameOrder reports an error if f is an invalid frame to return
-// next from ReadFrame. Mostly it checks whether HEADERS and
-// CONTINUATION frames are contiguous.
-func (fr *Framer) checkFrameOrder(f Frame) error {
- last := fr.lastFrame
- fr.lastFrame = f
- if fr.AllowIllegalReads {
- return nil
- }
-
- fh := f.Header()
- if fr.lastHeaderStream != 0 {
- if fh.Type != FrameContinuation {
- return fr.connError(ErrCodeProtocol,
- fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d",
- fh.Type, fh.StreamID,
- last.Header().Type, fr.lastHeaderStream))
- }
- if fh.StreamID != fr.lastHeaderStream {
- return fr.connError(ErrCodeProtocol,
- fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d",
- fh.StreamID, fr.lastHeaderStream))
- }
- } else if fh.Type == FrameContinuation {
- return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID))
- }
-
- switch fh.Type {
- case FrameHeaders, FrameContinuation:
- if fh.Flags.Has(FlagHeadersEndHeaders) {
- fr.lastHeaderStream = 0
- } else {
- fr.lastHeaderStream = fh.StreamID
- }
- }
-
- return nil
-}
-
-// A DataFrame conveys arbitrary, variable-length sequences of octets
-// associated with a stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.1
-type DataFrame struct {
- FrameHeader
- data []byte
-}
-
-func (f *DataFrame) StreamEnded() bool {
- return f.FrameHeader.Flags.Has(FlagDataEndStream)
-}
-
-// Data returns the frame's data octets, not including any padding
-// size byte or padding suffix bytes.
-// The caller must not retain the returned memory past the next
-// call to ReadFrame.
-func (f *DataFrame) Data() []byte {
- f.checkValid()
- return f.data
-}
-
-func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) {
- if fh.StreamID == 0 {
- // DATA frames MUST be associated with a stream. If a
- // DATA frame is received whose stream identifier
- // field is 0x0, the recipient MUST respond with a
- // connection error (Section 5.4.1) of type
- // PROTOCOL_ERROR.
- return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"}
- }
- f := &DataFrame{
- FrameHeader: fh,
- }
- var padSize byte
- if fh.Flags.Has(FlagDataPadded) {
- var err error
- payload, padSize, err = readByte(payload)
- if err != nil {
- return nil, err
- }
- }
- if int(padSize) > len(payload) {
- // If the length of the padding is greater than the
- // length of the frame payload, the recipient MUST
- // treat this as a connection error.
- // Filed: https://github.com/http2/http2-spec/issues/610
- return nil, connError{ErrCodeProtocol, "pad size larger than data payload"}
- }
- f.data = payload[:len(payload)-int(padSize)]
- return f, nil
-}
-
-var errStreamID = errors.New("invalid streamid")
-
-func validStreamID(streamID uint32) bool {
- return streamID != 0 && streamID&(1<<31) == 0
-}
-
-// WriteData writes a DATA frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error {
- // TODO: ignoring padding for now. will add when somebody cares.
- if !validStreamID(streamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- var flags Flags
- if endStream {
- flags |= FlagDataEndStream
- }
- f.startWrite(FrameData, flags, streamID)
- f.wbuf = append(f.wbuf, data...)
- return f.endWrite()
-}
-
-// A SettingsFrame conveys configuration parameters that affect how
-// endpoints communicate, such as preferences and constraints on peer
-// behavior.
-//
-// See http://http2.github.io/http2-spec/#SETTINGS
-type SettingsFrame struct {
- FrameHeader
- p []byte
-}
-
-func parseSettingsFrame(fh FrameHeader, p []byte) (Frame, error) {
- if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {
- // When this (ACK 0x1) bit is set, the payload of the
- // SETTINGS frame MUST be empty. Receipt of a
- // SETTINGS frame with the ACK flag set and a length
- // field value other than 0 MUST be treated as a
- // connection error (Section 5.4.1) of type
- // FRAME_SIZE_ERROR.
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- if fh.StreamID != 0 {
- // SETTINGS frames always apply to a connection,
- // never a single stream. The stream identifier for a
- // SETTINGS frame MUST be zero (0x0). If an endpoint
- // receives a SETTINGS frame whose stream identifier
- // field is anything other than 0x0, the endpoint MUST
- // respond with a connection error (Section 5.4.1) of
- // type PROTOCOL_ERROR.
- return nil, ConnectionError(ErrCodeProtocol)
- }
- if len(p)%6 != 0 {
- // Expecting even number of 6 byte settings.
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- f := &SettingsFrame{FrameHeader: fh, p: p}
- if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {
- // Values above the maximum flow control window size of 2^31 - 1 MUST
- // be treated as a connection error (Section 5.4.1) of type
- // FLOW_CONTROL_ERROR.
- return nil, ConnectionError(ErrCodeFlowControl)
- }
- return f, nil
-}
-
-func (f *SettingsFrame) IsAck() bool {
- return f.FrameHeader.Flags.Has(FlagSettingsAck)
-}
-
-func (f *SettingsFrame) Value(s SettingID) (v uint32, ok bool) {
- f.checkValid()
- buf := f.p
- for len(buf) > 0 {
- settingID := SettingID(binary.BigEndian.Uint16(buf[:2]))
- if settingID == s {
- return binary.BigEndian.Uint32(buf[2:6]), true
- }
- buf = buf[6:]
- }
- return 0, false
-}
-
-// ForeachSetting runs fn for each setting.
-// It stops and returns the first error.
-func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
- f.checkValid()
- buf := f.p
- for len(buf) > 0 {
- if err := fn(Setting{
- SettingID(binary.BigEndian.Uint16(buf[:2])),
- binary.BigEndian.Uint32(buf[2:6]),
- }); err != nil {
- return err
- }
- buf = buf[6:]
- }
- return nil
-}
-
-// WriteSettings writes a SETTINGS frame with zero or more settings
-// specified and the ACK bit not set.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WriteSettings(settings ...Setting) error {
- f.startWrite(FrameSettings, 0, 0)
- for _, s := range settings {
- f.writeUint16(uint16(s.ID))
- f.writeUint32(s.Val)
- }
- return f.endWrite()
-}
-
-// WriteSettings writes an empty SETTINGS frame with the ACK bit set.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WriteSettingsAck() error {
- f.startWrite(FrameSettings, FlagSettingsAck, 0)
- return f.endWrite()
-}
-
-// A PingFrame is a mechanism for measuring a minimal round trip time
-// from the sender, as well as determining whether an idle connection
-// is still functional.
-// See http://http2.github.io/http2-spec/#rfc.section.6.7
-type PingFrame struct {
- FrameHeader
- Data [8]byte
-}
-
-func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }
-
-func parsePingFrame(fh FrameHeader, payload []byte) (Frame, error) {
- if len(payload) != 8 {
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- if fh.StreamID != 0 {
- return nil, ConnectionError(ErrCodeProtocol)
- }
- f := &PingFrame{FrameHeader: fh}
- copy(f.Data[:], payload)
- return f, nil
-}
-
-func (f *Framer) WritePing(ack bool, data [8]byte) error {
- var flags Flags
- if ack {
- flags = FlagPingAck
- }
- f.startWrite(FramePing, flags, 0)
- f.writeBytes(data[:])
- return f.endWrite()
-}
-
-// A GoAwayFrame informs the remote peer to stop creating streams on this connection.
-// See http://http2.github.io/http2-spec/#rfc.section.6.8
-type GoAwayFrame struct {
- FrameHeader
- LastStreamID uint32
- ErrCode ErrCode
- debugData []byte
-}
-
-// DebugData returns any debug data in the GOAWAY frame. Its contents
-// are not defined.
-// The caller must not retain the returned memory past the next
-// call to ReadFrame.
-func (f *GoAwayFrame) DebugData() []byte {
- f.checkValid()
- return f.debugData
-}
-
-func parseGoAwayFrame(fh FrameHeader, p []byte) (Frame, error) {
- if fh.StreamID != 0 {
- return nil, ConnectionError(ErrCodeProtocol)
- }
- if len(p) < 8 {
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- return &GoAwayFrame{
- FrameHeader: fh,
- LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1),
- ErrCode: ErrCode(binary.BigEndian.Uint32(p[4:8])),
- debugData: p[8:],
- }, nil
-}
-
-func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error {
- f.startWrite(FrameGoAway, 0, 0)
- f.writeUint32(maxStreamID & (1<<31 - 1))
- f.writeUint32(uint32(code))
- f.writeBytes(debugData)
- return f.endWrite()
-}
-
-// An UnknownFrame is the frame type returned when the frame type is unknown
-// or no specific frame type parser exists.
-type UnknownFrame struct {
- FrameHeader
- p []byte
-}
-
-// Payload returns the frame's payload (after the header). It is not
-// valid to call this method after a subsequent call to
-// Framer.ReadFrame, nor is it valid to retain the returned slice.
-// The memory is owned by the Framer and is invalidated when the next
-// frame is read.
-func (f *UnknownFrame) Payload() []byte {
- f.checkValid()
- return f.p
-}
-
-func parseUnknownFrame(fh FrameHeader, p []byte) (Frame, error) {
- return &UnknownFrame{fh, p}, nil
-}
-
-// A WindowUpdateFrame is used to implement flow control.
-// See http://http2.github.io/http2-spec/#rfc.section.6.9
-type WindowUpdateFrame struct {
- FrameHeader
- Increment uint32 // never read with high bit set
-}
-
-func parseWindowUpdateFrame(fh FrameHeader, p []byte) (Frame, error) {
- if len(p) != 4 {
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
- if inc == 0 {
- // A receiver MUST treat the receipt of a
- // WINDOW_UPDATE frame with an flow control window
- // increment of 0 as a stream error (Section 5.4.2) of
- // type PROTOCOL_ERROR; errors on the connection flow
- // control window MUST be treated as a connection
- // error (Section 5.4.1).
- if fh.StreamID == 0 {
- return nil, ConnectionError(ErrCodeProtocol)
- }
- return nil, StreamError{fh.StreamID, ErrCodeProtocol}
- }
- return &WindowUpdateFrame{
- FrameHeader: fh,
- Increment: inc,
- }, nil
-}
-
-// WriteWindowUpdate writes a WINDOW_UPDATE frame.
-// The increment value must be between 1 and 2,147,483,647, inclusive.
-// If the Stream ID is zero, the window update applies to the
-// connection as a whole.
-func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error {
- // "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets."
- if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites {
- return errors.New("illegal window increment value")
- }
- f.startWrite(FrameWindowUpdate, 0, streamID)
- f.writeUint32(incr)
- return f.endWrite()
-}
-
-// A HeadersFrame is used to open a stream and additionally carries a
-// header block fragment.
-type HeadersFrame struct {
- FrameHeader
-
- // Priority is set if FlagHeadersPriority is set in the FrameHeader.
- Priority PriorityParam
-
- headerFragBuf []byte // not owned
-}
-
-func (f *HeadersFrame) HeaderBlockFragment() []byte {
- f.checkValid()
- return f.headerFragBuf
-}
-
-func (f *HeadersFrame) HeadersEnded() bool {
- return f.FrameHeader.Flags.Has(FlagHeadersEndHeaders)
-}
-
-func (f *HeadersFrame) StreamEnded() bool {
- return f.FrameHeader.Flags.Has(FlagHeadersEndStream)
-}
-
-func (f *HeadersFrame) HasPriority() bool {
- return f.FrameHeader.Flags.Has(FlagHeadersPriority)
-}
-
-func parseHeadersFrame(fh FrameHeader, p []byte) (_ Frame, err error) {
- hf := &HeadersFrame{
- FrameHeader: fh,
- }
- if fh.StreamID == 0 {
- // HEADERS frames MUST be associated with a stream. If a HEADERS frame
- // is received whose stream identifier field is 0x0, the recipient MUST
- // respond with a connection error (Section 5.4.1) of type
- // PROTOCOL_ERROR.
- return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"}
- }
- var padLength uint8
- if fh.Flags.Has(FlagHeadersPadded) {
- if p, padLength, err = readByte(p); err != nil {
- return
- }
- }
- if fh.Flags.Has(FlagHeadersPriority) {
- var v uint32
- p, v, err = readUint32(p)
- if err != nil {
- return nil, err
- }
- hf.Priority.StreamDep = v & 0x7fffffff
- hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
- p, hf.Priority.Weight, err = readByte(p)
- if err != nil {
- return nil, err
- }
- }
- if len(p)-int(padLength) <= 0 {
- return nil, StreamError{fh.StreamID, ErrCodeProtocol}
- }
- hf.headerFragBuf = p[:len(p)-int(padLength)]
- return hf, nil
-}
-
-// HeadersFrameParam are the parameters for writing a HEADERS frame.
-type HeadersFrameParam struct {
- // StreamID is the required Stream ID to initiate.
- StreamID uint32
- // BlockFragment is part (or all) of a Header Block.
- BlockFragment []byte
-
- // EndStream indicates that the header block is the last that
- // the endpoint will send for the identified stream. Setting
- // this flag causes the stream to enter one of "half closed"
- // states.
- EndStream bool
-
- // EndHeaders indicates that this frame contains an entire
- // header block and is not followed by any
- // CONTINUATION frames.
- EndHeaders bool
-
- // PadLength is the optional number of bytes of zeros to add
- // to this frame.
- PadLength uint8
-
- // Priority, if non-zero, includes stream priority information
- // in the HEADER frame.
- Priority PriorityParam
-}
-
-// WriteHeaders writes a single HEADERS frame.
-//
-// This is a low-level header writing method. Encoding headers and
-// splitting them into any necessary CONTINUATION frames is handled
-// elsewhere.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WriteHeaders(p HeadersFrameParam) error {
- if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- var flags Flags
- if p.PadLength != 0 {
- flags |= FlagHeadersPadded
- }
- if p.EndStream {
- flags |= FlagHeadersEndStream
- }
- if p.EndHeaders {
- flags |= FlagHeadersEndHeaders
- }
- if !p.Priority.IsZero() {
- flags |= FlagHeadersPriority
- }
- f.startWrite(FrameHeaders, flags, p.StreamID)
- if p.PadLength != 0 {
- f.writeByte(p.PadLength)
- }
- if !p.Priority.IsZero() {
- v := p.Priority.StreamDep
- if !validStreamID(v) && !f.AllowIllegalWrites {
- return errors.New("invalid dependent stream id")
- }
- if p.Priority.Exclusive {
- v |= 1 << 31
- }
- f.writeUint32(v)
- f.writeByte(p.Priority.Weight)
- }
- f.wbuf = append(f.wbuf, p.BlockFragment...)
- f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
- return f.endWrite()
-}
-
-// A PriorityFrame specifies the sender-advised priority of a stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.3
-type PriorityFrame struct {
- FrameHeader
- PriorityParam
-}
-
-// PriorityParam are the stream prioritzation parameters.
-type PriorityParam struct {
- // StreamDep is a 31-bit stream identifier for the
- // stream that this stream depends on. Zero means no
- // dependency.
- StreamDep uint32
-
- // Exclusive is whether the dependency is exclusive.
- Exclusive bool
-
- // Weight is the stream's zero-indexed weight. It should be
- // set together with StreamDep, or neither should be set. Per
- // the spec, "Add one to the value to obtain a weight between
- // 1 and 256."
- Weight uint8
-}
-
-func (p PriorityParam) IsZero() bool {
- return p == PriorityParam{}
-}
-
-func parsePriorityFrame(fh FrameHeader, payload []byte) (Frame, error) {
- if fh.StreamID == 0 {
- return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
- }
- if len(payload) != 5 {
- return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
- }
- v := binary.BigEndian.Uint32(payload[:4])
- streamID := v & 0x7fffffff // mask off high bit
- return &PriorityFrame{
- FrameHeader: fh,
- PriorityParam: PriorityParam{
- Weight: payload[4],
- StreamDep: streamID,
- Exclusive: streamID != v, // was high bit set?
- },
- }, nil
-}
-
-// WritePriority writes a PRIORITY frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {
- if !validStreamID(streamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- f.startWrite(FramePriority, 0, streamID)
- v := p.StreamDep
- if p.Exclusive {
- v |= 1 << 31
- }
- f.writeUint32(v)
- f.writeByte(p.Weight)
- return f.endWrite()
-}
-
-// A RSTStreamFrame allows for abnormal termination of a stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.4
-type RSTStreamFrame struct {
- FrameHeader
- ErrCode ErrCode
-}
-
-func parseRSTStreamFrame(fh FrameHeader, p []byte) (Frame, error) {
- if len(p) != 4 {
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- if fh.StreamID == 0 {
- return nil, ConnectionError(ErrCodeProtocol)
- }
- return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
-}
-
-// WriteRSTStream writes a RST_STREAM frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error {
- if !validStreamID(streamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- f.startWrite(FrameRSTStream, 0, streamID)
- f.writeUint32(uint32(code))
- return f.endWrite()
-}
-
-// A ContinuationFrame is used to continue a sequence of header block fragments.
-// See http://http2.github.io/http2-spec/#rfc.section.6.10
-type ContinuationFrame struct {
- FrameHeader
- headerFragBuf []byte
-}
-
-func parseContinuationFrame(fh FrameHeader, p []byte) (Frame, error) {
- if fh.StreamID == 0 {
- return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
- }
- return &ContinuationFrame{fh, p}, nil
-}
-
-func (f *ContinuationFrame) HeaderBlockFragment() []byte {
- f.checkValid()
- return f.headerFragBuf
-}
-
-func (f *ContinuationFrame) HeadersEnded() bool {
- return f.FrameHeader.Flags.Has(FlagContinuationEndHeaders)
-}
-
-// WriteContinuation writes a CONTINUATION frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error {
- if !validStreamID(streamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- var flags Flags
- if endHeaders {
- flags |= FlagContinuationEndHeaders
- }
- f.startWrite(FrameContinuation, flags, streamID)
- f.wbuf = append(f.wbuf, headerBlockFragment...)
- return f.endWrite()
-}
-
-// A PushPromiseFrame is used to initiate a server stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.6
-type PushPromiseFrame struct {
- FrameHeader
- PromiseID uint32
- headerFragBuf []byte // not owned
-}
-
-func (f *PushPromiseFrame) HeaderBlockFragment() []byte {
- f.checkValid()
- return f.headerFragBuf
-}
-
-func (f *PushPromiseFrame) HeadersEnded() bool {
- return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)
-}
-
-func parsePushPromise(fh FrameHeader, p []byte) (_ Frame, err error) {
- pp := &PushPromiseFrame{
- FrameHeader: fh,
- }
- if pp.StreamID == 0 {
- // PUSH_PROMISE frames MUST be associated with an existing,
- // peer-initiated stream. The stream identifier of a
- // PUSH_PROMISE frame indicates the stream it is associated
- // with. If the stream identifier field specifies the value
- // 0x0, a recipient MUST respond with a connection error
- // (Section 5.4.1) of type PROTOCOL_ERROR.
- return nil, ConnectionError(ErrCodeProtocol)
- }
- // The PUSH_PROMISE frame includes optional padding.
- // Padding fields and flags are identical to those defined for DATA frames
- var padLength uint8
- if fh.Flags.Has(FlagPushPromisePadded) {
- if p, padLength, err = readByte(p); err != nil {
- return
- }
- }
-
- p, pp.PromiseID, err = readUint32(p)
- if err != nil {
- return
- }
- pp.PromiseID = pp.PromiseID & (1<<31 - 1)
-
- if int(padLength) > len(p) {
- // like the DATA frame, error out if padding is longer than the body.
- return nil, ConnectionError(ErrCodeProtocol)
- }
- pp.headerFragBuf = p[:len(p)-int(padLength)]
- return pp, nil
-}
-
-// PushPromiseParam are the parameters for writing a PUSH_PROMISE frame.
-type PushPromiseParam struct {
- // StreamID is the required Stream ID to initiate.
- StreamID uint32
-
- // PromiseID is the required Stream ID which this
- // Push Promises
- PromiseID uint32
-
- // BlockFragment is part (or all) of a Header Block.
- BlockFragment []byte
-
- // EndHeaders indicates that this frame contains an entire
- // header block and is not followed by any
- // CONTINUATION frames.
- EndHeaders bool
-
- // PadLength is the optional number of bytes of zeros to add
- // to this frame.
- PadLength uint8
-}
-
-// WritePushPromise writes a single PushPromise Frame.
-//
-// As with Header Frames, This is the low level call for writing
-// individual frames. Continuation frames are handled elsewhere.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WritePushPromise(p PushPromiseParam) error {
- if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- var flags Flags
- if p.PadLength != 0 {
- flags |= FlagPushPromisePadded
- }
- if p.EndHeaders {
- flags |= FlagPushPromiseEndHeaders
- }
- f.startWrite(FramePushPromise, flags, p.StreamID)
- if p.PadLength != 0 {
- f.writeByte(p.PadLength)
- }
- if !validStreamID(p.PromiseID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- f.writeUint32(p.PromiseID)
- f.wbuf = append(f.wbuf, p.BlockFragment...)
- f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
- return f.endWrite()
-}
-
-// WriteRawFrame writes a raw frame. This can be used to write
-// extension frames unknown to this package.
-func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error {
- f.startWrite(t, flags, streamID)
- f.writeBytes(payload)
- return f.endWrite()
-}
-
-func readByte(p []byte) (remain []byte, b byte, err error) {
- if len(p) == 0 {
- return nil, 0, io.ErrUnexpectedEOF
- }
- return p[1:], p[0], nil
-}
-
-func readUint32(p []byte) (remain []byte, v uint32, err error) {
- if len(p) < 4 {
- return nil, 0, io.ErrUnexpectedEOF
- }
- return p[4:], binary.BigEndian.Uint32(p[:4]), nil
-}
-
-type streamEnder interface {
- StreamEnded() bool
-}
-
-type headersEnder interface {
- HeadersEnded() bool
-}
-
-func summarizeFrame(f Frame) string {
- var buf bytes.Buffer
- f.Header().writeDebug(&buf)
- switch f := f.(type) {
- case *SettingsFrame:
- n := 0
- f.ForeachSetting(func(s Setting) error {
- n++
- if n == 1 {
- buf.WriteString(", settings:")
- }
- fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val)
- return nil
- })
- if n > 0 {
- buf.Truncate(buf.Len() - 1) // remove trailing comma
- }
- case *DataFrame:
- data := f.Data()
- const max = 256
- if len(data) > max {
- data = data[:max]
- }
- fmt.Fprintf(&buf, " data=%q", data)
- if len(f.Data()) > max {
- fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max)
- }
- case *WindowUpdateFrame:
- if f.StreamID == 0 {
- buf.WriteString(" (conn)")
- }
- fmt.Fprintf(&buf, " incr=%v", f.Increment)
- case *PingFrame:
- fmt.Fprintf(&buf, " ping=%q", f.Data[:])
- case *GoAwayFrame:
- fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q",
- f.LastStreamID, f.ErrCode, f.debugData)
- case *RSTStreamFrame:
- fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode)
- }
- return buf.String()
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/go15.go b/kube2msb/src/vendor/golang.org/x/net/http2/go15.go
deleted file mode 100644
index f0a5624..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/go15.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2015 The Go 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.5
-
-package http2
-
-import "net/http"
-
-func requestCancel(req *http.Request) <-chan struct{} { return req.Cancel }
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/gotrack.go b/kube2msb/src/vendor/golang.org/x/net/http2/gotrack.go
deleted file mode 100644
index 9933c9f..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/gotrack.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Defensive debug-only utility to track that functions run on the
-// goroutine that they're supposed to.
-
-package http2
-
-import (
- "bytes"
- "errors"
- "fmt"
- "os"
- "runtime"
- "strconv"
- "sync"
-)
-
-var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
-
-type goroutineLock uint64
-
-func newGoroutineLock() goroutineLock {
- if !DebugGoroutines {
- return 0
- }
- return goroutineLock(curGoroutineID())
-}
-
-func (g goroutineLock) check() {
- if !DebugGoroutines {
- return
- }
- if curGoroutineID() != uint64(g) {
- panic("running on the wrong goroutine")
- }
-}
-
-func (g goroutineLock) checkNotOn() {
- if !DebugGoroutines {
- return
- }
- if curGoroutineID() == uint64(g) {
- panic("running on the wrong goroutine")
- }
-}
-
-var goroutineSpace = []byte("goroutine ")
-
-func curGoroutineID() uint64 {
- bp := littleBuf.Get().(*[]byte)
- defer littleBuf.Put(bp)
- b := *bp
- b = b[:runtime.Stack(b, false)]
- // Parse the 4707 out of "goroutine 4707 ["
- b = bytes.TrimPrefix(b, goroutineSpace)
- i := bytes.IndexByte(b, ' ')
- if i < 0 {
- panic(fmt.Sprintf("No space found in %q", b))
- }
- b = b[:i]
- n, err := parseUintBytes(b, 10, 64)
- if err != nil {
- panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", b, err))
- }
- return n
-}
-
-var littleBuf = sync.Pool{
- New: func() interface{} {
- buf := make([]byte, 64)
- return &buf
- },
-}
-
-// parseUintBytes is like strconv.ParseUint, but using a []byte.
-func parseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) {
- var cutoff, maxVal uint64
-
- if bitSize == 0 {
- bitSize = int(strconv.IntSize)
- }
-
- s0 := s
- switch {
- case len(s) < 1:
- err = strconv.ErrSyntax
- goto Error
-
- case 2 <= base && base <= 36:
- // valid base; nothing to do
-
- case base == 0:
- // Look for octal, hex prefix.
- switch {
- case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
- base = 16
- s = s[2:]
- if len(s) < 1 {
- err = strconv.ErrSyntax
- goto Error
- }
- case s[0] == '0':
- base = 8
- default:
- base = 10
- }
-
- default:
- err = errors.New("invalid base " + strconv.Itoa(base))
- goto Error
- }
-
- n = 0
- cutoff = cutoff64(base)
- maxVal = 1<<uint(bitSize) - 1
-
- for i := 0; i < len(s); i++ {
- var v byte
- d := s[i]
- switch {
- case '0' <= d && d <= '9':
- v = d - '0'
- case 'a' <= d && d <= 'z':
- v = d - 'a' + 10
- case 'A' <= d && d <= 'Z':
- v = d - 'A' + 10
- default:
- n = 0
- err = strconv.ErrSyntax
- goto Error
- }
- if int(v) >= base {
- n = 0
- err = strconv.ErrSyntax
- goto Error
- }
-
- if n >= cutoff {
- // n*base overflows
- n = 1<<64 - 1
- err = strconv.ErrRange
- goto Error
- }
- n *= uint64(base)
-
- n1 := n + uint64(v)
- if n1 < n || n1 > maxVal {
- // n+v overflows
- n = 1<<64 - 1
- err = strconv.ErrRange
- goto Error
- }
- n = n1
- }
-
- return n, nil
-
-Error:
- return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
-}
-
-// Return the first number n such that n*base >= 1<<64.
-func cutoff64(base int) uint64 {
- if base < 2 {
- return 0
- }
- return (1<<64-1)/uint64(base) + 1
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/headermap.go b/kube2msb/src/vendor/golang.org/x/net/http2/headermap.go
deleted file mode 100644
index c2805f6..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/headermap.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2014 The Go 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 http2
-
-import (
- "net/http"
- "strings"
-)
-
-var (
- commonLowerHeader = map[string]string{} // Go-Canonical-Case -> lower-case
- commonCanonHeader = map[string]string{} // lower-case -> Go-Canonical-Case
-)
-
-func init() {
- for _, v := range []string{
- "accept",
- "accept-charset",
- "accept-encoding",
- "accept-language",
- "accept-ranges",
- "age",
- "access-control-allow-origin",
- "allow",
- "authorization",
- "cache-control",
- "content-disposition",
- "content-encoding",
- "content-language",
- "content-length",
- "content-location",
- "content-range",
- "content-type",
- "cookie",
- "date",
- "etag",
- "expect",
- "expires",
- "from",
- "host",
- "if-match",
- "if-modified-since",
- "if-none-match",
- "if-unmodified-since",
- "last-modified",
- "link",
- "location",
- "max-forwards",
- "proxy-authenticate",
- "proxy-authorization",
- "range",
- "referer",
- "refresh",
- "retry-after",
- "server",
- "set-cookie",
- "strict-transport-security",
- "trailer",
- "transfer-encoding",
- "user-agent",
- "vary",
- "via",
- "www-authenticate",
- } {
- chk := http.CanonicalHeaderKey(v)
- commonLowerHeader[chk] = v
- commonCanonHeader[v] = chk
- }
-}
-
-func lowerHeader(v string) string {
- if s, ok := commonLowerHeader[v]; ok {
- return s
- }
- return strings.ToLower(v)
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/hpack/encode.go b/kube2msb/src/vendor/golang.org/x/net/http2/hpack/encode.go
deleted file mode 100644
index 80d621c..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/hpack/encode.go
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright 2014 The Go 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 hpack
-
-import (
- "io"
-)
-
-const (
- uint32Max = ^uint32(0)
- initialHeaderTableSize = 4096
-)
-
-type Encoder struct {
- dynTab dynamicTable
- // minSize is the minimum table size set by
- // SetMaxDynamicTableSize after the previous Header Table Size
- // Update.
- minSize uint32
- // maxSizeLimit is the maximum table size this encoder
- // supports. This will protect the encoder from too large
- // size.
- maxSizeLimit uint32
- // tableSizeUpdate indicates whether "Header Table Size
- // Update" is required.
- tableSizeUpdate bool
- w io.Writer
- buf []byte
-}
-
-// NewEncoder returns a new Encoder which performs HPACK encoding. An
-// encoded data is written to w.
-func NewEncoder(w io.Writer) *Encoder {
- e := &Encoder{
- minSize: uint32Max,
- maxSizeLimit: initialHeaderTableSize,
- tableSizeUpdate: false,
- w: w,
- }
- e.dynTab.setMaxSize(initialHeaderTableSize)
- return e
-}
-
-// WriteField encodes f into a single Write to e's underlying Writer.
-// This function may also produce bytes for "Header Table Size Update"
-// if necessary. If produced, it is done before encoding f.
-func (e *Encoder) WriteField(f HeaderField) error {
- e.buf = e.buf[:0]
-
- if e.tableSizeUpdate {
- e.tableSizeUpdate = false
- if e.minSize < e.dynTab.maxSize {
- e.buf = appendTableSize(e.buf, e.minSize)
- }
- e.minSize = uint32Max
- e.buf = appendTableSize(e.buf, e.dynTab.maxSize)
- }
-
- idx, nameValueMatch := e.searchTable(f)
- if nameValueMatch {
- e.buf = appendIndexed(e.buf, idx)
- } else {
- indexing := e.shouldIndex(f)
- if indexing {
- e.dynTab.add(f)
- }
-
- if idx == 0 {
- e.buf = appendNewName(e.buf, f, indexing)
- } else {
- e.buf = appendIndexedName(e.buf, f, idx, indexing)
- }
- }
- n, err := e.w.Write(e.buf)
- if err == nil && n != len(e.buf) {
- err = io.ErrShortWrite
- }
- return err
-}
-
-// searchTable searches f in both stable and dynamic header tables.
-// The static header table is searched first. Only when there is no
-// exact match for both name and value, the dynamic header table is
-// then searched. If there is no match, i is 0. If both name and value
-// match, i is the matched index and nameValueMatch becomes true. If
-// only name matches, i points to that index and nameValueMatch
-// becomes false.
-func (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) {
- for idx, hf := range staticTable {
- if !constantTimeStringCompare(hf.Name, f.Name) {
- continue
- }
- if i == 0 {
- i = uint64(idx + 1)
- }
- if f.Sensitive {
- continue
- }
- if !constantTimeStringCompare(hf.Value, f.Value) {
- continue
- }
- i = uint64(idx + 1)
- nameValueMatch = true
- return
- }
-
- j, nameValueMatch := e.dynTab.search(f)
- if nameValueMatch || (i == 0 && j != 0) {
- i = j + uint64(len(staticTable))
- }
- return
-}
-
-// SetMaxDynamicTableSize changes the dynamic header table size to v.
-// The actual size is bounded by the value passed to
-// SetMaxDynamicTableSizeLimit.
-func (e *Encoder) SetMaxDynamicTableSize(v uint32) {
- if v > e.maxSizeLimit {
- v = e.maxSizeLimit
- }
- if v < e.minSize {
- e.minSize = v
- }
- e.tableSizeUpdate = true
- e.dynTab.setMaxSize(v)
-}
-
-// SetMaxDynamicTableSizeLimit changes the maximum value that can be
-// specified in SetMaxDynamicTableSize to v. By default, it is set to
-// 4096, which is the same size of the default dynamic header table
-// size described in HPACK specification. If the current maximum
-// dynamic header table size is strictly greater than v, "Header Table
-// Size Update" will be done in the next WriteField call and the
-// maximum dynamic header table size is truncated to v.
-func (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) {
- e.maxSizeLimit = v
- if e.dynTab.maxSize > v {
- e.tableSizeUpdate = true
- e.dynTab.setMaxSize(v)
- }
-}
-
-// shouldIndex reports whether f should be indexed.
-func (e *Encoder) shouldIndex(f HeaderField) bool {
- return !f.Sensitive && f.size() <= e.dynTab.maxSize
-}
-
-// appendIndexed appends index i, as encoded in "Indexed Header Field"
-// representation, to dst and returns the extended buffer.
-func appendIndexed(dst []byte, i uint64) []byte {
- first := len(dst)
- dst = appendVarInt(dst, 7, i)
- dst[first] |= 0x80
- return dst
-}
-
-// appendNewName appends f, as encoded in one of "Literal Header field
-// - New Name" representation variants, to dst and returns the
-// extended buffer.
-//
-// If f.Sensitive is true, "Never Indexed" representation is used. If
-// f.Sensitive is false and indexing is true, "Inremental Indexing"
-// representation is used.
-func appendNewName(dst []byte, f HeaderField, indexing bool) []byte {
- dst = append(dst, encodeTypeByte(indexing, f.Sensitive))
- dst = appendHpackString(dst, f.Name)
- return appendHpackString(dst, f.Value)
-}
-
-// appendIndexedName appends f and index i referring indexed name
-// entry, as encoded in one of "Literal Header field - Indexed Name"
-// representation variants, to dst and returns the extended buffer.
-//
-// If f.Sensitive is true, "Never Indexed" representation is used. If
-// f.Sensitive is false and indexing is true, "Incremental Indexing"
-// representation is used.
-func appendIndexedName(dst []byte, f HeaderField, i uint64, indexing bool) []byte {
- first := len(dst)
- var n byte
- if indexing {
- n = 6
- } else {
- n = 4
- }
- dst = appendVarInt(dst, n, i)
- dst[first] |= encodeTypeByte(indexing, f.Sensitive)
- return appendHpackString(dst, f.Value)
-}
-
-// appendTableSize appends v, as encoded in "Header Table Size Update"
-// representation, to dst and returns the extended buffer.
-func appendTableSize(dst []byte, v uint32) []byte {
- first := len(dst)
- dst = appendVarInt(dst, 5, uint64(v))
- dst[first] |= 0x20
- return dst
-}
-
-// appendVarInt appends i, as encoded in variable integer form using n
-// bit prefix, to dst and returns the extended buffer.
-//
-// See
-// http://http2.github.io/http2-spec/compression.html#integer.representation
-func appendVarInt(dst []byte, n byte, i uint64) []byte {
- k := uint64((1 << n) - 1)
- if i < k {
- return append(dst, byte(i))
- }
- dst = append(dst, byte(k))
- i -= k
- for ; i >= 128; i >>= 7 {
- dst = append(dst, byte(0x80|(i&0x7f)))
- }
- return append(dst, byte(i))
-}
-
-// appendHpackString appends s, as encoded in "String Literal"
-// representation, to dst and returns the the extended buffer.
-//
-// s will be encoded in Huffman codes only when it produces strictly
-// shorter byte string.
-func appendHpackString(dst []byte, s string) []byte {
- huffmanLength := HuffmanEncodeLength(s)
- if huffmanLength < uint64(len(s)) {
- first := len(dst)
- dst = appendVarInt(dst, 7, huffmanLength)
- dst = AppendHuffmanString(dst, s)
- dst[first] |= 0x80
- } else {
- dst = appendVarInt(dst, 7, uint64(len(s)))
- dst = append(dst, s...)
- }
- return dst
-}
-
-// encodeTypeByte returns type byte. If sensitive is true, type byte
-// for "Never Indexed" representation is returned. If sensitive is
-// false and indexing is true, type byte for "Incremental Indexing"
-// representation is returned. Otherwise, type byte for "Without
-// Indexing" is returned.
-func encodeTypeByte(indexing, sensitive bool) byte {
- if sensitive {
- return 0x10
- }
- if indexing {
- return 0x40
- }
- return 0
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/hpack/hpack.go b/kube2msb/src/vendor/golang.org/x/net/http2/hpack/hpack.go
deleted file mode 100644
index 2ea4949..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/hpack/hpack.go
+++ /dev/null
@@ -1,533 +0,0 @@
-// Copyright 2014 The Go 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 hpack implements HPACK, a compression format for
-// efficiently representing HTTP header fields in the context of HTTP/2.
-//
-// See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09
-package hpack
-
-import (
- "bytes"
- "errors"
- "fmt"
-)
-
-// A DecodingError is something the spec defines as a decoding error.
-type DecodingError struct {
- Err error
-}
-
-func (de DecodingError) Error() string {
- return fmt.Sprintf("decoding error: %v", de.Err)
-}
-
-// An InvalidIndexError is returned when an encoder references a table
-// entry before the static table or after the end of the dynamic table.
-type InvalidIndexError int
-
-func (e InvalidIndexError) Error() string {
- return fmt.Sprintf("invalid indexed representation index %d", int(e))
-}
-
-// A HeaderField is a name-value pair. Both the name and value are
-// treated as opaque sequences of octets.
-type HeaderField struct {
- Name, Value string
-
- // Sensitive means that this header field should never be
- // indexed.
- Sensitive bool
-}
-
-func (hf HeaderField) String() string {
- var suffix string
- if hf.Sensitive {
- suffix = " (sensitive)"
- }
- return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix)
-}
-
-func (hf *HeaderField) size() uint32 {
- // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1
- // "The size of the dynamic table is the sum of the size of
- // its entries. The size of an entry is the sum of its name's
- // length in octets (as defined in Section 5.2), its value's
- // length in octets (see Section 5.2), plus 32. The size of
- // an entry is calculated using the length of the name and
- // value without any Huffman encoding applied."
-
- // This can overflow if somebody makes a large HeaderField
- // Name and/or Value by hand, but we don't care, because that
- // won't happen on the wire because the encoding doesn't allow
- // it.
- return uint32(len(hf.Name) + len(hf.Value) + 32)
-}
-
-// A Decoder is the decoding context for incremental processing of
-// header blocks.
-type Decoder struct {
- dynTab dynamicTable
- emit func(f HeaderField)
-
- emitEnabled bool // whether calls to emit are enabled
- maxStrLen int // 0 means unlimited
-
- // buf is the unparsed buffer. It's only written to
- // saveBuf if it was truncated in the middle of a header
- // block. Because it's usually not owned, we can only
- // process it under Write.
- buf []byte // not owned; only valid during Write
-
- // saveBuf is previous data passed to Write which we weren't able
- // to fully parse before. Unlike buf, we own this data.
- saveBuf bytes.Buffer
-}
-
-// NewDecoder returns a new decoder with the provided maximum dynamic
-// table size. The emitFunc will be called for each valid field
-// parsed, in the same goroutine as calls to Write, before Write returns.
-func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder {
- d := &Decoder{
- emit: emitFunc,
- emitEnabled: true,
- }
- d.dynTab.allowedMaxSize = maxDynamicTableSize
- d.dynTab.setMaxSize(maxDynamicTableSize)
- return d
-}
-
-// ErrStringLength is returned by Decoder.Write when the max string length
-// (as configured by Decoder.SetMaxStringLength) would be violated.
-var ErrStringLength = errors.New("hpack: string too long")
-
-// SetMaxStringLength sets the maximum size of a HeaderField name or
-// value string. If a string exceeds this length (even after any
-// decompression), Write will return ErrStringLength.
-// A value of 0 means unlimited and is the default from NewDecoder.
-func (d *Decoder) SetMaxStringLength(n int) {
- d.maxStrLen = n
-}
-
-// SetEmitFunc changes the callback used when new header fields
-// are decoded.
-// It must be non-nil. It does not affect EmitEnabled.
-func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) {
- d.emit = emitFunc
-}
-
-// SetEmitEnabled controls whether the emitFunc provided to NewDecoder
-// should be called. The default is true.
-//
-// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE
-// while still decoding and keeping in-sync with decoder state, but
-// without doing unnecessary decompression or generating unnecessary
-// garbage for header fields past the limit.
-func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v }
-
-// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder
-// are currently enabled. The default is true.
-func (d *Decoder) EmitEnabled() bool { return d.emitEnabled }
-
-// TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their
-// underlying buffers for garbage reasons.
-
-func (d *Decoder) SetMaxDynamicTableSize(v uint32) {
- d.dynTab.setMaxSize(v)
-}
-
-// SetAllowedMaxDynamicTableSize sets the upper bound that the encoded
-// stream (via dynamic table size updates) may set the maximum size
-// to.
-func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {
- d.dynTab.allowedMaxSize = v
-}
-
-type dynamicTable struct {
- // ents is the FIFO described at
- // http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2
- // The newest (low index) is append at the end, and items are
- // evicted from the front.
- ents []HeaderField
- size uint32
- maxSize uint32 // current maxSize
- allowedMaxSize uint32 // maxSize may go up to this, inclusive
-}
-
-func (dt *dynamicTable) setMaxSize(v uint32) {
- dt.maxSize = v
- dt.evict()
-}
-
-// TODO: change dynamicTable to be a struct with a slice and a size int field,
-// per http://http2.github.io/http2-spec/compression.html#rfc.section.4.1:
-//
-//
-// Then make add increment the size. maybe the max size should move from Decoder to
-// dynamicTable and add should return an ok bool if there was enough space.
-//
-// Later we'll need a remove operation on dynamicTable.
-
-func (dt *dynamicTable) add(f HeaderField) {
- dt.ents = append(dt.ents, f)
- dt.size += f.size()
- dt.evict()
-}
-
-// If we're too big, evict old stuff (front of the slice)
-func (dt *dynamicTable) evict() {
- base := dt.ents // keep base pointer of slice
- for dt.size > dt.maxSize {
- dt.size -= dt.ents[0].size()
- dt.ents = dt.ents[1:]
- }
-
- // Shift slice contents down if we evicted things.
- if len(dt.ents) != len(base) {
- copy(base, dt.ents)
- dt.ents = base[:len(dt.ents)]
- }
-}
-
-// constantTimeStringCompare compares string a and b in a constant
-// time manner.
-func constantTimeStringCompare(a, b string) bool {
- if len(a) != len(b) {
- return false
- }
-
- c := byte(0)
-
- for i := 0; i < len(a); i++ {
- c |= a[i] ^ b[i]
- }
-
- return c == 0
-}
-
-// Search searches f in the table. The return value i is 0 if there is
-// no name match. If there is name match or name/value match, i is the
-// index of that entry (1-based). If both name and value match,
-// nameValueMatch becomes true.
-func (dt *dynamicTable) search(f HeaderField) (i uint64, nameValueMatch bool) {
- l := len(dt.ents)
- for j := l - 1; j >= 0; j-- {
- ent := dt.ents[j]
- if !constantTimeStringCompare(ent.Name, f.Name) {
- continue
- }
- if i == 0 {
- i = uint64(l - j)
- }
- if f.Sensitive {
- continue
- }
- if !constantTimeStringCompare(ent.Value, f.Value) {
- continue
- }
- i = uint64(l - j)
- nameValueMatch = true
- return
- }
- return
-}
-
-func (d *Decoder) maxTableIndex() int {
- return len(d.dynTab.ents) + len(staticTable)
-}
-
-func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) {
- if i < 1 {
- return
- }
- if i > uint64(d.maxTableIndex()) {
- return
- }
- if i <= uint64(len(staticTable)) {
- return staticTable[i-1], true
- }
- dents := d.dynTab.ents
- return dents[len(dents)-(int(i)-len(staticTable))], true
-}
-
-// Decode decodes an entire block.
-//
-// TODO: remove this method and make it incremental later? This is
-// easier for debugging now.
-func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {
- var hf []HeaderField
- saveFunc := d.emit
- defer func() { d.emit = saveFunc }()
- d.emit = func(f HeaderField) { hf = append(hf, f) }
- if _, err := d.Write(p); err != nil {
- return nil, err
- }
- if err := d.Close(); err != nil {
- return nil, err
- }
- return hf, nil
-}
-
-func (d *Decoder) Close() error {
- if d.saveBuf.Len() > 0 {
- d.saveBuf.Reset()
- return DecodingError{errors.New("truncated headers")}
- }
- return nil
-}
-
-func (d *Decoder) Write(p []byte) (n int, err error) {
- if len(p) == 0 {
- // Prevent state machine CPU attacks (making us redo
- // work up to the point of finding out we don't have
- // enough data)
- return
- }
- // Only copy the data if we have to. Optimistically assume
- // that p will contain a complete header block.
- if d.saveBuf.Len() == 0 {
- d.buf = p
- } else {
- d.saveBuf.Write(p)
- d.buf = d.saveBuf.Bytes()
- d.saveBuf.Reset()
- }
-
- for len(d.buf) > 0 {
- err = d.parseHeaderFieldRepr()
- if err == errNeedMore {
- // Extra paranoia, making sure saveBuf won't
- // get too large. All the varint and string
- // reading code earlier should already catch
- // overlong things and return ErrStringLength,
- // but keep this as a last resort.
- const varIntOverhead = 8 // conservative
- if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) {
- return 0, ErrStringLength
- }
- d.saveBuf.Write(d.buf)
- return len(p), nil
- }
- if err != nil {
- break
- }
- }
- return len(p), err
-}
-
-// errNeedMore is an internal sentinel error value that means the
-// buffer is truncated and we need to read more data before we can
-// continue parsing.
-var errNeedMore = errors.New("need more data")
-
-type indexType int
-
-const (
- indexedTrue indexType = iota
- indexedFalse
- indexedNever
-)
-
-func (v indexType) indexed() bool { return v == indexedTrue }
-func (v indexType) sensitive() bool { return v == indexedNever }
-
-// returns errNeedMore if there isn't enough data available.
-// any other error is fatal.
-// consumes d.buf iff it returns nil.
-// precondition: must be called with len(d.buf) > 0
-func (d *Decoder) parseHeaderFieldRepr() error {
- b := d.buf[0]
- switch {
- case b&128 != 0:
- // Indexed representation.
- // High bit set?
- // http://http2.github.io/http2-spec/compression.html#rfc.section.6.1
- return d.parseFieldIndexed()
- case b&192 == 64:
- // 6.2.1 Literal Header Field with Incremental Indexing
- // 0b10xxxxxx: top two bits are 10
- // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1
- return d.parseFieldLiteral(6, indexedTrue)
- case b&240 == 0:
- // 6.2.2 Literal Header Field without Indexing
- // 0b0000xxxx: top four bits are 0000
- // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2
- return d.parseFieldLiteral(4, indexedFalse)
- case b&240 == 16:
- // 6.2.3 Literal Header Field never Indexed
- // 0b0001xxxx: top four bits are 0001
- // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3
- return d.parseFieldLiteral(4, indexedNever)
- case b&224 == 32:
- // 6.3 Dynamic Table Size Update
- // Top three bits are '001'.
- // http://http2.github.io/http2-spec/compression.html#rfc.section.6.3
- return d.parseDynamicTableSizeUpdate()
- }
-
- return DecodingError{errors.New("invalid encoding")}
-}
-
-// (same invariants and behavior as parseHeaderFieldRepr)
-func (d *Decoder) parseFieldIndexed() error {
- buf := d.buf
- idx, buf, err := readVarInt(7, buf)
- if err != nil {
- return err
- }
- hf, ok := d.at(idx)
- if !ok {
- return DecodingError{InvalidIndexError(idx)}
- }
- d.buf = buf
- return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value})
-}
-
-// (same invariants and behavior as parseHeaderFieldRepr)
-func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
- buf := d.buf
- nameIdx, buf, err := readVarInt(n, buf)
- if err != nil {
- return err
- }
-
- var hf HeaderField
- wantStr := d.emitEnabled || it.indexed()
- if nameIdx > 0 {
- ihf, ok := d.at(nameIdx)
- if !ok {
- return DecodingError{InvalidIndexError(nameIdx)}
- }
- hf.Name = ihf.Name
- } else {
- hf.Name, buf, err = d.readString(buf, wantStr)
- if err != nil {
- return err
- }
- }
- hf.Value, buf, err = d.readString(buf, wantStr)
- if err != nil {
- return err
- }
- d.buf = buf
- if it.indexed() {
- d.dynTab.add(hf)
- }
- hf.Sensitive = it.sensitive()
- return d.callEmit(hf)
-}
-
-func (d *Decoder) callEmit(hf HeaderField) error {
- if d.maxStrLen != 0 {
- if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen {
- return ErrStringLength
- }
- }
- if d.emitEnabled {
- d.emit(hf)
- }
- return nil
-}
-
-// (same invariants and behavior as parseHeaderFieldRepr)
-func (d *Decoder) parseDynamicTableSizeUpdate() error {
- buf := d.buf
- size, buf, err := readVarInt(5, buf)
- if err != nil {
- return err
- }
- if size > uint64(d.dynTab.allowedMaxSize) {
- return DecodingError{errors.New("dynamic table size update too large")}
- }
- d.dynTab.setMaxSize(uint32(size))
- d.buf = buf
- return nil
-}
-
-var errVarintOverflow = DecodingError{errors.New("varint integer overflow")}
-
-// readVarInt reads an unsigned variable length integer off the
-// beginning of p. n is the parameter as described in
-// http://http2.github.io/http2-spec/compression.html#rfc.section.5.1.
-//
-// n must always be between 1 and 8.
-//
-// The returned remain buffer is either a smaller suffix of p, or err != nil.
-// The error is errNeedMore if p doesn't contain a complete integer.
-func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {
- if n < 1 || n > 8 {
- panic("bad n")
- }
- if len(p) == 0 {
- return 0, p, errNeedMore
- }
- i = uint64(p[0])
- if n < 8 {
- i &= (1 << uint64(n)) - 1
- }
- if i < (1<<uint64(n))-1 {
- return i, p[1:], nil
- }
-
- origP := p
- p = p[1:]
- var m uint64
- for len(p) > 0 {
- b := p[0]
- p = p[1:]
- i += uint64(b&127) << m
- if b&128 == 0 {
- return i, p, nil
- }
- m += 7
- if m >= 63 { // TODO: proper overflow check. making this up.
- return 0, origP, errVarintOverflow
- }
- }
- return 0, origP, errNeedMore
-}
-
-// readString decodes an hpack string from p.
-//
-// wantStr is whether s will be used. If false, decompression and
-// []byte->string garbage are skipped if s will be ignored
-// anyway. This does mean that huffman decoding errors for non-indexed
-// strings past the MAX_HEADER_LIST_SIZE are ignored, but the server
-// is returning an error anyway, and because they're not indexed, the error
-// won't affect the decoding state.
-func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) {
- if len(p) == 0 {
- return "", p, errNeedMore
- }
- isHuff := p[0]&128 != 0
- strLen, p, err := readVarInt(7, p)
- if err != nil {
- return "", p, err
- }
- if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
- return "", nil, ErrStringLength
- }
- if uint64(len(p)) < strLen {
- return "", p, errNeedMore
- }
- if !isHuff {
- if wantStr {
- s = string(p[:strLen])
- }
- return s, p[strLen:], nil
- }
-
- if wantStr {
- buf := bufPool.Get().(*bytes.Buffer)
- buf.Reset() // don't trust others
- defer bufPool.Put(buf)
- if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil {
- buf.Reset()
- return "", nil, err
- }
- s = buf.String()
- buf.Reset() // be nice to GC
- }
- return s, p[strLen:], nil
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/hpack/huffman.go b/kube2msb/src/vendor/golang.org/x/net/http2/hpack/huffman.go
deleted file mode 100644
index eb4b1f0..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/hpack/huffman.go
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2014 The Go 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 hpack
-
-import (
- "bytes"
- "errors"
- "io"
- "sync"
-)
-
-var bufPool = sync.Pool{
- New: func() interface{} { return new(bytes.Buffer) },
-}
-
-// HuffmanDecode decodes the string in v and writes the expanded
-// result to w, returning the number of bytes written to w and the
-// Write call's return value. At most one Write call is made.
-func HuffmanDecode(w io.Writer, v []byte) (int, error) {
- buf := bufPool.Get().(*bytes.Buffer)
- buf.Reset()
- defer bufPool.Put(buf)
- if err := huffmanDecode(buf, 0, v); err != nil {
- return 0, err
- }
- return w.Write(buf.Bytes())
-}
-
-// HuffmanDecodeToString decodes the string in v.
-func HuffmanDecodeToString(v []byte) (string, error) {
- buf := bufPool.Get().(*bytes.Buffer)
- buf.Reset()
- defer bufPool.Put(buf)
- if err := huffmanDecode(buf, 0, v); err != nil {
- return "", err
- }
- return buf.String(), nil
-}
-
-// ErrInvalidHuffman is returned for errors found decoding
-// Huffman-encoded strings.
-var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data")
-
-// huffmanDecode decodes v to buf.
-// If maxLen is greater than 0, attempts to write more to buf than
-// maxLen bytes will return ErrStringLength.
-func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
- n := rootHuffmanNode
- cur, nbits := uint(0), uint8(0)
- for _, b := range v {
- cur = cur<<8 | uint(b)
- nbits += 8
- for nbits >= 8 {
- idx := byte(cur >> (nbits - 8))
- n = n.children[idx]
- if n == nil {
- return ErrInvalidHuffman
- }
- if n.children == nil {
- if maxLen != 0 && buf.Len() == maxLen {
- return ErrStringLength
- }
- buf.WriteByte(n.sym)
- nbits -= n.codeLen
- n = rootHuffmanNode
- } else {
- nbits -= 8
- }
- }
- }
- for nbits > 0 {
- n = n.children[byte(cur<<(8-nbits))]
- if n.children != nil || n.codeLen > nbits {
- break
- }
- buf.WriteByte(n.sym)
- nbits -= n.codeLen
- n = rootHuffmanNode
- }
- return nil
-}
-
-type node struct {
- // children is non-nil for internal nodes
- children []*node
-
- // The following are only valid if children is nil:
- codeLen uint8 // number of bits that led to the output of sym
- sym byte // output symbol
-}
-
-func newInternalNode() *node {
- return &node{children: make([]*node, 256)}
-}
-
-var rootHuffmanNode = newInternalNode()
-
-func init() {
- if len(huffmanCodes) != 256 {
- panic("unexpected size")
- }
- for i, code := range huffmanCodes {
- addDecoderNode(byte(i), code, huffmanCodeLen[i])
- }
-}
-
-func addDecoderNode(sym byte, code uint32, codeLen uint8) {
- cur := rootHuffmanNode
- for codeLen > 8 {
- codeLen -= 8
- i := uint8(code >> codeLen)
- if cur.children[i] == nil {
- cur.children[i] = newInternalNode()
- }
- cur = cur.children[i]
- }
- shift := 8 - codeLen
- start, end := int(uint8(code<<shift)), int(1<<shift)
- for i := start; i < start+end; i++ {
- cur.children[i] = &node{sym: sym, codeLen: codeLen}
- }
-}
-
-// AppendHuffmanString appends s, as encoded in Huffman codes, to dst
-// and returns the extended buffer.
-func AppendHuffmanString(dst []byte, s string) []byte {
- rembits := uint8(8)
-
- for i := 0; i < len(s); i++ {
- if rembits == 8 {
- dst = append(dst, 0)
- }
- dst, rembits = appendByteToHuffmanCode(dst, rembits, s[i])
- }
-
- if rembits < 8 {
- // special EOS symbol
- code := uint32(0x3fffffff)
- nbits := uint8(30)
-
- t := uint8(code >> (nbits - rembits))
- dst[len(dst)-1] |= t
- }
-
- return dst
-}
-
-// HuffmanEncodeLength returns the number of bytes required to encode
-// s in Huffman codes. The result is round up to byte boundary.
-func HuffmanEncodeLength(s string) uint64 {
- n := uint64(0)
- for i := 0; i < len(s); i++ {
- n += uint64(huffmanCodeLen[s[i]])
- }
- return (n + 7) / 8
-}
-
-// appendByteToHuffmanCode appends Huffman code for c to dst and
-// returns the extended buffer and the remaining bits in the last
-// element. The appending is not byte aligned and the remaining bits
-// in the last element of dst is given in rembits.
-func appendByteToHuffmanCode(dst []byte, rembits uint8, c byte) ([]byte, uint8) {
- code := huffmanCodes[c]
- nbits := huffmanCodeLen[c]
-
- for {
- if rembits > nbits {
- t := uint8(code << (rembits - nbits))
- dst[len(dst)-1] |= t
- rembits -= nbits
- break
- }
-
- t := uint8(code >> (nbits - rembits))
- dst[len(dst)-1] |= t
-
- nbits -= rembits
- rembits = 8
-
- if nbits == 0 {
- break
- }
-
- dst = append(dst, 0)
- }
-
- return dst, rembits
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/hpack/tables.go b/kube2msb/src/vendor/golang.org/x/net/http2/hpack/tables.go
deleted file mode 100644
index b9283a0..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/hpack/tables.go
+++ /dev/null
@@ -1,352 +0,0 @@
-// Copyright 2014 The Go 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 hpack
-
-func pair(name, value string) HeaderField {
- return HeaderField{Name: name, Value: value}
-}
-
-// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B
-var staticTable = [...]HeaderField{
- pair(":authority", ""), // index 1 (1-based)
- pair(":method", "GET"),
- pair(":method", "POST"),
- pair(":path", "/"),
- pair(":path", "/index.html"),
- pair(":scheme", "http"),
- pair(":scheme", "https"),
- pair(":status", "200"),
- pair(":status", "204"),
- pair(":status", "206"),
- pair(":status", "304"),
- pair(":status", "400"),
- pair(":status", "404"),
- pair(":status", "500"),
- pair("accept-charset", ""),
- pair("accept-encoding", "gzip, deflate"),
- pair("accept-language", ""),
- pair("accept-ranges", ""),
- pair("accept", ""),
- pair("access-control-allow-origin", ""),
- pair("age", ""),
- pair("allow", ""),
- pair("authorization", ""),
- pair("cache-control", ""),
- pair("content-disposition", ""),
- pair("content-encoding", ""),
- pair("content-language", ""),
- pair("content-length", ""),
- pair("content-location", ""),
- pair("content-range", ""),
- pair("content-type", ""),
- pair("cookie", ""),
- pair("date", ""),
- pair("etag", ""),
- pair("expect", ""),
- pair("expires", ""),
- pair("from", ""),
- pair("host", ""),
- pair("if-match", ""),
- pair("if-modified-since", ""),
- pair("if-none-match", ""),
- pair("if-range", ""),
- pair("if-unmodified-since", ""),
- pair("last-modified", ""),
- pair("link", ""),
- pair("location", ""),
- pair("max-forwards", ""),
- pair("proxy-authenticate", ""),
- pair("proxy-authorization", ""),
- pair("range", ""),
- pair("referer", ""),
- pair("refresh", ""),
- pair("retry-after", ""),
- pair("server", ""),
- pair("set-cookie", ""),
- pair("strict-transport-security", ""),
- pair("transfer-encoding", ""),
- pair("user-agent", ""),
- pair("vary", ""),
- pair("via", ""),
- pair("www-authenticate", ""),
-}
-
-var huffmanCodes = [256]uint32{
- 0x1ff8,
- 0x7fffd8,
- 0xfffffe2,
- 0xfffffe3,
- 0xfffffe4,
- 0xfffffe5,
- 0xfffffe6,
- 0xfffffe7,
- 0xfffffe8,
- 0xffffea,
- 0x3ffffffc,
- 0xfffffe9,
- 0xfffffea,
- 0x3ffffffd,
- 0xfffffeb,
- 0xfffffec,
- 0xfffffed,
- 0xfffffee,
- 0xfffffef,
- 0xffffff0,
- 0xffffff1,
- 0xffffff2,
- 0x3ffffffe,
- 0xffffff3,
- 0xffffff4,
- 0xffffff5,
- 0xffffff6,
- 0xffffff7,
- 0xffffff8,
- 0xffffff9,
- 0xffffffa,
- 0xffffffb,
- 0x14,
- 0x3f8,
- 0x3f9,
- 0xffa,
- 0x1ff9,
- 0x15,
- 0xf8,
- 0x7fa,
- 0x3fa,
- 0x3fb,
- 0xf9,
- 0x7fb,
- 0xfa,
- 0x16,
- 0x17,
- 0x18,
- 0x0,
- 0x1,
- 0x2,
- 0x19,
- 0x1a,
- 0x1b,
- 0x1c,
- 0x1d,
- 0x1e,
- 0x1f,
- 0x5c,
- 0xfb,
- 0x7ffc,
- 0x20,
- 0xffb,
- 0x3fc,
- 0x1ffa,
- 0x21,
- 0x5d,
- 0x5e,
- 0x5f,
- 0x60,
- 0x61,
- 0x62,
- 0x63,
- 0x64,
- 0x65,
- 0x66,
- 0x67,
- 0x68,
- 0x69,
- 0x6a,
- 0x6b,
- 0x6c,
- 0x6d,
- 0x6e,
- 0x6f,
- 0x70,
- 0x71,
- 0x72,
- 0xfc,
- 0x73,
- 0xfd,
- 0x1ffb,
- 0x7fff0,
- 0x1ffc,
- 0x3ffc,
- 0x22,
- 0x7ffd,
- 0x3,
- 0x23,
- 0x4,
- 0x24,
- 0x5,
- 0x25,
- 0x26,
- 0x27,
- 0x6,
- 0x74,
- 0x75,
- 0x28,
- 0x29,
- 0x2a,
- 0x7,
- 0x2b,
- 0x76,
- 0x2c,
- 0x8,
- 0x9,
- 0x2d,
- 0x77,
- 0x78,
- 0x79,
- 0x7a,
- 0x7b,
- 0x7ffe,
- 0x7fc,
- 0x3ffd,
- 0x1ffd,
- 0xffffffc,
- 0xfffe6,
- 0x3fffd2,
- 0xfffe7,
- 0xfffe8,
- 0x3fffd3,
- 0x3fffd4,
- 0x3fffd5,
- 0x7fffd9,
- 0x3fffd6,
- 0x7fffda,
- 0x7fffdb,
- 0x7fffdc,
- 0x7fffdd,
- 0x7fffde,
- 0xffffeb,
- 0x7fffdf,
- 0xffffec,
- 0xffffed,
- 0x3fffd7,
- 0x7fffe0,
- 0xffffee,
- 0x7fffe1,
- 0x7fffe2,
- 0x7fffe3,
- 0x7fffe4,
- 0x1fffdc,
- 0x3fffd8,
- 0x7fffe5,
- 0x3fffd9,
- 0x7fffe6,
- 0x7fffe7,
- 0xffffef,
- 0x3fffda,
- 0x1fffdd,
- 0xfffe9,
- 0x3fffdb,
- 0x3fffdc,
- 0x7fffe8,
- 0x7fffe9,
- 0x1fffde,
- 0x7fffea,
- 0x3fffdd,
- 0x3fffde,
- 0xfffff0,
- 0x1fffdf,
- 0x3fffdf,
- 0x7fffeb,
- 0x7fffec,
- 0x1fffe0,
- 0x1fffe1,
- 0x3fffe0,
- 0x1fffe2,
- 0x7fffed,
- 0x3fffe1,
- 0x7fffee,
- 0x7fffef,
- 0xfffea,
- 0x3fffe2,
- 0x3fffe3,
- 0x3fffe4,
- 0x7ffff0,
- 0x3fffe5,
- 0x3fffe6,
- 0x7ffff1,
- 0x3ffffe0,
- 0x3ffffe1,
- 0xfffeb,
- 0x7fff1,
- 0x3fffe7,
- 0x7ffff2,
- 0x3fffe8,
- 0x1ffffec,
- 0x3ffffe2,
- 0x3ffffe3,
- 0x3ffffe4,
- 0x7ffffde,
- 0x7ffffdf,
- 0x3ffffe5,
- 0xfffff1,
- 0x1ffffed,
- 0x7fff2,
- 0x1fffe3,
- 0x3ffffe6,
- 0x7ffffe0,
- 0x7ffffe1,
- 0x3ffffe7,
- 0x7ffffe2,
- 0xfffff2,
- 0x1fffe4,
- 0x1fffe5,
- 0x3ffffe8,
- 0x3ffffe9,
- 0xffffffd,
- 0x7ffffe3,
- 0x7ffffe4,
- 0x7ffffe5,
- 0xfffec,
- 0xfffff3,
- 0xfffed,
- 0x1fffe6,
- 0x3fffe9,
- 0x1fffe7,
- 0x1fffe8,
- 0x7ffff3,
- 0x3fffea,
- 0x3fffeb,
- 0x1ffffee,
- 0x1ffffef,
- 0xfffff4,
- 0xfffff5,
- 0x3ffffea,
- 0x7ffff4,
- 0x3ffffeb,
- 0x7ffffe6,
- 0x3ffffec,
- 0x3ffffed,
- 0x7ffffe7,
- 0x7ffffe8,
- 0x7ffffe9,
- 0x7ffffea,
- 0x7ffffeb,
- 0xffffffe,
- 0x7ffffec,
- 0x7ffffed,
- 0x7ffffee,
- 0x7ffffef,
- 0x7fffff0,
- 0x3ffffee,
-}
-
-var huffmanCodeLen = [256]uint8{
- 13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,
- 28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,
- 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6,
- 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10,
- 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6,
- 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5,
- 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28,
- 20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23,
- 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24,
- 22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23,
- 21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23,
- 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25,
- 19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27,
- 20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23,
- 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/http2.go b/kube2msb/src/vendor/golang.org/x/net/http2/http2.go
deleted file mode 100644
index 4c5e11a..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/http2.go
+++ /dev/null
@@ -1,429 +0,0 @@
-// Copyright 2014 The Go 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 http2 implements the HTTP/2 protocol.
-//
-// This package is low-level and intended to be used directly by very
-// few people. Most users will use it indirectly through the automatic
-// use by the net/http package (from Go 1.6 and later).
-// For use in earlier Go versions see ConfigureServer. (Transport support
-// requires Go 1.6 or later)
-//
-// See https://http2.github.io/ for more information on HTTP/2.
-//
-// See https://http2.golang.org/ for a test server running this code.
-package http2
-
-import (
- "bufio"
- "crypto/tls"
- "errors"
- "fmt"
- "io"
- "net/http"
- "os"
- "strconv"
- "strings"
- "sync"
-)
-
-var (
- VerboseLogs bool
- logFrameWrites bool
- logFrameReads bool
-)
-
-func init() {
- e := os.Getenv("GODEBUG")
- if strings.Contains(e, "http2debug=1") {
- VerboseLogs = true
- }
- if strings.Contains(e, "http2debug=2") {
- VerboseLogs = true
- logFrameWrites = true
- logFrameReads = true
- }
-}
-
-const (
- // ClientPreface is the string that must be sent by new
- // connections from clients.
- ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
-
- // SETTINGS_MAX_FRAME_SIZE default
- // http://http2.github.io/http2-spec/#rfc.section.6.5.2
- initialMaxFrameSize = 16384
-
- // NextProtoTLS is the NPN/ALPN protocol negotiated during
- // HTTP/2's TLS setup.
- NextProtoTLS = "h2"
-
- // http://http2.github.io/http2-spec/#SettingValues
- initialHeaderTableSize = 4096
-
- initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size
-
- defaultMaxReadFrameSize = 1 << 20
-)
-
-var (
- clientPreface = []byte(ClientPreface)
-)
-
-type streamState int
-
-const (
- stateIdle streamState = iota
- stateOpen
- stateHalfClosedLocal
- stateHalfClosedRemote
- stateResvLocal
- stateResvRemote
- stateClosed
-)
-
-var stateName = [...]string{
- stateIdle: "Idle",
- stateOpen: "Open",
- stateHalfClosedLocal: "HalfClosedLocal",
- stateHalfClosedRemote: "HalfClosedRemote",
- stateResvLocal: "ResvLocal",
- stateResvRemote: "ResvRemote",
- stateClosed: "Closed",
-}
-
-func (st streamState) String() string {
- return stateName[st]
-}
-
-// Setting is a setting parameter: which setting it is, and its value.
-type Setting struct {
- // ID is which setting is being set.
- // See http://http2.github.io/http2-spec/#SettingValues
- ID SettingID
-
- // Val is the value.
- Val uint32
-}
-
-func (s Setting) String() string {
- return fmt.Sprintf("[%v = %d]", s.ID, s.Val)
-}
-
-// Valid reports whether the setting is valid.
-func (s Setting) Valid() error {
- // Limits and error codes from 6.5.2 Defined SETTINGS Parameters
- switch s.ID {
- case SettingEnablePush:
- if s.Val != 1 && s.Val != 0 {
- return ConnectionError(ErrCodeProtocol)
- }
- case SettingInitialWindowSize:
- if s.Val > 1<<31-1 {
- return ConnectionError(ErrCodeFlowControl)
- }
- case SettingMaxFrameSize:
- if s.Val < 16384 || s.Val > 1<<24-1 {
- return ConnectionError(ErrCodeProtocol)
- }
- }
- return nil
-}
-
-// A SettingID is an HTTP/2 setting as defined in
-// http://http2.github.io/http2-spec/#iana-settings
-type SettingID uint16
-
-const (
- SettingHeaderTableSize SettingID = 0x1
- SettingEnablePush SettingID = 0x2
- SettingMaxConcurrentStreams SettingID = 0x3
- SettingInitialWindowSize SettingID = 0x4
- SettingMaxFrameSize SettingID = 0x5
- SettingMaxHeaderListSize SettingID = 0x6
-)
-
-var settingName = map[SettingID]string{
- SettingHeaderTableSize: "HEADER_TABLE_SIZE",
- SettingEnablePush: "ENABLE_PUSH",
- SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
- SettingInitialWindowSize: "INITIAL_WINDOW_SIZE",
- SettingMaxFrameSize: "MAX_FRAME_SIZE",
- SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
-}
-
-func (s SettingID) String() string {
- if v, ok := settingName[s]; ok {
- return v
- }
- return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s))
-}
-
-var (
- errInvalidHeaderFieldName = errors.New("http2: invalid header field name")
- errInvalidHeaderFieldValue = errors.New("http2: invalid header field value")
-)
-
-// validHeaderFieldName reports whether v is a valid header field name (key).
-// RFC 7230 says:
-// header-field = field-name ":" OWS field-value OWS
-// field-name = token
-// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
-// "^" / "_" / "
-// Further, http2 says:
-// "Just as in HTTP/1.x, header field names are strings of ASCII
-// characters that are compared in a case-insensitive
-// fashion. However, header field names MUST be converted to
-// lowercase prior to their encoding in HTTP/2. "
-func validHeaderFieldName(v string) bool {
- if len(v) == 0 {
- return false
- }
- for _, r := range v {
- if int(r) >= len(isTokenTable) || ('A' <= r && r <= 'Z') {
- return false
- }
- if !isTokenTable[byte(r)] {
- return false
- }
- }
- return true
-}
-
-// validHeaderFieldValue reports whether v is a valid header field value.
-//
-// RFC 7230 says:
-// field-value = *( field-content / obs-fold )
-// obj-fold = N/A to http2, and deprecated
-// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
-// field-vchar = VCHAR / obs-text
-// obs-text = %x80-FF
-// VCHAR = "any visible [USASCII] character"
-//
-// http2 further says: "Similarly, HTTP/2 allows header field values
-// that are not valid. While most of the values that can be encoded
-// will not alter header field parsing, carriage return (CR, ASCII
-// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII
-// 0x0) might be exploited by an attacker if they are translated
-// verbatim. Any request or response that contains a character not
-// permitted in a header field value MUST be treated as malformed
-// (Section 8.1.2.6). Valid characters are defined by the
-// field-content ABNF rule in Section 3.2 of [RFC7230]."
-//
-// This function does not (yet?) properly handle the rejection of
-// strings that begin or end with SP or HTAB.
-func validHeaderFieldValue(v string) bool {
- for i := 0; i < len(v); i++ {
- if b := v[i]; b < ' ' && b != '\t' || b == 0x7f {
- return false
- }
- }
- return true
-}
-
-var httpCodeStringCommon = map[int]string{} // n -> strconv.Itoa(n)
-
-func init() {
- for i := 100; i <= 999; i++ {
- if v := http.StatusText(i); v != "" {
- httpCodeStringCommon[i] = strconv.Itoa(i)
- }
- }
-}
-
-func httpCodeString(code int) string {
- if s, ok := httpCodeStringCommon[code]; ok {
- return s
- }
- return strconv.Itoa(code)
-}
-
-// from pkg io
-type stringWriter interface {
- WriteString(s string) (n int, err error)
-}
-
-// A gate lets two goroutines coordinate their activities.
-type gate chan struct{}
-
-func (g gate) Done() { g <- struct{}{} }
-func (g gate) Wait() { <-g }
-
-// A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).
-type closeWaiter chan struct{}
-
-// Init makes a closeWaiter usable.
-// It exists because so a closeWaiter value can be placed inside a
-// larger struct and have the Mutex and Cond's memory in the same
-// allocation.
-func (cw *closeWaiter) Init() {
- *cw = make(chan struct{})
-}
-
-// Close marks the closeWaiter as closed and unblocks any waiters.
-func (cw closeWaiter) Close() {
- close(cw)
-}
-
-// Wait waits for the closeWaiter to become closed.
-func (cw closeWaiter) Wait() {
- <-cw
-}
-
-// bufferedWriter is a buffered writer that writes to w.
-// Its buffered writer is lazily allocated as needed, to minimize
-// idle memory usage with many connections.
-type bufferedWriter struct {
- w io.Writer // immutable
- bw *bufio.Writer // non-nil when data is buffered
-}
-
-func newBufferedWriter(w io.Writer) *bufferedWriter {
- return &bufferedWriter{w: w}
-}
-
-var bufWriterPool = sync.Pool{
- New: func() interface{} {
- // TODO: pick something better? this is a bit under
- // (3 x typical 1500 byte MTU) at least.
- return bufio.NewWriterSize(nil, 4<<10)
- },
-}
-
-func (w *bufferedWriter) Write(p []byte) (n int, err error) {
- if w.bw == nil {
- bw := bufWriterPool.Get().(*bufio.Writer)
- bw.Reset(w.w)
- w.bw = bw
- }
- return w.bw.Write(p)
-}
-
-func (w *bufferedWriter) Flush() error {
- bw := w.bw
- if bw == nil {
- return nil
- }
- err := bw.Flush()
- bw.Reset(nil)
- bufWriterPool.Put(bw)
- w.bw = nil
- return err
-}
-
-func mustUint31(v int32) uint32 {
- if v < 0 || v > 2147483647 {
- panic("out of range")
- }
- return uint32(v)
-}
-
-// bodyAllowedForStatus reports whether a given response status code
-// permits a body. See RFC2616, section 4.4.
-func bodyAllowedForStatus(status int) bool {
- switch {
- case status >= 100 && status <= 199:
- return false
- case status == 204:
- return false
- case status == 304:
- return false
- }
- return true
-}
-
-type httpError struct {
- msg string
- timeout bool
-}
-
-func (e *httpError) Error() string { return e.msg }
-func (e *httpError) Timeout() bool { return e.timeout }
-func (e *httpError) Temporary() bool { return true }
-
-var errTimeout error = &httpError{msg: "http2: timeout awaiting response headers", timeout: true}
-
-var isTokenTable = [127]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,
-}
-
-type connectionStater interface {
- ConnectionState() tls.ConnectionState
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/not_go15.go b/kube2msb/src/vendor/golang.org/x/net/http2/not_go15.go
deleted file mode 100644
index d0fa5c8..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/not_go15.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2015 The Go 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.5
-
-package http2
-
-import "net/http"
-
-func requestCancel(req *http.Request) <-chan struct{} { return nil }
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/not_go16.go b/kube2msb/src/vendor/golang.org/x/net/http2/not_go16.go
deleted file mode 100644
index db53c5b..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/not_go16.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2015 The Go 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.6
-
-package http2
-
-import "net/http"
-
-func configureTransport(t1 *http.Transport) (*Transport, error) {
- return nil, errTransportVersion
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/pipe.go b/kube2msb/src/vendor/golang.org/x/net/http2/pipe.go
deleted file mode 100644
index 69446e7..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/pipe.go
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2014 The Go 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 http2
-
-import (
- "errors"
- "io"
- "sync"
-)
-
-// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like
-// io.Pipe except there are no PipeReader/PipeWriter halves, and the
-// underlying buffer is an interface. (io.Pipe is always unbuffered)
-type pipe struct {
- mu sync.Mutex
- c sync.Cond // c.L lazily initialized to &p.mu
- b pipeBuffer
- err error // read error once empty. non-nil means closed.
- breakErr error // immediate read error (caller doesn't see rest of b)
- donec chan struct{} // closed on error
- readFn func() // optional code to run in Read before error
-}
-
-type pipeBuffer interface {
- Len() int
- io.Writer
- io.Reader
-}
-
-// Read waits until data is available and copies bytes
-// from the buffer into p.
-func (p *pipe) Read(d []byte) (n int, err error) {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.c.L == nil {
- p.c.L = &p.mu
- }
- for {
- if p.breakErr != nil {
- return 0, p.breakErr
- }
- if p.b.Len() > 0 {
- return p.b.Read(d)
- }
- if p.err != nil {
- if p.readFn != nil {
- p.readFn() // e.g. copy trailers
- p.readFn = nil // not sticky like p.err
- }
- return 0, p.err
- }
- p.c.Wait()
- }
-}
-
-var errClosedPipeWrite = errors.New("write on closed buffer")
-
-// Write copies bytes from p into the buffer and wakes a reader.
-// It is an error to write more data than the buffer can hold.
-func (p *pipe) Write(d []byte) (n int, err error) {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.c.L == nil {
- p.c.L = &p.mu
- }
- defer p.c.Signal()
- if p.err != nil {
- return 0, errClosedPipeWrite
- }
- return p.b.Write(d)
-}
-
-// CloseWithError causes the next Read (waking up a current blocked
-// Read if needed) to return the provided err after all data has been
-// read.
-//
-// The error must be non-nil.
-func (p *pipe) CloseWithError(err error) { p.closeWithError(&p.err, err, nil) }
-
-// BreakWithError causes the next Read (waking up a current blocked
-// Read if needed) to return the provided err immediately, without
-// waiting for unread data.
-func (p *pipe) BreakWithError(err error) { p.closeWithError(&p.breakErr, err, nil) }
-
-// closeWithErrorAndCode is like CloseWithError but also sets some code to run
-// in the caller's goroutine before returning the error.
-func (p *pipe) closeWithErrorAndCode(err error, fn func()) { p.closeWithError(&p.err, err, fn) }
-
-func (p *pipe) closeWithError(dst *error, err error, fn func()) {
- if err == nil {
- panic("err must be non-nil")
- }
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.c.L == nil {
- p.c.L = &p.mu
- }
- defer p.c.Signal()
- if *dst != nil {
- // Already been done.
- return
- }
- p.readFn = fn
- *dst = err
- p.closeDoneLocked()
-}
-
-// requires p.mu be held.
-func (p *pipe) closeDoneLocked() {
- if p.donec == nil {
- return
- }
- // Close if unclosed. This isn't racy since we always
- // hold p.mu while closing.
- select {
- case <-p.donec:
- default:
- close(p.donec)
- }
-}
-
-// Err returns the error (if any) first set by BreakWithError or CloseWithError.
-func (p *pipe) Err() error {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.breakErr != nil {
- return p.breakErr
- }
- return p.err
-}
-
-// Done returns a channel which is closed if and when this pipe is closed
-// with CloseWithError.
-func (p *pipe) Done() <-chan struct{} {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.donec == nil {
- p.donec = make(chan struct{})
- if p.err != nil || p.breakErr != nil {
- // Already hit an error.
- p.closeDoneLocked()
- }
- }
- return p.donec
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/server.go b/kube2msb/src/vendor/golang.org/x/net/http2/server.go
deleted file mode 100644
index 6f4c2bb..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/server.go
+++ /dev/null
@@ -1,2308 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO: replace all <-sc.doneServing with reads from the stream's cw
-// instead, and make sure that on close we close all open
-// streams. then remove doneServing?
-
-// TODO: re-audit GOAWAY support. Consider each incoming frame type and
-// whether it should be ignored during graceful shutdown.
-
-// TODO: disconnect idle clients. GFE seems to do 4 minutes. make
-// configurable? or maximum number of idle clients and remove the
-// oldest?
-
-// TODO: turn off the serve goroutine when idle, so
-// an idle conn only has the readFrames goroutine active. (which could
-// also be optimized probably to pin less memory in crypto/tls). This
-// would involve tracking when the serve goroutine is active (atomic
-// int32 read/CAS probably?) and starting it up when frames arrive,
-// and shutting it down when all handlers exit. the occasional PING
-// packets could use time.AfterFunc to call sc.wakeStartServeLoop()
-// (which is a no-op if already running) and then queue the PING write
-// as normal. The serve loop would then exit in most cases (if no
-// Handlers running) and not be woken up again until the PING packet
-// returns.
-
-// TODO (maybe): add a mechanism for Handlers to going into
-// half-closed-local mode (rw.(io.Closer) test?) but not exit their
-// handler, and continue to be able to read from the
-// Request.Body. This would be a somewhat semantic change from HTTP/1
-// (or at least what we expose in net/http), so I'd probably want to
-// add it there too. For now, this package says that returning from
-// the Handler ServeHTTP function means you're both done reading and
-// done writing, without a way to stop just one or the other.
-
-package http2
-
-import (
- "bufio"
- "bytes"
- "crypto/tls"
- "errors"
- "fmt"
- "io"
- "log"
- "net"
- "net/http"
- "net/textproto"
- "net/url"
- "os"
- "reflect"
- "runtime"
- "sort"
- "strconv"
- "strings"
- "sync"
- "time"
-
- "golang.org/x/net/http2/hpack"
-)
-
-const (
- prefaceTimeout = 10 * time.Second
- firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway
- handlerChunkWriteSize = 4 << 10
- defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to?
-)
-
-var (
- errClientDisconnected = errors.New("client disconnected")
- errClosedBody = errors.New("body closed by handler")
- errHandlerComplete = errors.New("http2: request body closed due to handler exiting")
- errStreamClosed = errors.New("http2: stream closed")
-)
-
-var responseWriterStatePool = sync.Pool{
- New: func() interface{} {
- rws := &responseWriterState{}
- rws.bw = bufio.NewWriterSize(chunkWriter{rws}, handlerChunkWriteSize)
- return rws
- },
-}
-
-// Test hooks.
-var (
- testHookOnConn func()
- testHookGetServerConn func(*serverConn)
- testHookOnPanicMu *sync.Mutex // nil except in tests
- testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool)
-)
-
-// Server is an HTTP/2 server.
-type Server struct {
- // MaxHandlers limits the number of http.Handler ServeHTTP goroutines
- // which may run at a time over all connections.
- // Negative or zero no limit.
- // TODO: implement
- MaxHandlers int
-
- // MaxConcurrentStreams optionally specifies the number of
- // concurrent streams that each client may have open at a
- // time. This is unrelated to the number of http.Handler goroutines
- // which may be active globally, which is MaxHandlers.
- // If zero, MaxConcurrentStreams defaults to at least 100, per
- // the HTTP/2 spec's recommendations.
- MaxConcurrentStreams uint32
-
- // MaxReadFrameSize optionally specifies the largest frame
- // this server is willing to read. A valid value is between
- // 16k and 16M, inclusive. If zero or otherwise invalid, a
- // default value is used.
- MaxReadFrameSize uint32
-
- // PermitProhibitedCipherSuites, if true, permits the use of
- // cipher suites prohibited by the HTTP/2 spec.
- PermitProhibitedCipherSuites bool
-}
-
-func (s *Server) maxReadFrameSize() uint32 {
- if v := s.MaxReadFrameSize; v >= minMaxFrameSize && v <= maxFrameSize {
- return v
- }
- return defaultMaxReadFrameSize
-}
-
-func (s *Server) maxConcurrentStreams() uint32 {
- if v := s.MaxConcurrentStreams; v > 0 {
- return v
- }
- return defaultMaxStreams
-}
-
-// ConfigureServer adds HTTP/2 support to a net/http Server.
-//
-// The configuration conf may be nil.
-//
-// ConfigureServer must be called before s begins serving.
-func ConfigureServer(s *http.Server, conf *Server) error {
- if conf == nil {
- conf = new(Server)
- }
-
- if s.TLSConfig == nil {
- s.TLSConfig = new(tls.Config)
- } else if s.TLSConfig.CipherSuites != nil {
- // If they already provided a CipherSuite list, return
- // an error if it has a bad order or is missing
- // ECDHE_RSA_WITH_AES_128_GCM_SHA256.
- const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- haveRequired := false
- sawBad := false
- for i, cs := range s.TLSConfig.CipherSuites {
- if cs == requiredCipher {
- haveRequired = true
- }
- if isBadCipher(cs) {
- sawBad = true
- } else if sawBad {
- return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", i, cs)
- }
- }
- if !haveRequired {
- return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
- }
- }
-
- // Note: not setting MinVersion to tls.VersionTLS12,
- // as we don't want to interfere with HTTP/1.1 traffic
- // on the user's server. We enforce TLS 1.2 later once
- // we accept a connection. Ideally this should be done
- // during next-proto selection, but using TLS <1.2 with
- // HTTP/2 is still the client's bug.
-
- s.TLSConfig.PreferServerCipherSuites = true
-
- haveNPN := false
- for _, p := range s.TLSConfig.NextProtos {
- if p == NextProtoTLS {
- haveNPN = true
- break
- }
- }
- if !haveNPN {
- s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)
- }
- // h2-14 is temporary (as of 2015-03-05) while we wait for all browsers
- // to switch to "h2".
- s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "h2-14")
-
- if s.TLSNextProto == nil {
- s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
- }
- protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) {
- if testHookOnConn != nil {
- testHookOnConn()
- }
- conf.ServeConn(c, &ServeConnOpts{
- Handler: h,
- BaseConfig: hs,
- })
- }
- s.TLSNextProto[NextProtoTLS] = protoHandler
- s.TLSNextProto["h2-14"] = protoHandler // temporary; see above.
- return nil
-}
-
-// ServeConnOpts are options for the Server.ServeConn method.
-type ServeConnOpts struct {
- // BaseConfig optionally sets the base configuration
- // for values. If nil, defaults are used.
- BaseConfig *http.Server
-
- // Handler specifies which handler to use for processing
- // requests. If nil, BaseConfig.Handler is used. If BaseConfig
- // or BaseConfig.Handler is nil, http.DefaultServeMux is used.
- Handler http.Handler
-}
-
-func (o *ServeConnOpts) baseConfig() *http.Server {
- if o != nil && o.BaseConfig != nil {
- return o.BaseConfig
- }
- return new(http.Server)
-}
-
-func (o *ServeConnOpts) handler() http.Handler {
- if o != nil {
- if o.Handler != nil {
- return o.Handler
- }
- if o.BaseConfig != nil && o.BaseConfig.Handler != nil {
- return o.BaseConfig.Handler
- }
- }
- return http.DefaultServeMux
-}
-
-// ServeConn serves HTTP/2 requests on the provided connection and
-// blocks until the connection is no longer readable.
-//
-// ServeConn starts speaking HTTP/2 assuming that c has not had any
-// reads or writes. It writes its initial settings frame and expects
-// to be able to read the preface and settings frame from the
-// client. If c has a ConnectionState method like a *tls.Conn, the
-// ConnectionState is used to verify the TLS ciphersuite and to set
-// the Request.TLS field in Handlers.
-//
-// ServeConn does not support h2c by itself. Any h2c support must be
-// implemented in terms of providing a suitably-behaving net.Conn.
-//
-// The opts parameter is optional. If nil, default values are used.
-func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
- sc := &serverConn{
- srv: s,
- hs: opts.baseConfig(),
- conn: c,
- remoteAddrStr: c.RemoteAddr().String(),
- bw: newBufferedWriter(c),
- handler: opts.handler(),
- streams: make(map[uint32]*stream),
- readFrameCh: make(chan readFrameResult),
- wantWriteFrameCh: make(chan frameWriteMsg, 8),
- wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
- bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way
- doneServing: make(chan struct{}),
- advMaxStreams: s.maxConcurrentStreams(),
- writeSched: writeScheduler{
- maxFrameSize: initialMaxFrameSize,
- },
- initialWindowSize: initialWindowSize,
- headerTableSize: initialHeaderTableSize,
- serveG: newGoroutineLock(),
- pushEnabled: true,
- }
- sc.flow.add(initialWindowSize)
- sc.inflow.add(initialWindowSize)
- sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
- sc.hpackDecoder = hpack.NewDecoder(initialHeaderTableSize, nil)
- sc.hpackDecoder.SetMaxStringLength(sc.maxHeaderStringLen())
-
- fr := NewFramer(sc.bw, c)
- fr.SetMaxReadFrameSize(s.maxReadFrameSize())
- sc.framer = fr
-
- if tc, ok := c.(connectionStater); ok {
- sc.tlsState = new(tls.ConnectionState)
- *sc.tlsState = tc.ConnectionState()
- // 9.2 Use of TLS Features
- // An implementation of HTTP/2 over TLS MUST use TLS
- // 1.2 or higher with the restrictions on feature set
- // and cipher suite described in this section. Due to
- // implementation limitations, it might not be
- // possible to fail TLS negotiation. An endpoint MUST
- // immediately terminate an HTTP/2 connection that
- // does not meet the TLS requirements described in
- // this section with a connection error (Section
- // 5.4.1) of type INADEQUATE_SECURITY.
- if sc.tlsState.Version < tls.VersionTLS12 {
- sc.rejectConn(ErrCodeInadequateSecurity, "TLS version too low")
- return
- }
-
- if sc.tlsState.ServerName == "" {
- // Client must use SNI, but we don't enforce that anymore,
- // since it was causing problems when connecting to bare IP
- // addresses during development.
- //
- // TODO: optionally enforce? Or enforce at the time we receive
- // a new request, and verify the the ServerName matches the :authority?
- // But that precludes proxy situations, perhaps.
- //
- // So for now, do nothing here again.
- }
-
- if !s.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) {
- // "Endpoints MAY choose to generate a connection error
- // (Section 5.4.1) of type INADEQUATE_SECURITY if one of
- // the prohibited cipher suites are negotiated."
- //
- // We choose that. In my opinion, the spec is weak
- // here. It also says both parties must support at least
- // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no
- // excuses here. If we really must, we could allow an
- // "AllowInsecureWeakCiphers" option on the server later.
- // Let's see how it plays out first.
- sc.rejectConn(ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))
- return
- }
- }
-
- if hook := testHookGetServerConn; hook != nil {
- hook(sc)
- }
- sc.serve()
-}
-
-// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec.
-func isBadCipher(cipher uint16) bool {
- switch cipher {
- case tls.TLS_RSA_WITH_RC4_128_SHA,
- tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
- tls.TLS_RSA_WITH_AES_128_CBC_SHA,
- tls.TLS_RSA_WITH_AES_256_CBC_SHA,
- tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
- tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
- tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- // Reject cipher suites from Appendix A.
- // "This list includes those cipher suites that do not
- // offer an ephemeral key exchange and those that are
- // based on the TLS null, stream or block cipher type"
- return true
- default:
- return false
- }
-}
-
-func (sc *serverConn) rejectConn(err ErrCode, debug string) {
- sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
- // ignoring errors. hanging up anyway.
- sc.framer.WriteGoAway(0, err, []byte(debug))
- sc.bw.Flush()
- sc.conn.Close()
-}
-
-type serverConn struct {
- // Immutable:
- srv *Server
- hs *http.Server
- conn net.Conn
- bw *bufferedWriter // writing to conn
- handler http.Handler
- framer *Framer
- hpackDecoder *hpack.Decoder
- doneServing chan struct{} // closed when serverConn.serve ends
- readFrameCh chan readFrameResult // written by serverConn.readFrames
- wantWriteFrameCh chan frameWriteMsg // from handlers -> serve
- wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
- bodyReadCh chan bodyReadMsg // from handlers -> serve
- testHookCh chan func(int) // code to run on the serve loop
- flow flow // conn-wide (not stream-specific) outbound flow control
- inflow flow // conn-wide inbound flow control
- tlsState *tls.ConnectionState // shared by all handlers, like net/http
- remoteAddrStr string
-
- // Everything following is owned by the serve loop; use serveG.check():
- serveG goroutineLock // used to verify funcs are on serve()
- pushEnabled bool
- sawFirstSettings bool // got the initial SETTINGS frame after the preface
- needToSendSettingsAck bool
- unackedSettings int // how many SETTINGS have we sent without ACKs?
- clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
- advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
- curOpenStreams uint32 // client's number of open streams
- maxStreamID uint32 // max ever seen
- streams map[uint32]*stream
- initialWindowSize int32
- headerTableSize uint32
- peerMaxHeaderListSize uint32 // zero means unknown (default)
- canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
- req requestParam // non-zero while reading request headers
- writingFrame bool // started write goroutine but haven't heard back on wroteFrameCh
- needsFrameFlush bool // last frame write wasn't a flush
- writeSched writeScheduler
- inGoAway bool // we've started to or sent GOAWAY
- needToSendGoAway bool // we need to schedule a GOAWAY frame write
- goAwayCode ErrCode
- shutdownTimerCh <-chan time.Time // nil until used
- shutdownTimer *time.Timer // nil until used
-
- // Owned by the writeFrameAsync goroutine:
- headerWriteBuf bytes.Buffer
- hpackEncoder *hpack.Encoder
-}
-
-func (sc *serverConn) maxHeaderStringLen() int {
- v := sc.maxHeaderListSize()
- if uint32(int(v)) == v {
- return int(v)
- }
- // They had a crazy big number for MaxHeaderBytes anyway,
- // so give them unlimited header lengths:
- return 0
-}
-
-func (sc *serverConn) maxHeaderListSize() uint32 {
- n := sc.hs.MaxHeaderBytes
- if n <= 0 {
- n = http.DefaultMaxHeaderBytes
- }
- // http2's count is in a slightly different unit and includes 32 bytes per pair.
- // So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
- const perFieldOverhead = 32 // per http2 spec
- const typicalHeaders = 10 // conservative
- return uint32(n + typicalHeaders*perFieldOverhead)
-}
-
-// requestParam is the state of the next request, initialized over
-// potentially several frames HEADERS + zero or more CONTINUATION
-// frames.
-type requestParam struct {
- // stream is non-nil if we're reading (HEADER or CONTINUATION)
- // frames for a request (but not DATA).
- stream *stream
- header http.Header
- method, path string
- scheme, authority string
- sawRegularHeader bool // saw a non-pseudo header already
- invalidHeader bool // an invalid header was seen
- headerListSize int64 // actually uint32, but easier math this way
-}
-
-// stream represents a stream. This is the minimal metadata needed by
-// the serve goroutine. Most of the actual stream state is owned by
-// the http.Handler's goroutine in the responseWriter. Because the
-// responseWriter's responseWriterState is recycled at the end of a
-// handler, this struct intentionally has no pointer to the
-// *responseWriter{,State} itself, as the Handler ending nils out the
-// responseWriter's state field.
-type stream struct {
- // immutable:
- sc *serverConn
- id uint32
- body *pipe // non-nil if expecting DATA frames
- cw closeWaiter // closed wait stream transitions to closed state
-
- // owned by serverConn's serve loop:
- bodyBytes int64 // body bytes seen so far
- declBodyBytes int64 // or -1 if undeclared
- flow flow // limits writing from Handler to client
- inflow flow // what the client is allowed to POST/etc to us
- parent *stream // or nil
- numTrailerValues int64
- weight uint8
- state streamState
- sentReset bool // only true once detached from streams map
- gotReset bool // only true once detacted from streams map
- gotTrailerHeader bool // HEADER frame for trailers was seen
-
- trailer http.Header // accumulated trailers
- reqTrailer http.Header // handler's Request.Trailer
-}
-
-func (sc *serverConn) Framer() *Framer { return sc.framer }
-func (sc *serverConn) CloseConn() error { return sc.conn.Close() }
-func (sc *serverConn) Flush() error { return sc.bw.Flush() }
-func (sc *serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) {
- return sc.hpackEncoder, &sc.headerWriteBuf
-}
-
-func (sc *serverConn) state(streamID uint32) (streamState, *stream) {
- sc.serveG.check()
- // http://http2.github.io/http2-spec/#rfc.section.5.1
- if st, ok := sc.streams[streamID]; ok {
- return st.state, st
- }
- // "The first use of a new stream identifier implicitly closes all
- // streams in the "idle" state that might have been initiated by
- // that peer with a lower-valued stream identifier. For example, if
- // a client sends a HEADERS frame on stream 7 without ever sending a
- // frame on stream 5, then stream 5 transitions to the "closed"
- // state when the first frame for stream 7 is sent or received."
- if streamID <= sc.maxStreamID {
- return stateClosed, nil
- }
- return stateIdle, nil
-}
-
-// setConnState calls the net/http ConnState hook for this connection, if configured.
-// Note that the net/http package does StateNew and StateClosed for us.
-// There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
-func (sc *serverConn) setConnState(state http.ConnState) {
- if sc.hs.ConnState != nil {
- sc.hs.ConnState(sc.conn, state)
- }
-}
-
-func (sc *serverConn) vlogf(format string, args ...interface{}) {
- if VerboseLogs {
- sc.logf(format, args...)
- }
-}
-
-func (sc *serverConn) logf(format string, args ...interface{}) {
- if lg := sc.hs.ErrorLog; lg != nil {
- lg.Printf(format, args...)
- } else {
- log.Printf(format, args...)
- }
-}
-
-// errno returns v's underlying uintptr, else 0.
-//
-// TODO: remove this helper function once http2 can use build
-// tags. See comment in isClosedConnError.
-func errno(v error) uintptr {
- if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {
- return uintptr(rv.Uint())
- }
- return 0
-}
-
-// isClosedConnError reports whether err is an error from use of a closed
-// network connection.
-func isClosedConnError(err error) bool {
- if err == nil {
- return false
- }
-
- // TODO: remove this string search and be more like the Windows
- // case below. That might involve modifying the standard library
- // to return better error types.
- str := err.Error()
- if strings.Contains(str, "use of closed network connection") {
- return true
- }
-
- // TODO(bradfitz): x/tools/cmd/bundle doesn't really support
- // build tags, so I can't make an http2_windows.go file with
- // Windows-specific stuff. Fix that and move this, once we
- // have a way to bundle this into std's net/http somehow.
- if runtime.GOOS == "windows" {
- if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
- if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" {
- const WSAECONNABORTED = 10053
- const WSAECONNRESET = 10054
- if n := errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED {
- return true
- }
- }
- }
- }
- return false
-}
-
-func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
- if err == nil {
- return
- }
- if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) {
- // Boring, expected errors.
- sc.vlogf(format, args...)
- } else {
- sc.logf(format, args...)
- }
-}
-
-func (sc *serverConn) onNewHeaderField(f hpack.HeaderField) {
- sc.serveG.check()
- if VerboseLogs {
- sc.vlogf("http2: server decoded %v", f)
- }
- switch {
- case !validHeaderFieldValue(f.Value): // f.Name checked _after_ pseudo check, since ':' is invalid
- sc.req.invalidHeader = true
- case strings.HasPrefix(f.Name, ":"):
- if sc.req.sawRegularHeader {
- sc.logf("pseudo-header after regular header")
- sc.req.invalidHeader = true
- return
- }
- var dst *string
- switch f.Name {
- case ":method":
- dst = &sc.req.method
- case ":path":
- dst = &sc.req.path
- case ":scheme":
- dst = &sc.req.scheme
- case ":authority":
- dst = &sc.req.authority
- default:
- // 8.1.2.1 Pseudo-Header Fields
- // "Endpoints MUST treat a request or response
- // that contains undefined or invalid
- // pseudo-header fields as malformed (Section
- // 8.1.2.6)."
- sc.logf("invalid pseudo-header %q", f.Name)
- sc.req.invalidHeader = true
- return
- }
- if *dst != "" {
- sc.logf("duplicate pseudo-header %q sent", f.Name)
- sc.req.invalidHeader = true
- return
- }
- *dst = f.Value
- case !validHeaderFieldName(f.Name):
- sc.req.invalidHeader = true
- default:
- sc.req.sawRegularHeader = true
- sc.req.header.Add(sc.canonicalHeader(f.Name), f.Value)
- const headerFieldOverhead = 32 // per spec
- sc.req.headerListSize += int64(len(f.Name)) + int64(len(f.Value)) + headerFieldOverhead
- if sc.req.headerListSize > int64(sc.maxHeaderListSize()) {
- sc.hpackDecoder.SetEmitEnabled(false)
- }
- }
-}
-
-func (st *stream) onNewTrailerField(f hpack.HeaderField) {
- sc := st.sc
- sc.serveG.check()
- if VerboseLogs {
- sc.vlogf("http2: server decoded trailer %v", f)
- }
- switch {
- case strings.HasPrefix(f.Name, ":"):
- sc.req.invalidHeader = true
- return
- case !validHeaderFieldName(f.Name) || !validHeaderFieldValue(f.Value):
- sc.req.invalidHeader = true
- return
- default:
- key := sc.canonicalHeader(f.Name)
- if st.trailer != nil {
- vv := append(st.trailer[key], f.Value)
- st.trailer[key] = vv
-
- // arbitrary; TODO: read spec about header list size limits wrt trailers
- const tooBig = 1000
- if len(vv) >= tooBig {
- sc.hpackDecoder.SetEmitEnabled(false)
- }
- }
- }
-}
-
-func (sc *serverConn) canonicalHeader(v string) string {
- sc.serveG.check()
- cv, ok := commonCanonHeader[v]
- if ok {
- return cv
- }
- cv, ok = sc.canonHeader[v]
- if ok {
- return cv
- }
- if sc.canonHeader == nil {
- sc.canonHeader = make(map[string]string)
- }
- cv = http.CanonicalHeaderKey(v)
- sc.canonHeader[v] = cv
- return cv
-}
-
-type readFrameResult struct {
- f Frame // valid until readMore is called
- err error
-
- // readMore should be called once the consumer no longer needs or
- // retains f. After readMore, f is invalid and more frames can be
- // read.
- readMore func()
-}
-
-// readFrames is the loop that reads incoming frames.
-// It takes care to only read one frame at a time, blocking until the
-// consumer is done with the frame.
-// It's run on its own goroutine.
-func (sc *serverConn) readFrames() {
- gate := make(gate)
- for {
- f, err := sc.framer.ReadFrame()
- select {
- case sc.readFrameCh <- readFrameResult{f, err, gate.Done}:
- case <-sc.doneServing:
- return
- }
- select {
- case <-gate:
- case <-sc.doneServing:
- return
- }
- if terminalReadFrameError(err) {
- return
- }
- }
-}
-
-// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
-type frameWriteResult struct {
- wm frameWriteMsg // what was written (or attempted)
- err error // result of the writeFrame call
-}
-
-// writeFrameAsync runs in its own goroutine and writes a single frame
-// and then reports when it's done.
-// At most one goroutine can be running writeFrameAsync at a time per
-// serverConn.
-func (sc *serverConn) writeFrameAsync(wm frameWriteMsg) {
- err := wm.write.writeFrame(sc)
- sc.wroteFrameCh <- frameWriteResult{wm, err}
-}
-
-func (sc *serverConn) closeAllStreamsOnConnClose() {
- sc.serveG.check()
- for _, st := range sc.streams {
- sc.closeStream(st, errClientDisconnected)
- }
-}
-
-func (sc *serverConn) stopShutdownTimer() {
- sc.serveG.check()
- if t := sc.shutdownTimer; t != nil {
- t.Stop()
- }
-}
-
-func (sc *serverConn) notePanic() {
- // Note: this is for serverConn.serve panicking, not http.Handler code.
- if testHookOnPanicMu != nil {
- testHookOnPanicMu.Lock()
- defer testHookOnPanicMu.Unlock()
- }
- if testHookOnPanic != nil {
- if e := recover(); e != nil {
- if testHookOnPanic(sc, e) {
- panic(e)
- }
- }
- }
-}
-
-func (sc *serverConn) serve() {
- sc.serveG.check()
- defer sc.notePanic()
- defer sc.conn.Close()
- defer sc.closeAllStreamsOnConnClose()
- defer sc.stopShutdownTimer()
- defer close(sc.doneServing) // unblocks handlers trying to send
-
- if VerboseLogs {
- sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
- }
-
- sc.writeFrame(frameWriteMsg{
- write: writeSettings{
- {SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
- {SettingMaxConcurrentStreams, sc.advMaxStreams},
- {SettingMaxHeaderListSize, sc.maxHeaderListSize()},
-
- // TODO: more actual settings, notably
- // SettingInitialWindowSize, but then we also
- // want to bump up the conn window size the
- // same amount here right after the settings
- },
- })
- sc.unackedSettings++
-
- if err := sc.readPreface(); err != nil {
- sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err)
- return
- }
- // Now that we've got the preface, get us out of the
- // "StateNew" state. We can't go directly to idle, though.
- // Active means we read some data and anticipate a request. We'll
- // do another Active when we get a HEADERS frame.
- sc.setConnState(http.StateActive)
- sc.setConnState(http.StateIdle)
-
- go sc.readFrames() // closed by defer sc.conn.Close above
-
- settingsTimer := time.NewTimer(firstSettingsTimeout)
- loopNum := 0
- for {
- loopNum++
- select {
- case wm := <-sc.wantWriteFrameCh:
- sc.writeFrame(wm)
- case res := <-sc.wroteFrameCh:
- sc.wroteFrame(res)
- case res := <-sc.readFrameCh:
- if !sc.processFrameFromReader(res) {
- return
- }
- res.readMore()
- if settingsTimer.C != nil {
- settingsTimer.Stop()
- settingsTimer.C = nil
- }
- case m := <-sc.bodyReadCh:
- sc.noteBodyRead(m.st, m.n)
- case <-settingsTimer.C:
- sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr())
- return
- case <-sc.shutdownTimerCh:
- sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr())
- return
- case fn := <-sc.testHookCh:
- fn(loopNum)
- }
- }
-}
-
-// readPreface reads the ClientPreface greeting from the peer
-// or returns an error on timeout or an invalid greeting.
-func (sc *serverConn) readPreface() error {
- errc := make(chan error, 1)
- go func() {
- // Read the client preface
- buf := make([]byte, len(ClientPreface))
- if _, err := io.ReadFull(sc.conn, buf); err != nil {
- errc <- err
- } else if !bytes.Equal(buf, clientPreface) {
- errc <- fmt.Errorf("bogus greeting %q", buf)
- } else {
- errc <- nil
- }
- }()
- timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server?
- defer timer.Stop()
- select {
- case <-timer.C:
- return errors.New("timeout waiting for client preface")
- case err := <-errc:
- if err == nil {
- if VerboseLogs {
- sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr())
- }
- }
- return err
- }
-}
-
-var errChanPool = sync.Pool{
- New: func() interface{} { return make(chan error, 1) },
-}
-
-var writeDataPool = sync.Pool{
- New: func() interface{} { return new(writeData) },
-}
-
-// writeDataFromHandler writes DATA response frames from a handler on
-// the given stream.
-func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error {
- ch := errChanPool.Get().(chan error)
- writeArg := writeDataPool.Get().(*writeData)
- *writeArg = writeData{stream.id, data, endStream}
- err := sc.writeFrameFromHandler(frameWriteMsg{
- write: writeArg,
- stream: stream,
- done: ch,
- })
- if err != nil {
- return err
- }
- var frameWriteDone bool // the frame write is done (successfully or not)
- select {
- case err = <-ch:
- frameWriteDone = true
- case <-sc.doneServing:
- return errClientDisconnected
- case <-stream.cw:
- // If both ch and stream.cw were ready (as might
- // happen on the final Write after an http.Handler
- // ends), prefer the write result. Otherwise this
- // might just be us successfully closing the stream.
- // The writeFrameAsync and serve goroutines guarantee
- // that the ch send will happen before the stream.cw
- // close.
- select {
- case err = <-ch:
- frameWriteDone = true
- default:
- return errStreamClosed
- }
- }
- errChanPool.Put(ch)
- if frameWriteDone {
- writeDataPool.Put(writeArg)
- }
- return err
-}
-
-// writeFrameFromHandler sends wm to sc.wantWriteFrameCh, but aborts
-// if the connection has gone away.
-//
-// This must not be run from the serve goroutine itself, else it might
-// deadlock writing to sc.wantWriteFrameCh (which is only mildly
-// buffered and is read by serve itself). If you're on the serve
-// goroutine, call writeFrame instead.
-func (sc *serverConn) writeFrameFromHandler(wm frameWriteMsg) error {
- sc.serveG.checkNotOn() // NOT
- select {
- case sc.wantWriteFrameCh <- wm:
- return nil
- case <-sc.doneServing:
- // Serve loop is gone.
- // Client has closed their connection to the server.
- return errClientDisconnected
- }
-}
-
-// writeFrame schedules a frame to write and sends it if there's nothing
-// already being written.
-//
-// There is no pushback here (the serve goroutine never blocks). It's
-// the http.Handlers that block, waiting for their previous frames to
-// make it onto the wire
-//
-// If you're not on the serve goroutine, use writeFrameFromHandler instead.
-func (sc *serverConn) writeFrame(wm frameWriteMsg) {
- sc.serveG.check()
- sc.writeSched.add(wm)
- sc.scheduleFrameWrite()
-}
-
-// startFrameWrite starts a goroutine to write wm (in a separate
-// goroutine since that might block on the network), and updates the
-// serve goroutine's state about the world, updated from info in wm.
-func (sc *serverConn) startFrameWrite(wm frameWriteMsg) {
- sc.serveG.check()
- if sc.writingFrame {
- panic("internal error: can only be writing one frame at a time")
- }
-
- st := wm.stream
- if st != nil {
- switch st.state {
- case stateHalfClosedLocal:
- panic("internal error: attempt to send frame on half-closed-local stream")
- case stateClosed:
- if st.sentReset || st.gotReset {
- // Skip this frame.
- sc.scheduleFrameWrite()
- return
- }
- panic(fmt.Sprintf("internal error: attempt to send a write %v on a closed stream", wm))
- }
- }
-
- sc.writingFrame = true
- sc.needsFrameFlush = true
- go sc.writeFrameAsync(wm)
-}
-
-// errHandlerPanicked is the error given to any callers blocked in a read from
-// Request.Body when the main goroutine panics. Since most handlers read in the
-// the main ServeHTTP goroutine, this will show up rarely.
-var errHandlerPanicked = errors.New("http2: handler panicked")
-
-// wroteFrame is called on the serve goroutine with the result of
-// whatever happened on writeFrameAsync.
-func (sc *serverConn) wroteFrame(res frameWriteResult) {
- sc.serveG.check()
- if !sc.writingFrame {
- panic("internal error: expected to be already writing a frame")
- }
- sc.writingFrame = false
-
- wm := res.wm
- st := wm.stream
-
- closeStream := endsStream(wm.write)
-
- if _, ok := wm.write.(handlerPanicRST); ok {
- sc.closeStream(st, errHandlerPanicked)
- }
-
- // Reply (if requested) to the blocked ServeHTTP goroutine.
- if ch := wm.done; ch != nil {
- select {
- case ch <- res.err:
- default:
- panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wm.write))
- }
- }
- wm.write = nil // prevent use (assume it's tainted after wm.done send)
-
- if closeStream {
- if st == nil {
- panic("internal error: expecting non-nil stream")
- }
- switch st.state {
- case stateOpen:
- // Here we would go to stateHalfClosedLocal in
- // theory, but since our handler is done and
- // the net/http package provides no mechanism
- // for finishing writing to a ResponseWriter
- // while still reading data (see possible TODO
- // at top of this file), we go into closed
- // state here anyway, after telling the peer
- // we're hanging up on them.
- st.state = stateHalfClosedLocal // won't last long, but necessary for closeStream via resetStream
- errCancel := StreamError{st.id, ErrCodeCancel}
- sc.resetStream(errCancel)
- case stateHalfClosedRemote:
- sc.closeStream(st, errHandlerComplete)
- }
- }
-
- sc.scheduleFrameWrite()
-}
-
-// scheduleFrameWrite tickles the frame writing scheduler.
-//
-// If a frame is already being written, nothing happens. This will be called again
-// when the frame is done being written.
-//
-// If a frame isn't being written we need to send one, the best frame
-// to send is selected, preferring first things that aren't
-// stream-specific (e.g. ACKing settings), and then finding the
-// highest priority stream.
-//
-// If a frame isn't being written and there's nothing else to send, we
-// flush the write buffer.
-func (sc *serverConn) scheduleFrameWrite() {
- sc.serveG.check()
- if sc.writingFrame {
- return
- }
- if sc.needToSendGoAway {
- sc.needToSendGoAway = false
- sc.startFrameWrite(frameWriteMsg{
- write: &writeGoAway{
- maxStreamID: sc.maxStreamID,
- code: sc.goAwayCode,
- },
- })
- return
- }
- if sc.needToSendSettingsAck {
- sc.needToSendSettingsAck = false
- sc.startFrameWrite(frameWriteMsg{write: writeSettingsAck{}})
- return
- }
- if !sc.inGoAway {
- if wm, ok := sc.writeSched.take(); ok {
- sc.startFrameWrite(wm)
- return
- }
- }
- if sc.needsFrameFlush {
- sc.startFrameWrite(frameWriteMsg{write: flushFrameWriter{}})
- sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
- return
- }
-}
-
-func (sc *serverConn) goAway(code ErrCode) {
- sc.serveG.check()
- if sc.inGoAway {
- return
- }
- if code != ErrCodeNo {
- sc.shutDownIn(250 * time.Millisecond)
- } else {
- // TODO: configurable
- sc.shutDownIn(1 * time.Second)
- }
- sc.inGoAway = true
- sc.needToSendGoAway = true
- sc.goAwayCode = code
- sc.scheduleFrameWrite()
-}
-
-func (sc *serverConn) shutDownIn(d time.Duration) {
- sc.serveG.check()
- sc.shutdownTimer = time.NewTimer(d)
- sc.shutdownTimerCh = sc.shutdownTimer.C
-}
-
-func (sc *serverConn) resetStream(se StreamError) {
- sc.serveG.check()
- sc.writeFrame(frameWriteMsg{write: se})
- if st, ok := sc.streams[se.StreamID]; ok {
- st.sentReset = true
- sc.closeStream(st, se)
- }
-}
-
-// processFrameFromReader processes the serve loop's read from readFrameCh from the
-// frame-reading goroutine.
-// processFrameFromReader returns whether the connection should be kept open.
-func (sc *serverConn) processFrameFromReader(res readFrameResult) bool {
- sc.serveG.check()
- err := res.err
- if err != nil {
- if err == ErrFrameTooLarge {
- sc.goAway(ErrCodeFrameSize)
- return true // goAway will close the loop
- }
- clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err)
- if clientGone {
- // TODO: could we also get into this state if
- // the peer does a half close
- // (e.g. CloseWrite) because they're done
- // sending frames but they're still wanting
- // our open replies? Investigate.
- // TODO: add CloseWrite to crypto/tls.Conn first
- // so we have a way to test this? I suppose
- // just for testing we could have a non-TLS mode.
- return false
- }
- } else {
- f := res.f
- if VerboseLogs {
- sc.vlogf("http2: server read frame %v", summarizeFrame(f))
- }
- err = sc.processFrame(f)
- if err == nil {
- return true
- }
- }
-
- switch ev := err.(type) {
- case StreamError:
- sc.resetStream(ev)
- return true
- case goAwayFlowError:
- sc.goAway(ErrCodeFlowControl)
- return true
- case ConnectionError:
- sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev)
- sc.goAway(ErrCode(ev))
- return true // goAway will handle shutdown
- default:
- if res.err != nil {
- sc.vlogf("http2: server closing client connection; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err)
- } else {
- sc.logf("http2: server closing client connection: %v", err)
- }
- return false
- }
-}
-
-func (sc *serverConn) processFrame(f Frame) error {
- sc.serveG.check()
-
- // First frame received must be SETTINGS.
- if !sc.sawFirstSettings {
- if _, ok := f.(*SettingsFrame); !ok {
- return ConnectionError(ErrCodeProtocol)
- }
- sc.sawFirstSettings = true
- }
-
- switch f := f.(type) {
- case *SettingsFrame:
- return sc.processSettings(f)
- case *HeadersFrame:
- return sc.processHeaders(f)
- case *ContinuationFrame:
- return sc.processContinuation(f)
- case *WindowUpdateFrame:
- return sc.processWindowUpdate(f)
- case *PingFrame:
- return sc.processPing(f)
- case *DataFrame:
- return sc.processData(f)
- case *RSTStreamFrame:
- return sc.processResetStream(f)
- case *PriorityFrame:
- return sc.processPriority(f)
- case *PushPromiseFrame:
- // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
- // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
- return ConnectionError(ErrCodeProtocol)
- default:
- sc.vlogf("http2: server ignoring frame: %v", f.Header())
- return nil
- }
-}
-
-func (sc *serverConn) processPing(f *PingFrame) error {
- sc.serveG.check()
- if f.IsAck() {
- // 6.7 PING: " An endpoint MUST NOT respond to PING frames
- // containing this flag."
- return nil
- }
- if f.StreamID != 0 {
- // "PING frames are not associated with any individual
- // stream. If a PING frame is received with a stream
- // identifier field value other than 0x0, the recipient MUST
- // respond with a connection error (Section 5.4.1) of type
- // PROTOCOL_ERROR."
- return ConnectionError(ErrCodeProtocol)
- }
- sc.writeFrame(frameWriteMsg{write: writePingAck{f}})
- return nil
-}
-
-func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {
- sc.serveG.check()
- switch {
- case f.StreamID != 0: // stream-level flow control
- st := sc.streams[f.StreamID]
- if st == nil {
- // "WINDOW_UPDATE can be sent by a peer that has sent a
- // frame bearing the END_STREAM flag. This means that a
- // receiver could receive a WINDOW_UPDATE frame on a "half
- // closed (remote)" or "closed" stream. A receiver MUST
- // NOT treat this as an error, see Section 5.1."
- return nil
- }
- if !st.flow.add(int32(f.Increment)) {
- return StreamError{f.StreamID, ErrCodeFlowControl}
- }
- default: // connection-level flow control
- if !sc.flow.add(int32(f.Increment)) {
- return goAwayFlowError{}
- }
- }
- sc.scheduleFrameWrite()
- return nil
-}
-
-func (sc *serverConn) processResetStream(f *RSTStreamFrame) error {
- sc.serveG.check()
-
- state, st := sc.state(f.StreamID)
- if state == stateIdle {
- // 6.4 "RST_STREAM frames MUST NOT be sent for a
- // stream in the "idle" state. If a RST_STREAM frame
- // identifying an idle stream is received, the
- // recipient MUST treat this as a connection error
- // (Section 5.4.1) of type PROTOCOL_ERROR.
- return ConnectionError(ErrCodeProtocol)
- }
- if st != nil {
- st.gotReset = true
- sc.closeStream(st, StreamError{f.StreamID, f.ErrCode})
- }
- return nil
-}
-
-func (sc *serverConn) closeStream(st *stream, err error) {
- sc.serveG.check()
- if st.state == stateIdle || st.state == stateClosed {
- panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
- }
- st.state = stateClosed
- sc.curOpenStreams--
- if sc.curOpenStreams == 0 {
- sc.setConnState(http.StateIdle)
- }
- delete(sc.streams, st.id)
- if p := st.body; p != nil {
- p.CloseWithError(err)
- }
- st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
- sc.writeSched.forgetStream(st.id)
-}
-
-func (sc *serverConn) processSettings(f *SettingsFrame) error {
- sc.serveG.check()
- if f.IsAck() {
- sc.unackedSettings--
- if sc.unackedSettings < 0 {
- // Why is the peer ACKing settings we never sent?
- // The spec doesn't mention this case, but
- // hang up on them anyway.
- return ConnectionError(ErrCodeProtocol)
- }
- return nil
- }
- if err := f.ForeachSetting(sc.processSetting); err != nil {
- return err
- }
- sc.needToSendSettingsAck = true
- sc.scheduleFrameWrite()
- return nil
-}
-
-func (sc *serverConn) processSetting(s Setting) error {
- sc.serveG.check()
- if err := s.Valid(); err != nil {
- return err
- }
- if VerboseLogs {
- sc.vlogf("http2: server processing setting %v", s)
- }
- switch s.ID {
- case SettingHeaderTableSize:
- sc.headerTableSize = s.Val
- sc.hpackEncoder.SetMaxDynamicTableSize(s.Val)
- case SettingEnablePush:
- sc.pushEnabled = s.Val != 0
- case SettingMaxConcurrentStreams:
- sc.clientMaxStreams = s.Val
- case SettingInitialWindowSize:
- return sc.processSettingInitialWindowSize(s.Val)
- case SettingMaxFrameSize:
- sc.writeSched.maxFrameSize = s.Val
- case SettingMaxHeaderListSize:
- sc.peerMaxHeaderListSize = s.Val
- default:
- // Unknown setting: "An endpoint that receives a SETTINGS
- // frame with any unknown or unsupported identifier MUST
- // ignore that setting."
- if VerboseLogs {
- sc.vlogf("http2: server ignoring unknown setting %v", s)
- }
- }
- return nil
-}
-
-func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
- sc.serveG.check()
- // Note: val already validated to be within range by
- // processSetting's Valid call.
-
- // "A SETTINGS frame can alter the initial flow control window
- // size for all current streams. When the value of
- // SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST
- // adjust the size of all stream flow control windows that it
- // maintains by the difference between the new value and the
- // old value."
- old := sc.initialWindowSize
- sc.initialWindowSize = int32(val)
- growth := sc.initialWindowSize - old // may be negative
- for _, st := range sc.streams {
- if !st.flow.add(growth) {
- // 6.9.2 Initial Flow Control Window Size
- // "An endpoint MUST treat a change to
- // SETTINGS_INITIAL_WINDOW_SIZE that causes any flow
- // control window to exceed the maximum size as a
- // connection error (Section 5.4.1) of type
- // FLOW_CONTROL_ERROR."
- return ConnectionError(ErrCodeFlowControl)
- }
- }
- return nil
-}
-
-func (sc *serverConn) processData(f *DataFrame) error {
- sc.serveG.check()
- // "If a DATA frame is received whose stream is not in "open"
- // or "half closed (local)" state, the recipient MUST respond
- // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
- id := f.Header().StreamID
- st, ok := sc.streams[id]
- if !ok || st.state != stateOpen || st.gotTrailerHeader {
- // This includes sending a RST_STREAM if the stream is
- // in stateHalfClosedLocal (which currently means that
- // the http.Handler returned, so it's done reading &
- // done writing). Try to stop the client from sending
- // more DATA.
- return StreamError{id, ErrCodeStreamClosed}
- }
- if st.body == nil {
- panic("internal error: should have a body in this state")
- }
- data := f.Data()
-
- // Sender sending more than they'd declared?
- if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
- st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
- return StreamError{id, ErrCodeStreamClosed}
- }
- if len(data) > 0 {
- // Check whether the client has flow control quota.
- if int(st.inflow.available()) < len(data) {
- return StreamError{id, ErrCodeFlowControl}
- }
- st.inflow.take(int32(len(data)))
- wrote, err := st.body.Write(data)
- if err != nil {
- return StreamError{id, ErrCodeStreamClosed}
- }
- if wrote != len(data) {
- panic("internal error: bad Writer")
- }
- st.bodyBytes += int64(len(data))
- }
- if f.StreamEnded() {
- st.endStream()
- }
- return nil
-}
-
-// endStream closes a Request.Body's pipe. It is called when a DATA
-// frame says a request body is over (or after trailers).
-func (st *stream) endStream() {
- sc := st.sc
- sc.serveG.check()
-
- if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {
- st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
- st.declBodyBytes, st.bodyBytes))
- } else {
- st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest)
- st.body.CloseWithError(io.EOF)
- }
- st.state = stateHalfClosedRemote
-}
-
-// copyTrailersToHandlerRequest is run in the Handler's goroutine in
-// its Request.Body.Read just before it gets io.EOF.
-func (st *stream) copyTrailersToHandlerRequest() {
- for k, vv := range st.trailer {
- if _, ok := st.reqTrailer[k]; ok {
- // Only copy it over it was pre-declared.
- st.reqTrailer[k] = vv
- }
- }
-}
-
-func (sc *serverConn) processHeaders(f *HeadersFrame) error {
- sc.serveG.check()
- id := f.Header().StreamID
- if sc.inGoAway {
- // Ignore.
- return nil
- }
- // http://http2.github.io/http2-spec/#rfc.section.5.1.1
- // Streams initiated by a client MUST use odd-numbered stream
- // identifiers. [...] An endpoint that receives an unexpected
- // stream identifier MUST respond with a connection error
- // (Section 5.4.1) of type PROTOCOL_ERROR.
- if id%2 != 1 {
- return ConnectionError(ErrCodeProtocol)
- }
- // A HEADERS frame can be used to create a new stream or
- // send a trailer for an open one. If we already have a stream
- // open, let it process its own HEADERS frame (trailers at this
- // point, if it's valid).
- st := sc.streams[f.Header().StreamID]
- if st != nil {
- return st.processTrailerHeaders(f)
- }
-
- // [...] The identifier of a newly established stream MUST be
- // numerically greater than all streams that the initiating
- // endpoint has opened or reserved. [...] An endpoint that
- // receives an unexpected stream identifier MUST respond with
- // a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
- if id <= sc.maxStreamID || sc.req.stream != nil {
- return ConnectionError(ErrCodeProtocol)
- }
-
- if id > sc.maxStreamID {
- sc.maxStreamID = id
- }
- st = &stream{
- sc: sc,
- id: id,
- state: stateOpen,
- }
- if f.StreamEnded() {
- st.state = stateHalfClosedRemote
- }
- st.cw.Init()
-
- st.flow.conn = &sc.flow // link to conn-level counter
- st.flow.add(sc.initialWindowSize)
- st.inflow.conn = &sc.inflow // link to conn-level counter
- st.inflow.add(initialWindowSize) // TODO: update this when we send a higher initial window size in the initial settings
-
- sc.streams[id] = st
- if f.HasPriority() {
- adjustStreamPriority(sc.streams, st.id, f.Priority)
- }
- sc.curOpenStreams++
- if sc.curOpenStreams == 1 {
- sc.setConnState(http.StateActive)
- }
- sc.req = requestParam{
- stream: st,
- header: make(http.Header),
- }
- sc.hpackDecoder.SetEmitFunc(sc.onNewHeaderField)
- sc.hpackDecoder.SetEmitEnabled(true)
- return sc.processHeaderBlockFragment(st, f.HeaderBlockFragment(), f.HeadersEnded())
-}
-
-func (st *stream) processTrailerHeaders(f *HeadersFrame) error {
- sc := st.sc
- sc.serveG.check()
- if st.gotTrailerHeader {
- return ConnectionError(ErrCodeProtocol)
- }
- st.gotTrailerHeader = true
- if !f.StreamEnded() {
- return StreamError{st.id, ErrCodeProtocol}
- }
- sc.resetPendingRequest() // we use invalidHeader from it for trailers
- return st.processTrailerHeaderBlockFragment(f.HeaderBlockFragment(), f.HeadersEnded())
-}
-
-func (sc *serverConn) processContinuation(f *ContinuationFrame) error {
- sc.serveG.check()
- st := sc.streams[f.Header().StreamID]
- if st.gotTrailerHeader {
- return st.processTrailerHeaderBlockFragment(f.HeaderBlockFragment(), f.HeadersEnded())
- }
- return sc.processHeaderBlockFragment(st, f.HeaderBlockFragment(), f.HeadersEnded())
-}
-
-func (sc *serverConn) processHeaderBlockFragment(st *stream, frag []byte, end bool) error {
- sc.serveG.check()
- if _, err := sc.hpackDecoder.Write(frag); err != nil {
- return ConnectionError(ErrCodeCompression)
- }
- if !end {
- return nil
- }
- if err := sc.hpackDecoder.Close(); err != nil {
- return ConnectionError(ErrCodeCompression)
- }
- defer sc.resetPendingRequest()
- if sc.curOpenStreams > sc.advMaxStreams {
- // "Endpoints MUST NOT exceed the limit set by their
- // peer. An endpoint that receives a HEADERS frame
- // that causes their advertised concurrent stream
- // limit to be exceeded MUST treat this as a stream
- // error (Section 5.4.2) of type PROTOCOL_ERROR or
- // REFUSED_STREAM."
- if sc.unackedSettings == 0 {
- // They should know better.
- return StreamError{st.id, ErrCodeProtocol}
- }
- // Assume it's a network race, where they just haven't
- // received our last SETTINGS update. But actually
- // this can't happen yet, because we don't yet provide
- // a way for users to adjust server parameters at
- // runtime.
- return StreamError{st.id, ErrCodeRefusedStream}
- }
-
- rw, req, err := sc.newWriterAndRequest()
- if err != nil {
- return err
- }
- st.reqTrailer = req.Trailer
- if st.reqTrailer != nil {
- st.trailer = make(http.Header)
- }
- st.body = req.Body.(*requestBody).pipe // may be nil
- st.declBodyBytes = req.ContentLength
-
- handler := sc.handler.ServeHTTP
- if !sc.hpackDecoder.EmitEnabled() {
- // Their header list was too long. Send a 431 error.
- handler = handleHeaderListTooLong
- }
-
- go sc.runHandler(rw, req, handler)
- return nil
-}
-
-func (st *stream) processTrailerHeaderBlockFragment(frag []byte, end bool) error {
- sc := st.sc
- sc.serveG.check()
- sc.hpackDecoder.SetEmitFunc(st.onNewTrailerField)
- if _, err := sc.hpackDecoder.Write(frag); err != nil {
- return ConnectionError(ErrCodeCompression)
- }
- if !end {
- return nil
- }
-
- rp := &sc.req
- if rp.invalidHeader {
- return StreamError{rp.stream.id, ErrCodeProtocol}
- }
-
- err := sc.hpackDecoder.Close()
- st.endStream()
- if err != nil {
- return ConnectionError(ErrCodeCompression)
- }
- return nil
-}
-
-func (sc *serverConn) processPriority(f *PriorityFrame) error {
- adjustStreamPriority(sc.streams, f.StreamID, f.PriorityParam)
- return nil
-}
-
-func adjustStreamPriority(streams map[uint32]*stream, streamID uint32, priority PriorityParam) {
- st, ok := streams[streamID]
- if !ok {
- // TODO: not quite correct (this streamID might
- // already exist in the dep tree, but be closed), but
- // close enough for now.
- return
- }
- st.weight = priority.Weight
- parent := streams[priority.StreamDep] // might be nil
- if parent == st {
- // if client tries to set this stream to be the parent of itself
- // ignore and keep going
- return
- }
-
- // section 5.3.3: If a stream is made dependent on one of its
- // own dependencies, the formerly dependent stream is first
- // moved to be dependent on the reprioritized stream's previous
- // parent. The moved dependency retains its weight.
- for piter := parent; piter != nil; piter = piter.parent {
- if piter == st {
- parent.parent = st.parent
- break
- }
- }
- st.parent = parent
- if priority.Exclusive && (st.parent != nil || priority.StreamDep == 0) {
- for _, openStream := range streams {
- if openStream != st && openStream.parent == st.parent {
- openStream.parent = st
- }
- }
- }
-}
-
-// resetPendingRequest zeros out all state related to a HEADERS frame
-// and its zero or more CONTINUATION frames sent to start a new
-// request.
-func (sc *serverConn) resetPendingRequest() {
- sc.serveG.check()
- sc.req = requestParam{}
-}
-
-func (sc *serverConn) newWriterAndRequest() (*responseWriter, *http.Request, error) {
- sc.serveG.check()
- rp := &sc.req
-
- if rp.invalidHeader {
- return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
- }
-
- isConnect := rp.method == "CONNECT"
- if isConnect {
- if rp.path != "" || rp.scheme != "" || rp.authority == "" {
- return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
- }
- } else if rp.method == "" || rp.path == "" ||
- (rp.scheme != "https" && rp.scheme != "http") {
- // See 8.1.2.6 Malformed Requests and Responses:
- //
- // Malformed requests or responses that are detected
- // MUST be treated as a stream error (Section 5.4.2)
- // of type PROTOCOL_ERROR."
- //
- // 8.1.2.3 Request Pseudo-Header Fields
- // "All HTTP/2 requests MUST include exactly one valid
- // value for the :method, :scheme, and :path
- // pseudo-header fields"
- return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
- }
-
- bodyOpen := rp.stream.state == stateOpen
- if rp.method == "HEAD" && bodyOpen {
- // HEAD requests can't have bodies
- return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
- }
- var tlsState *tls.ConnectionState // nil if not scheme https
-
- if rp.scheme == "https" {
- tlsState = sc.tlsState
- }
- authority := rp.authority
- if authority == "" {
- authority = rp.header.Get("Host")
- }
- needsContinue := rp.header.Get("Expect") == "100-continue"
- if needsContinue {
- rp.header.Del("Expect")
- }
- // Merge Cookie headers into one "; "-delimited value.
- if cookies := rp.header["Cookie"]; len(cookies) > 1 {
- rp.header.Set("Cookie", strings.Join(cookies, "; "))
- }
-
- // Setup Trailers
- var trailer http.Header
- for _, v := range rp.header["Trailer"] {
- for _, key := range strings.Split(v, ",") {
- key = http.CanonicalHeaderKey(strings.TrimSpace(key))
- switch key {
- case "Transfer-Encoding", "Trailer", "Content-Length":
- // Bogus. (copy of http1 rules)
- // Ignore.
- default:
- if trailer == nil {
- trailer = make(http.Header)
- }
- trailer[key] = nil
- }
- }
- }
- delete(rp.header, "Trailer")
-
- body := &requestBody{
- conn: sc,
- stream: rp.stream,
- needsContinue: needsContinue,
- }
- var url_ *url.URL
- var requestURI string
- if isConnect {
- url_ = &url.URL{Host: rp.authority}
- requestURI = rp.authority // mimic HTTP/1 server behavior
- } else {
- var err error
- url_, err = url.ParseRequestURI(rp.path)
- if err != nil {
- return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol}
- }
- requestURI = rp.path
- }
- req := &http.Request{
- Method: rp.method,
- URL: url_,
- RemoteAddr: sc.remoteAddrStr,
- Header: rp.header,
- RequestURI: requestURI,
- Proto: "HTTP/2.0",
- ProtoMajor: 2,
- ProtoMinor: 0,
- TLS: tlsState,
- Host: authority,
- Body: body,
- Trailer: trailer,
- }
- if bodyOpen {
- body.pipe = &pipe{
- b: &fixedBuffer{buf: make([]byte, initialWindowSize)}, // TODO: garbage
- }
-
- if vv, ok := rp.header["Content-Length"]; ok {
- req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64)
- } else {
- req.ContentLength = -1
- }
- }
-
- rws := responseWriterStatePool.Get().(*responseWriterState)
- bwSave := rws.bw
- *rws = responseWriterState{} // zero all the fields
- rws.conn = sc
- rws.bw = bwSave
- rws.bw.Reset(chunkWriter{rws})
- rws.stream = rp.stream
- rws.req = req
- rws.body = body
-
- rw := &responseWriter{rws: rws}
- return rw, req, nil
-}
-
-// Run on its own goroutine.
-func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
- didPanic := true
- defer func() {
- if didPanic {
- e := recover()
- // Same as net/http:
- const size = 64 << 10
- buf := make([]byte, size)
- buf = buf[:runtime.Stack(buf, false)]
- sc.writeFrameFromHandler(frameWriteMsg{
- write: handlerPanicRST{rw.rws.stream.id},
- stream: rw.rws.stream,
- })
- sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
- return
- }
- rw.handlerDone()
- }()
- handler(rw, req)
- didPanic = false
-}
-
-func handleHeaderListTooLong(w http.ResponseWriter, r *http.Request) {
- // 10.5.1 Limits on Header Block Size:
- // .. "A server that receives a larger header block than it is
- // willing to handle can send an HTTP 431 (Request Header Fields Too
- // Large) status code"
- const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+
- w.WriteHeader(statusRequestHeaderFieldsTooLarge)
- io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
-}
-
-// called from handler goroutines.
-// h may be nil.
-func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) error {
- sc.serveG.checkNotOn() // NOT on
- var errc chan error
- if headerData.h != nil {
- // If there's a header map (which we don't own), so we have to block on
- // waiting for this frame to be written, so an http.Flush mid-handler
- // writes out the correct value of keys, before a handler later potentially
- // mutates it.
- errc = errChanPool.Get().(chan error)
- }
- if err := sc.writeFrameFromHandler(frameWriteMsg{
- write: headerData,
- stream: st,
- done: errc,
- }); err != nil {
- return err
- }
- if errc != nil {
- select {
- case err := <-errc:
- errChanPool.Put(errc)
- return err
- case <-sc.doneServing:
- return errClientDisconnected
- case <-st.cw:
- return errStreamClosed
- }
- }
- return nil
-}
-
-// called from handler goroutines.
-func (sc *serverConn) write100ContinueHeaders(st *stream) {
- sc.writeFrameFromHandler(frameWriteMsg{
- write: write100ContinueHeadersFrame{st.id},
- stream: st,
- })
-}
-
-// A bodyReadMsg tells the server loop that the http.Handler read n
-// bytes of the DATA from the client on the given stream.
-type bodyReadMsg struct {
- st *stream
- n int
-}
-
-// called from handler goroutines.
-// Notes that the handler for the given stream ID read n bytes of its body
-// and schedules flow control tokens to be sent.
-func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int) {
- sc.serveG.checkNotOn() // NOT on
- select {
- case sc.bodyReadCh <- bodyReadMsg{st, n}:
- case <-sc.doneServing:
- }
-}
-
-func (sc *serverConn) noteBodyRead(st *stream, n int) {
- sc.serveG.check()
- sc.sendWindowUpdate(nil, n) // conn-level
- if st.state != stateHalfClosedRemote && st.state != stateClosed {
- // Don't send this WINDOW_UPDATE if the stream is closed
- // remotely.
- sc.sendWindowUpdate(st, n)
- }
-}
-
-// st may be nil for conn-level
-func (sc *serverConn) sendWindowUpdate(st *stream, n int) {
- sc.serveG.check()
- // "The legal range for the increment to the flow control
- // window is 1 to 2^31-1 (2,147,483,647) octets."
- // A Go Read call on 64-bit machines could in theory read
- // a larger Read than this. Very unlikely, but we handle it here
- // rather than elsewhere for now.
- const maxUint31 = 1<<31 - 1
- for n >= maxUint31 {
- sc.sendWindowUpdate32(st, maxUint31)
- n -= maxUint31
- }
- sc.sendWindowUpdate32(st, int32(n))
-}
-
-// st may be nil for conn-level
-func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) {
- sc.serveG.check()
- if n == 0 {
- return
- }
- if n < 0 {
- panic("negative update")
- }
- var streamID uint32
- if st != nil {
- streamID = st.id
- }
- sc.writeFrame(frameWriteMsg{
- write: writeWindowUpdate{streamID: streamID, n: uint32(n)},
- stream: st,
- })
- var ok bool
- if st == nil {
- ok = sc.inflow.add(n)
- } else {
- ok = st.inflow.add(n)
- }
- if !ok {
- panic("internal error; sent too many window updates without decrements?")
- }
-}
-
-type requestBody struct {
- stream *stream
- conn *serverConn
- closed bool
- pipe *pipe // non-nil if we have a HTTP entity message body
- needsContinue bool // need to send a 100-continue
-}
-
-func (b *requestBody) Close() error {
- if b.pipe != nil {
- b.pipe.CloseWithError(errClosedBody)
- }
- b.closed = true
- return nil
-}
-
-func (b *requestBody) Read(p []byte) (n int, err error) {
- if b.needsContinue {
- b.needsContinue = false
- b.conn.write100ContinueHeaders(b.stream)
- }
- if b.pipe == nil {
- return 0, io.EOF
- }
- n, err = b.pipe.Read(p)
- if n > 0 {
- b.conn.noteBodyReadFromHandler(b.stream, n)
- }
- return
-}
-
-// responseWriter is the http.ResponseWriter implementation. It's
-// intentionally small (1 pointer wide) to minimize garbage. The
-// responseWriterState pointer inside is zeroed at the end of a
-// request (in handlerDone) and calls on the responseWriter thereafter
-// simply crash (caller's mistake), but the much larger responseWriterState
-// and buffers are reused between multiple requests.
-type responseWriter struct {
- rws *responseWriterState
-}
-
-// Optional http.ResponseWriter interfaces implemented.
-var (
- _ http.CloseNotifier = (*responseWriter)(nil)
- _ http.Flusher = (*responseWriter)(nil)
- _ stringWriter = (*responseWriter)(nil)
-)
-
-type responseWriterState struct {
- // immutable within a request:
- stream *stream
- req *http.Request
- body *requestBody // to close at end of request, if DATA frames didn't
- conn *serverConn
-
- // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
- bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}
-
- // mutated by http.Handler goroutine:
- handlerHeader http.Header // nil until called
- snapHeader http.Header // snapshot of handlerHeader at WriteHeader time
- trailers []string // set in writeChunk
- status int // status code passed to WriteHeader
- wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
- sentHeader bool // have we sent the header frame?
- handlerDone bool // handler has finished
-
- sentContentLen int64 // non-zero if handler set a Content-Length header
- wroteBytes int64
-
- closeNotifierMu sync.Mutex // guards closeNotifierCh
- closeNotifierCh chan bool // nil until first used
-}
-
-type chunkWriter struct{ rws *responseWriterState }
-
-func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
-
-func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 }
-
-// declareTrailer is called for each Trailer header when the
-// response header is written. It notes that a header will need to be
-// written in the trailers at the end of the response.
-func (rws *responseWriterState) declareTrailer(k string) {
- k = http.CanonicalHeaderKey(k)
- switch k {
- case "Transfer-Encoding", "Content-Length", "Trailer":
- // Forbidden by RFC 2616 14.40.
- return
- }
- if !strSliceContains(rws.trailers, k) {
- rws.trailers = append(rws.trailers, k)
- }
-}
-
-// writeChunk writes chunks from the bufio.Writer. But because
-// bufio.Writer may bypass its chunking, sometimes p may be
-// arbitrarily large.
-//
-// writeChunk is also responsible (on the first chunk) for sending the
-// HEADER response.
-func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
- if !rws.wroteHeader {
- rws.writeHeader(200)
- }
-
- isHeadResp := rws.req.Method == "HEAD"
- if !rws.sentHeader {
- rws.sentHeader = true
- var ctype, clen string
- if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
- rws.snapHeader.Del("Content-Length")
- clen64, err := strconv.ParseInt(clen, 10, 64)
- if err == nil && clen64 >= 0 {
- rws.sentContentLen = clen64
- } else {
- clen = ""
- }
- }
- if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
- clen = strconv.Itoa(len(p))
- }
- _, hasContentType := rws.snapHeader["Content-Type"]
- if !hasContentType && bodyAllowedForStatus(rws.status) {
- ctype = http.DetectContentType(p)
- }
- var date string
- if _, ok := rws.snapHeader["Date"]; !ok {
- // TODO(bradfitz): be faster here, like net/http? measure.
- date = time.Now().UTC().Format(http.TimeFormat)
- }
-
- for _, v := range rws.snapHeader["Trailer"] {
- foreachHeaderElement(v, rws.declareTrailer)
- }
-
- endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
- err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
- streamID: rws.stream.id,
- httpResCode: rws.status,
- h: rws.snapHeader,
- endStream: endStream,
- contentType: ctype,
- contentLength: clen,
- date: date,
- })
- if err != nil {
- return 0, err
- }
- if endStream {
- return 0, nil
- }
- }
- if isHeadResp {
- return len(p), nil
- }
- if len(p) == 0 && !rws.handlerDone {
- return 0, nil
- }
-
- if rws.handlerDone {
- rws.promoteUndeclaredTrailers()
- }
-
- endStream := rws.handlerDone && !rws.hasTrailers()
- if len(p) > 0 || endStream {
- // only send a 0 byte DATA frame if we're ending the stream.
- if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
- return 0, err
- }
- }
-
- if rws.handlerDone && rws.hasTrailers() {
- err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
- streamID: rws.stream.id,
- h: rws.handlerHeader,
- trailers: rws.trailers,
- endStream: true,
- })
- return len(p), err
- }
- return len(p), nil
-}
-
-// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
-// that, if present, signals that the map entry is actually for
-// the response trailers, and not the response headers. The prefix
-// is stripped after the ServeHTTP call finishes and the values are
-// sent in the trailers.
-//
-// This mechanism is intended only for trailers that are not known
-// prior to the headers being written. If the set of trailers is fixed
-// or known before the header is written, the normal Go trailers mechanism
-// is preferred:
-// https://golang.org/pkg/net/http/#ResponseWriter
-// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
-const TrailerPrefix = "Trailer:"
-
-// promoteUndeclaredTrailers permits http.Handlers to set trailers
-// after the header has already been flushed. Because the Go
-// ResponseWriter interface has no way to set Trailers (only the
-// Header), and because we didn't want to expand the ResponseWriter
-// interface, and because nobody used trailers, and because RFC 2616
-// says you SHOULD (but not must) predeclare any trailers in the
-// header, the official ResponseWriter rules said trailers in Go must
-// be predeclared, and then we reuse the same ResponseWriter.Header()
-// map to mean both Headers and Trailers. When it's time to write the
-// Trailers, we pick out the fields of Headers that were declared as
-// trailers. That worked for a while, until we found the first major
-// user of Trailers in the wild: gRPC (using them only over http2),
-// and gRPC libraries permit setting trailers mid-stream without
-// predeclarnig them. So: change of plans. We still permit the old
-// way, but we also permit this hack: if a Header() key begins with
-// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
-// invalid token byte anyway, there is no ambiguity. (And it's already
-// filtered out) It's mildly hacky, but not terrible.
-//
-// This method runs after the Handler is done and promotes any Header
-// fields to be trailers.
-func (rws *responseWriterState) promoteUndeclaredTrailers() {
- for k, vv := range rws.handlerHeader {
- if !strings.HasPrefix(k, TrailerPrefix) {
- continue
- }
- trailerKey := strings.TrimPrefix(k, TrailerPrefix)
- rws.declareTrailer(trailerKey)
- rws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv
- }
- sort.Strings(rws.trailers)
-}
-
-func (w *responseWriter) Flush() {
- rws := w.rws
- if rws == nil {
- panic("Header called after Handler finished")
- }
- if rws.bw.Buffered() > 0 {
- if err := rws.bw.Flush(); err != nil {
- // Ignore the error. The frame writer already knows.
- return
- }
- } else {
- // The bufio.Writer won't call chunkWriter.Write
- // (writeChunk with zero bytes, so we have to do it
- // ourselves to force the HTTP response header and/or
- // final DATA frame (with END_STREAM) to be sent.
- rws.writeChunk(nil)
- }
-}
-
-func (w *responseWriter) CloseNotify() <-chan bool {
- rws := w.rws
- if rws == nil {
- panic("CloseNotify called after Handler finished")
- }
- rws.closeNotifierMu.Lock()
- ch := rws.closeNotifierCh
- if ch == nil {
- ch = make(chan bool, 1)
- rws.closeNotifierCh = ch
- go func() {
- rws.stream.cw.Wait() // wait for close
- ch <- true
- }()
- }
- rws.closeNotifierMu.Unlock()
- return ch
-}
-
-func (w *responseWriter) Header() http.Header {
- rws := w.rws
- if rws == nil {
- panic("Header called after Handler finished")
- }
- if rws.handlerHeader == nil {
- rws.handlerHeader = make(http.Header)
- }
- return rws.handlerHeader
-}
-
-func (w *responseWriter) WriteHeader(code int) {
- rws := w.rws
- if rws == nil {
- panic("WriteHeader called after Handler finished")
- }
- rws.writeHeader(code)
-}
-
-func (rws *responseWriterState) writeHeader(code int) {
- if !rws.wroteHeader {
- rws.wroteHeader = true
- rws.status = code
- if len(rws.handlerHeader) > 0 {
- rws.snapHeader = cloneHeader(rws.handlerHeader)
- }
- }
-}
-
-func cloneHeader(h http.Header) http.Header {
- h2 := make(http.Header, len(h))
- for k, vv := range h {
- vv2 := make([]string, len(vv))
- copy(vv2, vv)
- h2[k] = vv2
- }
- return h2
-}
-
-// The Life Of A Write is like this:
-//
-// * Handler calls w.Write or w.WriteString ->
-// * -> rws.bw (*bufio.Writer) ->
-// * (Handler migth call Flush)
-// * -> chunkWriter{rws}
-// * -> responseWriterState.writeChunk(p []byte)
-// * -> responseWriterState.writeChunk (most of the magic; see comment there)
-func (w *responseWriter) Write(p []byte) (n int, err error) {
- return w.write(len(p), p, "")
-}
-
-func (w *responseWriter) WriteString(s string) (n int, err error) {
- return w.write(len(s), nil, s)
-}
-
-// either dataB or dataS is non-zero.
-func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) {
- rws := w.rws
- if rws == nil {
- panic("Write called after Handler finished")
- }
- if !rws.wroteHeader {
- w.WriteHeader(200)
- }
- if !bodyAllowedForStatus(rws.status) {
- return 0, http.ErrBodyNotAllowed
- }
- rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set
- if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {
- // TODO: send a RST_STREAM
- return 0, errors.New("http2: handler wrote more than declared Content-Length")
- }
-
- if dataB != nil {
- return rws.bw.Write(dataB)
- } else {
- return rws.bw.WriteString(dataS)
- }
-}
-
-func (w *responseWriter) handlerDone() {
- rws := w.rws
- rws.handlerDone = true
- w.Flush()
- w.rws = nil
- responseWriterStatePool.Put(rws)
-}
-
-// foreachHeaderElement splits v according to the "#rule" construction
-// in RFC 2616 section 2.1 and calls fn for each non-empty element.
-func foreachHeaderElement(v string, fn func(string)) {
- v = textproto.TrimString(v)
- if v == "" {
- return
- }
- if !strings.Contains(v, ",") {
- fn(v)
- return
- }
- for _, f := range strings.Split(v, ",") {
- if f = textproto.TrimString(f); f != "" {
- fn(f)
- }
- }
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/transport.go b/kube2msb/src/vendor/golang.org/x/net/http2/transport.go
deleted file mode 100644
index c3a1bdb..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/transport.go
+++ /dev/null
@@ -1,1750 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Transport code.
-
-package http2
-
-import (
- "bufio"
- "bytes"
- "compress/gzip"
- "crypto/tls"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "net"
- "net/http"
- "sort"
- "strconv"
- "strings"
- "sync"
- "time"
-
- "golang.org/x/net/http2/hpack"
-)
-
-const (
- // transportDefaultConnFlow is how many connection-level flow control
- // tokens we give the server at start-up, past the default 64k.
- transportDefaultConnFlow = 1 << 30
-
- // transportDefaultStreamFlow is how many stream-level flow
- // control tokens we announce to the peer, and how many bytes
- // we buffer per stream.
- transportDefaultStreamFlow = 4 << 20
-
- // transportDefaultStreamMinRefresh is the minimum number of bytes we'll send
- // a stream-level WINDOW_UPDATE for at a time.
- transportDefaultStreamMinRefresh = 4 << 10
-
- defaultUserAgent = "Go-http-client/2.0"
-)
-
-// Transport is an HTTP/2 Transport.
-//
-// A Transport internally caches connections to servers. It is safe
-// for concurrent use by multiple goroutines.
-type Transport struct {
- // DialTLS specifies an optional dial function for creating
- // TLS connections for requests.
- //
- // If DialTLS is nil, tls.Dial is used.
- //
- // If the returned net.Conn has a ConnectionState method like tls.Conn,
- // it will be used to set http.Response.TLS.
- DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)
-
- // TLSClientConfig specifies the TLS configuration to use with
- // tls.Client. If nil, the default configuration is used.
- TLSClientConfig *tls.Config
-
- // ConnPool optionally specifies an alternate connection pool to use.
- // If nil, the default is used.
- ConnPool ClientConnPool
-
- // DisableCompression, if true, prevents the Transport from
- // requesting compression with an "Accept-Encoding: gzip"
- // request header when the Request contains no existing
- // Accept-Encoding value. If the Transport requests gzip on
- // its own and gets a gzipped response, it's transparently
- // decoded in the Response.Body. However, if the user
- // explicitly requested gzip it is not automatically
- // uncompressed.
- DisableCompression bool
-
- // MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to
- // send in the initial settings frame. It is how many bytes
- // of response headers are allow. Unlike the http2 spec, zero here
- // means to use a default limit (currently 10MB). If you actually
- // want to advertise an ulimited value to the peer, Transport
- // interprets the highest possible value here (0xffffffff or 1<<32-1)
- // to mean no limit.
- MaxHeaderListSize uint32
-
- // t1, if non-nil, is the standard library Transport using
- // this transport. Its settings are used (but not its
- // RoundTrip method, etc).
- t1 *http.Transport
-
- connPoolOnce sync.Once
- connPoolOrDef ClientConnPool // non-nil version of ConnPool
-}
-
-func (t *Transport) maxHeaderListSize() uint32 {
- if t.MaxHeaderListSize == 0 {
- return 10 << 20
- }
- if t.MaxHeaderListSize == 0xffffffff {
- return 0
- }
- return t.MaxHeaderListSize
-}
-
-func (t *Transport) disableCompression() bool {
- return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
-}
-
-var errTransportVersion = errors.New("http2: ConfigureTransport is only supported starting at Go 1.6")
-
-// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
-// It requires Go 1.6 or later and returns an error if the net/http package is too old
-// or if t1 has already been HTTP/2-enabled.
-func ConfigureTransport(t1 *http.Transport) error {
- _, err := configureTransport(t1) // in configure_transport.go (go1.6) or not_go16.go
- return err
-}
-
-func (t *Transport) connPool() ClientConnPool {
- t.connPoolOnce.Do(t.initConnPool)
- return t.connPoolOrDef
-}
-
-func (t *Transport) initConnPool() {
- if t.ConnPool != nil {
- t.connPoolOrDef = t.ConnPool
- } else {
- t.connPoolOrDef = &clientConnPool{t: t}
- }
-}
-
-// ClientConn is the state of a single HTTP/2 client connection to an
-// HTTP/2 server.
-type ClientConn struct {
- t *Transport
- tconn net.Conn // usually *tls.Conn, except specialized impls
- tlsState *tls.ConnectionState // nil only for specialized impls
-
- // readLoop goroutine fields:
- readerDone chan struct{} // closed on error
- readerErr error // set before readerDone is closed
-
- mu sync.Mutex // guards following
- cond *sync.Cond // hold mu; broadcast on flow/closed changes
- flow flow // our conn-level flow control quota (cs.flow is per stream)
- inflow flow // peer's conn-level flow control
- closed bool
- goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received
- streams map[uint32]*clientStream // client-initiated
- nextStreamID uint32
- bw *bufio.Writer
- br *bufio.Reader
- fr *Framer
- // Settings from peer:
- maxFrameSize uint32
- maxConcurrentStreams uint32
- initialWindowSize uint32
- hbuf bytes.Buffer // HPACK encoder writes into this
- henc *hpack.Encoder
- freeBuf [][]byte
-
- wmu sync.Mutex // held while writing; acquire AFTER mu if holding both
- werr error // first write error that has occurred
-}
-
-// clientStream is the state for a single HTTP/2 stream. One of these
-// is created for each Transport.RoundTrip call.
-type clientStream struct {
- cc *ClientConn
- req *http.Request
- ID uint32
- resc chan resAndError
- bufPipe pipe // buffered pipe with the flow-controlled response payload
- requestedGzip bool
-
- flow flow // guarded by cc.mu
- inflow flow // guarded by cc.mu
- bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read
- readErr error // sticky read error; owned by transportResponseBody.Read
- stopReqBody error // if non-nil, stop writing req body; guarded by cc.mu
-
- peerReset chan struct{} // closed on peer reset
- resetErr error // populated before peerReset is closed
-
- done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu
-
- // owned by clientConnReadLoop:
- pastHeaders bool // got HEADERS w/ END_HEADERS
- pastTrailers bool // got second HEADERS frame w/ END_HEADERS
-
- trailer http.Header // accumulated trailers
- resTrailer *http.Header // client's Response.Trailer
-}
-
-// awaitRequestCancel runs in its own goroutine and waits for the user
-// to either cancel a RoundTrip request (using the provided
-// Request.Cancel channel), or for the request to be done (any way it
-// might be removed from the cc.streams map: peer reset, successful
-// completion, TCP connection breakage, etc)
-func (cs *clientStream) awaitRequestCancel(cancel <-chan struct{}) {
- if cancel == nil {
- return
- }
- select {
- case <-cancel:
- cs.bufPipe.CloseWithError(errRequestCanceled)
- cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
- case <-cs.done:
- }
-}
-
-// checkReset reports any error sent in a RST_STREAM frame by the
-// server.
-func (cs *clientStream) checkReset() error {
- select {
- case <-cs.peerReset:
- return cs.resetErr
- default:
- return nil
- }
-}
-
-func (cs *clientStream) abortRequestBodyWrite(err error) {
- if err == nil {
- panic("nil error")
- }
- cc := cs.cc
- cc.mu.Lock()
- cs.stopReqBody = err
- cc.cond.Broadcast()
- cc.mu.Unlock()
-}
-
-type stickyErrWriter struct {
- w io.Writer
- err *error
-}
-
-func (sew stickyErrWriter) Write(p []byte) (n int, err error) {
- if *sew.err != nil {
- return 0, *sew.err
- }
- n, err = sew.w.Write(p)
- *sew.err = err
- return
-}
-
-var ErrNoCachedConn = errors.New("http2: no cached connection was available")
-
-// RoundTripOpt are options for the Transport.RoundTripOpt method.
-type RoundTripOpt struct {
- // OnlyCachedConn controls whether RoundTripOpt may
- // create a new TCP connection. If set true and
- // no cached connection is available, RoundTripOpt
- // will return ErrNoCachedConn.
- OnlyCachedConn bool
-}
-
-func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
- return t.RoundTripOpt(req, RoundTripOpt{})
-}
-
-// authorityAddr returns a given authority (a host/IP, or host:port / ip:port)
-// and returns a host:port. The port 443 is added if needed.
-func authorityAddr(authority string) (addr string) {
- if _, _, err := net.SplitHostPort(authority); err == nil {
- return authority
- }
- return net.JoinHostPort(authority, "443")
-}
-
-// RoundTripOpt is like RoundTrip, but takes options.
-func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
- if req.URL.Scheme != "https" {
- return nil, errors.New("http2: unsupported scheme")
- }
-
- addr := authorityAddr(req.URL.Host)
- for {
- cc, err := t.connPool().GetClientConn(req, addr)
- if err != nil {
- t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err)
- return nil, err
- }
- res, err := cc.RoundTrip(req)
- if shouldRetryRequest(req, err) {
- continue
- }
- if err != nil {
- t.vlogf("RoundTrip failure: %v", err)
- return nil, err
- }
- return res, nil
- }
-}
-
-// CloseIdleConnections closes any connections which were previously
-// connected from previous requests but are now sitting idle.
-// It does not interrupt any connections currently in use.
-func (t *Transport) CloseIdleConnections() {
- if cp, ok := t.connPool().(*clientConnPool); ok {
- cp.closeIdleConnections()
- }
-}
-
-var (
- errClientConnClosed = errors.New("http2: client conn is closed")
- errClientConnUnusable = errors.New("http2: client conn not usable")
-)
-
-func shouldRetryRequest(req *http.Request, err error) bool {
- // TODO: retry GET requests (no bodies) more aggressively, if shutdown
- // before response.
- return err == errClientConnUnusable
-}
-
-func (t *Transport) dialClientConn(addr string) (*ClientConn, error) {
- host, _, err := net.SplitHostPort(addr)
- if err != nil {
- return nil, err
- }
- tconn, err := t.dialTLS()("tcp", addr, t.newTLSConfig(host))
- if err != nil {
- return nil, err
- }
- return t.NewClientConn(tconn)
-}
-
-func (t *Transport) newTLSConfig(host string) *tls.Config {
- cfg := new(tls.Config)
- if t.TLSClientConfig != nil {
- *cfg = *t.TLSClientConfig
- }
- cfg.NextProtos = []string{NextProtoTLS} // TODO: don't override if already in list
- cfg.ServerName = host
- return cfg
-}
-
-func (t *Transport) dialTLS() func(string, string, *tls.Config) (net.Conn, error) {
- if t.DialTLS != nil {
- return t.DialTLS
- }
- return t.dialTLSDefault
-}
-
-func (t *Transport) dialTLSDefault(network, addr string, cfg *tls.Config) (net.Conn, error) {
- cn, err := tls.Dial(network, addr, cfg)
- if err != nil {
- return nil, err
- }
- if err := cn.Handshake(); err != nil {
- return nil, err
- }
- if !cfg.InsecureSkipVerify {
- if err := cn.VerifyHostname(cfg.ServerName); err != nil {
- return nil, err
- }
- }
- state := cn.ConnectionState()
- if p := state.NegotiatedProtocol; p != NextProtoTLS {
- return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS)
- }
- if !state.NegotiatedProtocolIsMutual {
- return nil, errors.New("http2: could not negotiate protocol mutually")
- }
- return cn, nil
-}
-
-// disableKeepAlives reports whether connections should be closed as
-// soon as possible after handling the first request.
-func (t *Transport) disableKeepAlives() bool {
- return t.t1 != nil && t.t1.DisableKeepAlives
-}
-
-func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
- if VerboseLogs {
- t.vlogf("http2: Transport creating client conn to %v", c.RemoteAddr())
- }
- if _, err := c.Write(clientPreface); err != nil {
- t.vlogf("client preface write error: %v", err)
- return nil, err
- }
-
- cc := &ClientConn{
- t: t,
- tconn: c,
- readerDone: make(chan struct{}),
- nextStreamID: 1,
- maxFrameSize: 16 << 10, // spec default
- initialWindowSize: 65535, // spec default
- maxConcurrentStreams: 1000, // "infinite", per spec. 1000 seems good enough.
- streams: make(map[uint32]*clientStream),
- }
- cc.cond = sync.NewCond(&cc.mu)
- cc.flow.add(int32(initialWindowSize))
-
- // TODO: adjust this writer size to account for frame size +
- // MTU + crypto/tls record padding.
- cc.bw = bufio.NewWriter(stickyErrWriter{c, &cc.werr})
- cc.br = bufio.NewReader(c)
- cc.fr = NewFramer(cc.bw, cc.br)
-
- // TODO: SetMaxDynamicTableSize, SetMaxDynamicTableSizeLimit on
- // henc in response to SETTINGS frames?
- cc.henc = hpack.NewEncoder(&cc.hbuf)
-
- if cs, ok := c.(connectionStater); ok {
- state := cs.ConnectionState()
- cc.tlsState = &state
- }
-
- initialSettings := []Setting{
- Setting{ID: SettingEnablePush, Val: 0},
- Setting{ID: SettingInitialWindowSize, Val: transportDefaultStreamFlow},
- }
- if max := t.maxHeaderListSize(); max != 0 {
- initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max})
- }
- cc.fr.WriteSettings(initialSettings...)
- cc.fr.WriteWindowUpdate(0, transportDefaultConnFlow)
- cc.inflow.add(transportDefaultConnFlow + initialWindowSize)
- cc.bw.Flush()
- if cc.werr != nil {
- return nil, cc.werr
- }
-
- // Read the obligatory SETTINGS frame
- f, err := cc.fr.ReadFrame()
- if err != nil {
- return nil, err
- }
- sf, ok := f.(*SettingsFrame)
- if !ok {
- return nil, fmt.Errorf("expected settings frame, got: %T", f)
- }
- cc.fr.WriteSettingsAck()
- cc.bw.Flush()
-
- sf.ForeachSetting(func(s Setting) error {
- switch s.ID {
- case SettingMaxFrameSize:
- cc.maxFrameSize = s.Val
- case SettingMaxConcurrentStreams:
- cc.maxConcurrentStreams = s.Val
- case SettingInitialWindowSize:
- cc.initialWindowSize = s.Val
- default:
- // TODO(bradfitz): handle more; at least SETTINGS_HEADER_TABLE_SIZE?
- t.vlogf("Unhandled Setting: %v", s)
- }
- return nil
- })
-
- go cc.readLoop()
- return cc, nil
-}
-
-func (cc *ClientConn) setGoAway(f *GoAwayFrame) {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- cc.goAway = f
-}
-
-func (cc *ClientConn) CanTakeNewRequest() bool {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- return cc.canTakeNewRequestLocked()
-}
-
-func (cc *ClientConn) canTakeNewRequestLocked() bool {
- return cc.goAway == nil && !cc.closed &&
- int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) &&
- cc.nextStreamID < 2147483647
-}
-
-func (cc *ClientConn) closeIfIdle() {
- cc.mu.Lock()
- if len(cc.streams) > 0 {
- cc.mu.Unlock()
- return
- }
- cc.closed = true
- // TODO: do clients send GOAWAY too? maybe? Just Close:
- cc.mu.Unlock()
-
- cc.tconn.Close()
-}
-
-const maxAllocFrameSize = 512 << 10
-
-// frameBuffer returns a scratch buffer suitable for writing DATA frames.
-// They're capped at the min of the peer's max frame size or 512KB
-// (kinda arbitrarily), but definitely capped so we don't allocate 4GB
-// bufers.
-func (cc *ClientConn) frameScratchBuffer() []byte {
- cc.mu.Lock()
- size := cc.maxFrameSize
- if size > maxAllocFrameSize {
- size = maxAllocFrameSize
- }
- for i, buf := range cc.freeBuf {
- if len(buf) >= int(size) {
- cc.freeBuf[i] = nil
- cc.mu.Unlock()
- return buf[:size]
- }
- }
- cc.mu.Unlock()
- return make([]byte, size)
-}
-
-func (cc *ClientConn) putFrameScratchBuffer(buf []byte) {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- const maxBufs = 4 // arbitrary; 4 concurrent requests per conn? investigate.
- if len(cc.freeBuf) < maxBufs {
- cc.freeBuf = append(cc.freeBuf, buf)
- return
- }
- for i, old := range cc.freeBuf {
- if old == nil {
- cc.freeBuf[i] = buf
- return
- }
- }
- // forget about it.
-}
-
-// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
-// exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests.
-var errRequestCanceled = errors.New("net/http: request canceled")
-
-func commaSeparatedTrailers(req *http.Request) (string, error) {
- keys := make([]string, 0, len(req.Trailer))
- for k := range req.Trailer {
- k = http.CanonicalHeaderKey(k)
- switch k {
- case "Transfer-Encoding", "Trailer", "Content-Length":
- return "", &badStringError{"invalid Trailer key", k}
- }
- keys = append(keys, k)
- }
- if len(keys) > 0 {
- sort.Strings(keys)
- // TODO: could do better allocation-wise here, but trailers are rare,
- // so being lazy for now.
- return strings.Join(keys, ","), nil
- }
- return "", nil
-}
-
-func (cc *ClientConn) responseHeaderTimeout() time.Duration {
- if cc.t.t1 != nil {
- return cc.t.t1.ResponseHeaderTimeout
- }
- // No way to do this (yet?) with just an http2.Transport. Probably
- // no need. Request.Cancel this is the new way. We only need to support
- // this for compatibility with the old http.Transport fields when
- // we're doing transparent http2.
- return 0
-}
-
-// checkConnHeaders checks whether req has any invalid connection-level headers.
-// per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields.
-// Certain headers are special-cased as okay but not transmitted later.
-func checkConnHeaders(req *http.Request) error {
- if v := req.Header.Get("Upgrade"); v != "" {
- return errors.New("http2: invalid Upgrade request header")
- }
- if v := req.Header.Get("Transfer-Encoding"); (v != "" && v != "chunked") || len(req.Header["Transfer-Encoding"]) > 1 {
- return errors.New("http2: invalid Transfer-Encoding request header")
- }
- if v := req.Header.Get("Connection"); (v != "" && v != "close" && v != "keep-alive") || len(req.Header["Connection"]) > 1 {
- return errors.New("http2: invalid Connection request header")
- }
- return nil
-}
-
-func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
- if err := checkConnHeaders(req); err != nil {
- return nil, err
- }
-
- trailers, err := commaSeparatedTrailers(req)
- if err != nil {
- return nil, err
- }
- hasTrailers := trailers != ""
-
- var body io.Reader = req.Body
- contentLen := req.ContentLength
- if req.Body != nil && contentLen == 0 {
- // Test to see if it's actually zero or just unset.
- var buf [1]byte
- n, rerr := io.ReadFull(body, buf[:])
- if rerr != nil && rerr != io.EOF {
- contentLen = -1
- body = errorReader{rerr}
- } else if n == 1 {
- // Oh, guess there is data in this Body Reader after all.
- // The ContentLength field just wasn't set.
- // Stich the Body back together again, re-attaching our
- // consumed byte.
- contentLen = -1
- body = io.MultiReader(bytes.NewReader(buf[:]), body)
- } else {
- // Body is actually empty.
- body = nil
- }
- }
-
- cc.mu.Lock()
- if cc.closed || !cc.canTakeNewRequestLocked() {
- cc.mu.Unlock()
- return nil, errClientConnUnusable
- }
-
- cs := cc.newStream()
- cs.req = req
- hasBody := body != nil
-
- // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
- if !cc.t.disableCompression() &&
- req.Header.Get("Accept-Encoding") == "" &&
- req.Header.Get("Range") == "" &&
- req.Method != "HEAD" {
- // Request gzip only, not deflate. Deflate is ambiguous and
- // not as universally supported anyway.
- // See: http://www.gzip.org/zlib/zlib_faq.html#faq38
- //
- // Note that we don't request this for HEAD requests,
- // due to a bug in nginx:
- // http://trac.nginx.org/nginx/ticket/358
- // https://golang.org/issue/5522
- //
- // We don't request gzip if the request is for a range, since
- // auto-decoding a portion of a gzipped document will just fail
- // anyway. See https://golang.org/issue/8923
- cs.requestedGzip = true
- }
-
- // we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is
- // sent by writeRequestBody below, along with any Trailers,
- // again in form HEADERS{1}, CONTINUATION{0,})
- hdrs := cc.encodeHeaders(req, cs.requestedGzip, trailers, contentLen)
- cc.wmu.Lock()
- endStream := !hasBody && !hasTrailers
- werr := cc.writeHeaders(cs.ID, endStream, hdrs)
- cc.wmu.Unlock()
- cc.mu.Unlock()
-
- if werr != nil {
- if hasBody {
- req.Body.Close() // per RoundTripper contract
- }
- cc.forgetStreamID(cs.ID)
- // Don't bother sending a RST_STREAM (our write already failed;
- // no need to keep writing)
- return nil, werr
- }
-
- var respHeaderTimer <-chan time.Time
- var bodyCopyErrc chan error // result of body copy
- if hasBody {
- bodyCopyErrc = make(chan error, 1)
- go func() {
- bodyCopyErrc <- cs.writeRequestBody(body, req.Body)
- }()
- } else {
- if d := cc.responseHeaderTimeout(); d != 0 {
- timer := time.NewTimer(d)
- defer timer.Stop()
- respHeaderTimer = timer.C
- }
- }
-
- readLoopResCh := cs.resc
- requestCanceledCh := requestCancel(req)
- bodyWritten := false
-
- for {
- select {
- case re := <-readLoopResCh:
- res := re.res
- if re.err != nil || res.StatusCode > 299 {
- // On error or status code 3xx, 4xx, 5xx, etc abort any
- // ongoing write, assuming that the server doesn't care
- // about our request body. If the server replied with 1xx or
- // 2xx, however, then assume the server DOES potentially
- // want our body (e.g. full-duplex streaming:
- // golang.org/issue/13444). If it turns out the server
- // doesn't, they'll RST_STREAM us soon enough. This is a
- // heuristic to avoid adding knobs to Transport. Hopefully
- // we can keep it.
- cs.abortRequestBodyWrite(errStopReqBodyWrite)
- }
- if re.err != nil {
- cc.forgetStreamID(cs.ID)
- return nil, re.err
- }
- res.Request = req
- res.TLS = cc.tlsState
- return res, nil
- case <-respHeaderTimer:
- cc.forgetStreamID(cs.ID)
- if !hasBody || bodyWritten {
- cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
- } else {
- cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel)
- }
- return nil, errTimeout
- case <-requestCanceledCh:
- cc.forgetStreamID(cs.ID)
- if !hasBody || bodyWritten {
- cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
- } else {
- cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel)
- }
- return nil, errRequestCanceled
- case <-cs.peerReset:
- // processResetStream already removed the
- // stream from the streams map; no need for
- // forgetStreamID.
- return nil, cs.resetErr
- case err := <-bodyCopyErrc:
- if err != nil {
- return nil, err
- }
- bodyWritten = true
- if d := cc.responseHeaderTimeout(); d != 0 {
- timer := time.NewTimer(d)
- defer timer.Stop()
- respHeaderTimer = timer.C
- }
- }
- }
-}
-
-// requires cc.wmu be held
-func (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, hdrs []byte) error {
- first := true // first frame written (HEADERS is first, then CONTINUATION)
- frameSize := int(cc.maxFrameSize)
- for len(hdrs) > 0 && cc.werr == nil {
- chunk := hdrs
- if len(chunk) > frameSize {
- chunk = chunk[:frameSize]
- }
- hdrs = hdrs[len(chunk):]
- endHeaders := len(hdrs) == 0
- if first {
- cc.fr.WriteHeaders(HeadersFrameParam{
- StreamID: streamID,
- BlockFragment: chunk,
- EndStream: endStream,
- EndHeaders: endHeaders,
- })
- first = false
- } else {
- cc.fr.WriteContinuation(streamID, endHeaders, chunk)
- }
- }
- // TODO(bradfitz): this Flush could potentially block (as
- // could the WriteHeaders call(s) above), which means they
- // wouldn't respond to Request.Cancel being readable. That's
- // rare, but this should probably be in a goroutine.
- cc.bw.Flush()
- return cc.werr
-}
-
-// internal error values; they don't escape to callers
-var (
- // abort request body write; don't send cancel
- errStopReqBodyWrite = errors.New("http2: aborting request body write")
-
- // abort request body write, but send stream reset of cancel.
- errStopReqBodyWriteAndCancel = errors.New("http2: canceling request")
-)
-
-func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (err error) {
- cc := cs.cc
- sentEnd := false // whether we sent the final DATA frame w/ END_STREAM
- buf := cc.frameScratchBuffer()
- defer cc.putFrameScratchBuffer(buf)
-
- defer func() {
- // TODO: write h12Compare test showing whether
- // Request.Body is closed by the Transport,
- // and in multiple cases: server replies <=299 and >299
- // while still writing request body
- cerr := bodyCloser.Close()
- if err == nil {
- err = cerr
- }
- }()
-
- req := cs.req
- hasTrailers := req.Trailer != nil
-
- var sawEOF bool
- for !sawEOF {
- n, err := body.Read(buf)
- if err == io.EOF {
- sawEOF = true
- err = nil
- } else if err != nil {
- return err
- }
-
- remain := buf[:n]
- for len(remain) > 0 && err == nil {
- var allowed int32
- allowed, err = cs.awaitFlowControl(len(remain))
- switch {
- case err == errStopReqBodyWrite:
- return err
- case err == errStopReqBodyWriteAndCancel:
- cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
- return err
- case err != nil:
- return err
- }
- cc.wmu.Lock()
- data := remain[:allowed]
- remain = remain[allowed:]
- sentEnd = sawEOF && len(remain) == 0 && !hasTrailers
- err = cc.fr.WriteData(cs.ID, sentEnd, data)
- if err == nil {
- // TODO(bradfitz): this flush is for latency, not bandwidth.
- // Most requests won't need this. Make this opt-in or opt-out?
- // Use some heuristic on the body type? Nagel-like timers?
- // Based on 'n'? Only last chunk of this for loop, unless flow control
- // tokens are low? For now, always:
- err = cc.bw.Flush()
- }
- cc.wmu.Unlock()
- }
- if err != nil {
- return err
- }
- }
-
- cc.wmu.Lock()
- if !sentEnd {
- var trls []byte
- if hasTrailers {
- cc.mu.Lock()
- trls = cc.encodeTrailers(req)
- cc.mu.Unlock()
- }
-
- // Avoid forgetting to send an END_STREAM if the encoded
- // trailers are 0 bytes. Both results produce and END_STREAM.
- if len(trls) > 0 {
- err = cc.writeHeaders(cs.ID, true, trls)
- } else {
- err = cc.fr.WriteData(cs.ID, true, nil)
- }
- }
- if ferr := cc.bw.Flush(); ferr != nil && err == nil {
- err = ferr
- }
- cc.wmu.Unlock()
-
- return err
-}
-
-// awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow
-// control tokens from the server.
-// It returns either the non-zero number of tokens taken or an error
-// if the stream is dead.
-func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) {
- cc := cs.cc
- cc.mu.Lock()
- defer cc.mu.Unlock()
- for {
- if cc.closed {
- return 0, errClientConnClosed
- }
- if cs.stopReqBody != nil {
- return 0, cs.stopReqBody
- }
- if err := cs.checkReset(); err != nil {
- return 0, err
- }
- if a := cs.flow.available(); a > 0 {
- take := a
- if int(take) > maxBytes {
-
- take = int32(maxBytes) // can't truncate int; take is int32
- }
- if take > int32(cc.maxFrameSize) {
- take = int32(cc.maxFrameSize)
- }
- cs.flow.take(take)
- return take, nil
- }
- cc.cond.Wait()
- }
-}
-
-type badStringError struct {
- what string
- str string
-}
-
-func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
-
-// requires cc.mu be held.
-func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) []byte {
- cc.hbuf.Reset()
-
- host := req.Host
- if host == "" {
- host = req.URL.Host
- }
-
- // 8.1.2.3 Request Pseudo-Header Fields
- // The :path pseudo-header field includes the path and query parts of the
- // target URI (the path-absolute production and optionally a '?' character
- // followed by the query production (see Sections 3.3 and 3.4 of
- // [RFC3986]).
- cc.writeHeader(":authority", host)
- cc.writeHeader(":method", req.Method)
- if req.Method != "CONNECT" {
- cc.writeHeader(":path", req.URL.RequestURI())
- cc.writeHeader(":scheme", "https")
- }
- if trailers != "" {
- cc.writeHeader("trailer", trailers)
- }
-
- var didUA bool
- for k, vv := range req.Header {
- lowKey := strings.ToLower(k)
- switch lowKey {
- case "host", "content-length":
- // Host is :authority, already sent.
- // Content-Length is automatic, set below.
- continue
- case "connection", "proxy-connection", "transfer-encoding", "upgrade":
- // Per 8.1.2.2 Connection-Specific Header
- // Fields, don't send connection-specific
- // fields. We deal with these earlier in
- // RoundTrip, deciding whether they're
- // error-worthy, but we don't want to mutate
- // the user's *Request so at this point, just
- // skip over them at this point.
- continue
- case "user-agent":
- // Match Go's http1 behavior: at most one
- // User-Agent. If set to nil or empty string,
- // then omit it. Otherwise if not mentioned,
- // include the default (below).
- didUA = true
- if len(vv) < 1 {
- continue
- }
- vv = vv[:1]
- if vv[0] == "" {
- continue
- }
- }
- for _, v := range vv {
- cc.writeHeader(lowKey, v)
- }
- }
- if shouldSendReqContentLength(req.Method, contentLength) {
- cc.writeHeader("content-length", strconv.FormatInt(contentLength, 10))
- }
- if addGzipHeader {
- cc.writeHeader("accept-encoding", "gzip")
- }
- if !didUA {
- cc.writeHeader("user-agent", defaultUserAgent)
- }
- return cc.hbuf.Bytes()
-}
-
-// shouldSendReqContentLength reports whether the http2.Transport should send
-// a "content-length" request header. This logic is basically a copy of the net/http
-// transferWriter.shouldSendContentLength.
-// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown).
-// -1 means unknown.
-func shouldSendReqContentLength(method string, contentLength int64) bool {
- if contentLength > 0 {
- return true
- }
- if contentLength < 0 {
- return false
- }
- // For zero bodies, whether we send a content-length depends on the method.
- // It also kinda doesn't matter for http2 either way, with END_STREAM.
- switch method {
- case "POST", "PUT", "PATCH":
- return true
- default:
- return false
- }
-}
-
-// requires cc.mu be held.
-func (cc *ClientConn) encodeTrailers(req *http.Request) []byte {
- cc.hbuf.Reset()
- for k, vv := range req.Trailer {
- // Transfer-Encoding, etc.. have already been filter at the
- // start of RoundTrip
- lowKey := strings.ToLower(k)
- for _, v := range vv {
- cc.writeHeader(lowKey, v)
- }
- }
- return cc.hbuf.Bytes()
-}
-
-func (cc *ClientConn) writeHeader(name, value string) {
- if VerboseLogs {
- log.Printf("http2: Transport encoding header %q = %q", name, value)
- }
- cc.henc.WriteField(hpack.HeaderField{Name: name, Value: value})
-}
-
-type resAndError struct {
- res *http.Response
- err error
-}
-
-// requires cc.mu be held.
-func (cc *ClientConn) newStream() *clientStream {
- cs := &clientStream{
- cc: cc,
- ID: cc.nextStreamID,
- resc: make(chan resAndError, 1),
- peerReset: make(chan struct{}),
- done: make(chan struct{}),
- }
- cs.flow.add(int32(cc.initialWindowSize))
- cs.flow.setConnFlow(&cc.flow)
- cs.inflow.add(transportDefaultStreamFlow)
- cs.inflow.setConnFlow(&cc.inflow)
- cc.nextStreamID += 2
- cc.streams[cs.ID] = cs
- return cs
-}
-
-func (cc *ClientConn) forgetStreamID(id uint32) {
- cc.streamByID(id, true)
-}
-
-func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- cs := cc.streams[id]
- if andRemove && cs != nil && !cc.closed {
- delete(cc.streams, id)
- close(cs.done)
- }
- return cs
-}
-
-// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
-type clientConnReadLoop struct {
- cc *ClientConn
- activeRes map[uint32]*clientStream // keyed by streamID
- closeWhenIdle bool
-
- hdec *hpack.Decoder
-
- // Fields reset on each HEADERS:
- nextRes *http.Response
- sawRegHeader bool // saw non-pseudo header
- reqMalformed error // non-nil once known to be malformed
- lastHeaderEndsStream bool
- headerListSize int64 // actually uint32, but easier math this way
-}
-
-// readLoop runs in its own goroutine and reads and dispatches frames.
-func (cc *ClientConn) readLoop() {
- rl := &clientConnReadLoop{
- cc: cc,
- activeRes: make(map[uint32]*clientStream),
- }
- rl.hdec = hpack.NewDecoder(initialHeaderTableSize, rl.onNewHeaderField)
-
- defer rl.cleanup()
- cc.readerErr = rl.run()
- if ce, ok := cc.readerErr.(ConnectionError); ok {
- cc.wmu.Lock()
- cc.fr.WriteGoAway(0, ErrCode(ce), nil)
- cc.wmu.Unlock()
- }
-}
-
-func (rl *clientConnReadLoop) cleanup() {
- cc := rl.cc
- defer cc.tconn.Close()
- defer cc.t.connPool().MarkDead(cc)
- defer close(cc.readerDone)
-
- // Close any response bodies if the server closes prematurely.
- // TODO: also do this if we've written the headers but not
- // gotten a response yet.
- err := cc.readerErr
- if err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- cc.mu.Lock()
- for _, cs := range rl.activeRes {
- cs.bufPipe.CloseWithError(err)
- }
- for _, cs := range cc.streams {
- select {
- case cs.resc <- resAndError{err: err}:
- default:
- }
- close(cs.done)
- }
- cc.closed = true
- cc.cond.Broadcast()
- cc.mu.Unlock()
-}
-
-func (rl *clientConnReadLoop) run() error {
- cc := rl.cc
- rl.closeWhenIdle = cc.t.disableKeepAlives()
- gotReply := false // ever saw a reply
- for {
- f, err := cc.fr.ReadFrame()
- if err != nil {
- cc.vlogf("Transport readFrame error: (%T) %v", err, err)
- }
- if se, ok := err.(StreamError); ok {
- // TODO: deal with stream errors from the framer.
- return se
- } else if err != nil {
- return err
- }
- if VerboseLogs {
- cc.vlogf("http2: Transport received %s", summarizeFrame(f))
- }
- maybeIdle := false // whether frame might transition us to idle
-
- switch f := f.(type) {
- case *HeadersFrame:
- err = rl.processHeaders(f)
- maybeIdle = true
- gotReply = true
- case *ContinuationFrame:
- err = rl.processContinuation(f)
- maybeIdle = true
- case *DataFrame:
- err = rl.processData(f)
- maybeIdle = true
- case *GoAwayFrame:
- err = rl.processGoAway(f)
- maybeIdle = true
- case *RSTStreamFrame:
- err = rl.processResetStream(f)
- maybeIdle = true
- case *SettingsFrame:
- err = rl.processSettings(f)
- case *PushPromiseFrame:
- err = rl.processPushPromise(f)
- case *WindowUpdateFrame:
- err = rl.processWindowUpdate(f)
- case *PingFrame:
- err = rl.processPing(f)
- default:
- cc.logf("Transport: unhandled response frame type %T", f)
- }
- if err != nil {
- return err
- }
- if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 {
- cc.closeIfIdle()
- }
- }
-}
-
-func (rl *clientConnReadLoop) processHeaders(f *HeadersFrame) error {
- rl.sawRegHeader = false
- rl.reqMalformed = nil
- rl.lastHeaderEndsStream = f.StreamEnded()
- rl.headerListSize = 0
- rl.nextRes = &http.Response{
- Proto: "HTTP/2.0",
- ProtoMajor: 2,
- Header: make(http.Header),
- }
- rl.hdec.SetEmitEnabled(true)
- return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded())
-}
-
-func (rl *clientConnReadLoop) processContinuation(f *ContinuationFrame) error {
- return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded())
-}
-
-func (rl *clientConnReadLoop) processHeaderBlockFragment(frag []byte, streamID uint32, finalFrag bool) error {
- cc := rl.cc
- streamEnded := rl.lastHeaderEndsStream
- cs := cc.streamByID(streamID, streamEnded && finalFrag)
- if cs == nil {
- // We'd get here if we canceled a request while the
- // server was mid-way through replying with its
- // headers. (The case of a CONTINUATION arriving
- // without HEADERS would be rejected earlier by the
- // Framer). So if this was just something we canceled,
- // ignore it.
- return nil
- }
- if cs.pastHeaders {
- rl.hdec.SetEmitFunc(func(f hpack.HeaderField) { rl.onNewTrailerField(cs, f) })
- } else {
- rl.hdec.SetEmitFunc(rl.onNewHeaderField)
- }
- _, err := rl.hdec.Write(frag)
- if err != nil {
- return ConnectionError(ErrCodeCompression)
- }
- if finalFrag {
- if err := rl.hdec.Close(); err != nil {
- return ConnectionError(ErrCodeCompression)
- }
- }
-
- if !finalFrag {
- return nil
- }
-
- if !cs.pastHeaders {
- cs.pastHeaders = true
- } else {
- // We're dealing with trailers. (and specifically the
- // final frame of headers)
- if cs.pastTrailers {
- // Too many HEADERS frames for this stream.
- return ConnectionError(ErrCodeProtocol)
- }
- cs.pastTrailers = true
- if !streamEnded {
- // We expect that any header block fragment
- // frame for trailers with END_HEADERS also
- // has END_STREAM.
- return ConnectionError(ErrCodeProtocol)
- }
- rl.endStream(cs)
- return nil
- }
-
- if rl.reqMalformed != nil {
- cs.resc <- resAndError{err: rl.reqMalformed}
- rl.cc.writeStreamReset(cs.ID, ErrCodeProtocol, rl.reqMalformed)
- return nil
- }
-
- res := rl.nextRes
-
- if res.StatusCode == 100 {
- // Just skip 100-continue response headers for now.
- // TODO: golang.org/issue/13851 for doing it properly.
- cs.pastHeaders = false // do it all again
- return nil
- }
-
- if !streamEnded || cs.req.Method == "HEAD" {
- res.ContentLength = -1
- if clens := res.Header["Content-Length"]; len(clens) == 1 {
- if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil {
- res.ContentLength = clen64
- } else {
- // TODO: care? unlike http/1, it won't mess up our framing, so it's
- // more safe smuggling-wise to ignore.
- }
- } else if len(clens) > 1 {
- // TODO: care? unlike http/1, it won't mess up our framing, so it's
- // more safe smuggling-wise to ignore.
- }
- }
-
- if streamEnded {
- res.Body = noBody
- } else {
- buf := new(bytes.Buffer) // TODO(bradfitz): recycle this garbage
- cs.bufPipe = pipe{b: buf}
- cs.bytesRemain = res.ContentLength
- res.Body = transportResponseBody{cs}
- go cs.awaitRequestCancel(requestCancel(cs.req))
-
- if cs.requestedGzip && res.Header.Get("Content-Encoding") == "gzip" {
- res.Header.Del("Content-Encoding")
- res.Header.Del("Content-Length")
- res.ContentLength = -1
- res.Body = &gzipReader{body: res.Body}
- }
- rl.activeRes[cs.ID] = cs
- }
-
- cs.resTrailer = &res.Trailer
- cs.resc <- resAndError{res: res}
- rl.nextRes = nil // unused now; will be reset next HEADERS frame
- return nil
-}
-
-// transportResponseBody is the concrete type of Transport.RoundTrip's
-// Response.Body. It is an io.ReadCloser. On Read, it reads from cs.body.
-// On Close it sends RST_STREAM if EOF wasn't already seen.
-type transportResponseBody struct {
- cs *clientStream
-}
-
-func (b transportResponseBody) Read(p []byte) (n int, err error) {
- cs := b.cs
- cc := cs.cc
-
- if cs.readErr != nil {
- return 0, cs.readErr
- }
- n, err = b.cs.bufPipe.Read(p)
- if cs.bytesRemain != -1 {
- if int64(n) > cs.bytesRemain {
- n = int(cs.bytesRemain)
- if err == nil {
- err = errors.New("net/http: server replied with more than declared Content-Length; truncated")
- cc.writeStreamReset(cs.ID, ErrCodeProtocol, err)
- }
- cs.readErr = err
- return int(cs.bytesRemain), err
- }
- cs.bytesRemain -= int64(n)
- if err == io.EOF && cs.bytesRemain > 0 {
- err = io.ErrUnexpectedEOF
- cs.readErr = err
- return n, err
- }
- }
- if n == 0 {
- // No flow control tokens to send back.
- return
- }
-
- cc.mu.Lock()
- defer cc.mu.Unlock()
-
- var connAdd, streamAdd int32
- // Check the conn-level first, before the stream-level.
- if v := cc.inflow.available(); v < transportDefaultConnFlow/2 {
- connAdd = transportDefaultConnFlow - v
- cc.inflow.add(connAdd)
- }
- if err == nil { // No need to refresh if the stream is over or failed.
- if v := cs.inflow.available(); v < transportDefaultStreamFlow-transportDefaultStreamMinRefresh {
- streamAdd = transportDefaultStreamFlow - v
- cs.inflow.add(streamAdd)
- }
- }
- if connAdd != 0 || streamAdd != 0 {
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
- if connAdd != 0 {
- cc.fr.WriteWindowUpdate(0, mustUint31(connAdd))
- }
- if streamAdd != 0 {
- cc.fr.WriteWindowUpdate(cs.ID, mustUint31(streamAdd))
- }
- cc.bw.Flush()
- }
- return
-}
-
-var errClosedResponseBody = errors.New("http2: response body closed")
-
-func (b transportResponseBody) Close() error {
- cs := b.cs
- if cs.bufPipe.Err() != io.EOF {
- // TODO: write test for this
- cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
- }
- cs.bufPipe.BreakWithError(errClosedResponseBody)
- return nil
-}
-
-func (rl *clientConnReadLoop) processData(f *DataFrame) error {
- cc := rl.cc
- cs := cc.streamByID(f.StreamID, f.StreamEnded())
- if cs == nil {
- cc.mu.Lock()
- neverSent := cc.nextStreamID
- cc.mu.Unlock()
- if f.StreamID >= neverSent {
- // We never asked for this.
- cc.logf("http2: Transport received unsolicited DATA frame; closing connection")
- return ConnectionError(ErrCodeProtocol)
- }
- // We probably did ask for this, but canceled. Just ignore it.
- // TODO: be stricter here? only silently ignore things which
- // we canceled, but not things which were closed normally
- // by the peer? Tough without accumulating too much state.
- return nil
- }
- if data := f.Data(); len(data) > 0 {
- if cs.bufPipe.b == nil {
- // Data frame after it's already closed?
- cc.logf("http2: Transport received DATA frame for closed stream; closing connection")
- return ConnectionError(ErrCodeProtocol)
- }
-
- // Check connection-level flow control.
- cc.mu.Lock()
- if cs.inflow.available() >= int32(len(data)) {
- cs.inflow.take(int32(len(data)))
- } else {
- cc.mu.Unlock()
- return ConnectionError(ErrCodeFlowControl)
- }
- cc.mu.Unlock()
-
- if _, err := cs.bufPipe.Write(data); err != nil {
- return err
- }
- }
-
- if f.StreamEnded() {
- rl.endStream(cs)
- }
- return nil
-}
-
-var errInvalidTrailers = errors.New("http2: invalid trailers")
-
-func (rl *clientConnReadLoop) endStream(cs *clientStream) {
- // TODO: check that any declared content-length matches, like
- // server.go's (*stream).endStream method.
- err := io.EOF
- code := cs.copyTrailers
- if rl.reqMalformed != nil {
- err = rl.reqMalformed
- code = nil
- }
- cs.bufPipe.closeWithErrorAndCode(err, code)
- delete(rl.activeRes, cs.ID)
- if cs.req.Close || cs.req.Header.Get("Connection") == "close" {
- rl.closeWhenIdle = true
- }
-}
-
-func (cs *clientStream) copyTrailers() {
- for k, vv := range cs.trailer {
- t := cs.resTrailer
- if *t == nil {
- *t = make(http.Header)
- }
- (*t)[k] = vv
- }
-}
-
-func (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error {
- cc := rl.cc
- cc.t.connPool().MarkDead(cc)
- if f.ErrCode != 0 {
- // TODO: deal with GOAWAY more. particularly the error code
- cc.vlogf("transport got GOAWAY with error code = %v", f.ErrCode)
- }
- cc.setGoAway(f)
- return nil
-}
-
-func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error {
- cc := rl.cc
- cc.mu.Lock()
- defer cc.mu.Unlock()
- return f.ForeachSetting(func(s Setting) error {
- switch s.ID {
- case SettingMaxFrameSize:
- cc.maxFrameSize = s.Val
- case SettingMaxConcurrentStreams:
- cc.maxConcurrentStreams = s.Val
- case SettingInitialWindowSize:
- // TODO: error if this is too large.
-
- // TODO: adjust flow control of still-open
- // frames by the difference of the old initial
- // window size and this one.
- cc.initialWindowSize = s.Val
- default:
- // TODO(bradfitz): handle more settings? SETTINGS_HEADER_TABLE_SIZE probably.
- cc.vlogf("Unhandled Setting: %v", s)
- }
- return nil
- })
-}
-
-func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {
- cc := rl.cc
- cs := cc.streamByID(f.StreamID, false)
- if f.StreamID != 0 && cs == nil {
- return nil
- }
-
- cc.mu.Lock()
- defer cc.mu.Unlock()
-
- fl := &cc.flow
- if cs != nil {
- fl = &cs.flow
- }
- if !fl.add(int32(f.Increment)) {
- return ConnectionError(ErrCodeFlowControl)
- }
- cc.cond.Broadcast()
- return nil
-}
-
-func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error {
- cs := rl.cc.streamByID(f.StreamID, true)
- if cs == nil {
- // TODO: return error if server tries to RST_STEAM an idle stream
- return nil
- }
- select {
- case <-cs.peerReset:
- // Already reset.
- // This is the only goroutine
- // which closes this, so there
- // isn't a race.
- default:
- err := StreamError{cs.ID, f.ErrCode}
- cs.resetErr = err
- close(cs.peerReset)
- cs.bufPipe.CloseWithError(err)
- cs.cc.cond.Broadcast() // wake up checkReset via clientStream.awaitFlowControl
- }
- delete(rl.activeRes, cs.ID)
- return nil
-}
-
-func (rl *clientConnReadLoop) processPing(f *PingFrame) error {
- if f.IsAck() {
- // 6.7 PING: " An endpoint MUST NOT respond to PING frames
- // containing this flag."
- return nil
- }
- cc := rl.cc
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
- if err := cc.fr.WritePing(true, f.Data); err != nil {
- return err
- }
- return cc.bw.Flush()
-}
-
-func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error {
- // We told the peer we don't want them.
- // Spec says:
- // "PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH
- // setting of the peer endpoint is set to 0. An endpoint that
- // has set this setting and has received acknowledgement MUST
- // treat the receipt of a PUSH_PROMISE frame as a connection
- // error (Section 5.4.1) of type PROTOCOL_ERROR."
- return ConnectionError(ErrCodeProtocol)
-}
-
-func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, err error) {
- // TODO: do something with err? send it as a debug frame to the peer?
- // But that's only in GOAWAY. Invent a new frame type? Is there one already?
- cc.wmu.Lock()
- cc.fr.WriteRSTStream(streamID, code)
- cc.bw.Flush()
- cc.wmu.Unlock()
-}
-
-var (
- errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit")
- errPseudoTrailers = errors.New("http2: invalid pseudo header in trailers")
-)
-
-func (rl *clientConnReadLoop) checkHeaderField(f hpack.HeaderField) bool {
- if rl.reqMalformed != nil {
- return false
- }
-
- const headerFieldOverhead = 32 // per spec
- rl.headerListSize += int64(len(f.Name)) + int64(len(f.Value)) + headerFieldOverhead
- if max := rl.cc.t.maxHeaderListSize(); max != 0 && rl.headerListSize > int64(max) {
- rl.hdec.SetEmitEnabled(false)
- rl.reqMalformed = errResponseHeaderListSize
- return false
- }
-
- if !validHeaderFieldValue(f.Value) {
- rl.reqMalformed = errInvalidHeaderFieldValue
- return false
- }
-
- isPseudo := strings.HasPrefix(f.Name, ":")
- if isPseudo {
- if rl.sawRegHeader {
- rl.reqMalformed = errors.New("http2: invalid pseudo header after regular header")
- return false
- }
- } else {
- if !validHeaderFieldName(f.Name) {
- rl.reqMalformed = errInvalidHeaderFieldName
- return false
- }
- rl.sawRegHeader = true
- }
-
- return true
-}
-
-// onNewHeaderField runs on the readLoop goroutine whenever a new
-// hpack header field is decoded.
-func (rl *clientConnReadLoop) onNewHeaderField(f hpack.HeaderField) {
- cc := rl.cc
- if VerboseLogs {
- cc.logf("http2: Transport decoded %v", f)
- }
-
- if !rl.checkHeaderField(f) {
- return
- }
-
- isPseudo := strings.HasPrefix(f.Name, ":")
- if isPseudo {
- switch f.Name {
- case ":status":
- code, err := strconv.Atoi(f.Value)
- if err != nil {
- rl.reqMalformed = errors.New("http2: invalid :status")
- return
- }
- rl.nextRes.Status = f.Value + " " + http.StatusText(code)
- rl.nextRes.StatusCode = code
- default:
- // "Endpoints MUST NOT generate pseudo-header
- // fields other than those defined in this
- // document."
- rl.reqMalformed = fmt.Errorf("http2: unknown response pseudo header %q", f.Name)
- }
- return
- }
-
- key := http.CanonicalHeaderKey(f.Name)
- if key == "Trailer" {
- t := rl.nextRes.Trailer
- if t == nil {
- t = make(http.Header)
- rl.nextRes.Trailer = t
- }
- foreachHeaderElement(f.Value, func(v string) {
- t[http.CanonicalHeaderKey(v)] = nil
- })
- } else {
- rl.nextRes.Header.Add(key, f.Value)
- }
-}
-
-func (rl *clientConnReadLoop) onNewTrailerField(cs *clientStream, f hpack.HeaderField) {
- if VerboseLogs {
- rl.cc.logf("http2: Transport decoded trailer %v", f)
- }
- if !rl.checkHeaderField(f) {
- return
- }
- if strings.HasPrefix(f.Name, ":") {
- // Pseudo-header fields MUST NOT appear in
- // trailers. Endpoints MUST treat a request or
- // response that contains undefined or invalid
- // pseudo-header fields as malformed.
- rl.reqMalformed = errPseudoTrailers
- return
- }
-
- key := http.CanonicalHeaderKey(f.Name)
-
- // The spec says one must predeclare their trailers but in practice
- // popular users (which is to say the only user we found) do not so we
- // violate the spec and accept all of them.
- const acceptAllTrailers = true
- if _, ok := (*cs.resTrailer)[key]; ok || acceptAllTrailers {
- if cs.trailer == nil {
- cs.trailer = make(http.Header)
- }
- cs.trailer[key] = append(cs.trailer[key], f.Value)
- }
-}
-
-func (cc *ClientConn) logf(format string, args ...interface{}) {
- cc.t.logf(format, args...)
-}
-
-func (cc *ClientConn) vlogf(format string, args ...interface{}) {
- cc.t.vlogf(format, args...)
-}
-
-func (t *Transport) vlogf(format string, args ...interface{}) {
- if VerboseLogs {
- t.logf(format, args...)
- }
-}
-
-func (t *Transport) logf(format string, args ...interface{}) {
- log.Printf(format, args...)
-}
-
-var noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil))
-
-func strSliceContains(ss []string, s string) bool {
- for _, v := range ss {
- if v == s {
- return true
- }
- }
- return false
-}
-
-type erringRoundTripper struct{ err error }
-
-func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err }
-
-// gzipReader wraps a response body so it can lazily
-// call gzip.NewReader on the first call to Read
-type gzipReader struct {
- body io.ReadCloser // underlying Response.Body
- zr *gzip.Reader // lazily-initialized gzip reader
- zerr error // sticky error
-}
-
-func (gz *gzipReader) Read(p []byte) (n int, err error) {
- if gz.zerr != nil {
- return 0, gz.zerr
- }
- if gz.zr == nil {
- gz.zr, err = gzip.NewReader(gz.body)
- if err != nil {
- gz.zerr = err
- return 0, err
- }
- }
- return gz.zr.Read(p)
-}
-
-func (gz *gzipReader) Close() error {
- return gz.body.Close()
-}
-
-type errorReader struct{ err error }
-
-func (r errorReader) Read(p []byte) (int, error) { return 0, r.err }
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/write.go b/kube2msb/src/vendor/golang.org/x/net/http2/write.go
deleted file mode 100644
index 5297a4b..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/write.go
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 2014 The Go 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 http2
-
-import (
- "bytes"
- "fmt"
- "log"
- "net/http"
- "sort"
- "time"
-
- "golang.org/x/net/http2/hpack"
-)
-
-// writeFramer is implemented by any type that is used to write frames.
-type writeFramer interface {
- writeFrame(writeContext) error
-}
-
-// writeContext is the interface needed by the various frame writer
-// types below. All the writeFrame methods below are scheduled via the
-// frame writing scheduler (see writeScheduler in writesched.go).
-//
-// This interface is implemented by *serverConn.
-//
-// TODO: decide whether to a) use this in the client code (which didn't
-// end up using this yet, because it has a simpler design, not
-// currently implementing priorities), or b) delete this and
-// make the server code a bit more concrete.
-type writeContext interface {
- Framer() *Framer
- Flush() error
- CloseConn() error
- // HeaderEncoder returns an HPACK encoder that writes to the
- // returned buffer.
- HeaderEncoder() (*hpack.Encoder, *bytes.Buffer)
-}
-
-// endsStream reports whether the given frame writer w will locally
-// close the stream.
-func endsStream(w writeFramer) bool {
- switch v := w.(type) {
- case *writeData:
- return v.endStream
- case *writeResHeaders:
- return v.endStream
- case nil:
- // This can only happen if the caller reuses w after it's
- // been intentionally nil'ed out to prevent use. Keep this
- // here to catch future refactoring breaking it.
- panic("endsStream called on nil writeFramer")
- }
- return false
-}
-
-type flushFrameWriter struct{}
-
-func (flushFrameWriter) writeFrame(ctx writeContext) error {
- return ctx.Flush()
-}
-
-type writeSettings []Setting
-
-func (s writeSettings) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteSettings([]Setting(s)...)
-}
-
-type writeGoAway struct {
- maxStreamID uint32
- code ErrCode
-}
-
-func (p *writeGoAway) writeFrame(ctx writeContext) error {
- err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil)
- if p.code != 0 {
- ctx.Flush() // ignore error: we're hanging up on them anyway
- time.Sleep(50 * time.Millisecond)
- ctx.CloseConn()
- }
- return err
-}
-
-type writeData struct {
- streamID uint32
- p []byte
- endStream bool
-}
-
-func (w *writeData) String() string {
- return fmt.Sprintf("writeData(stream=%d, p=%d, endStream=%v)", w.streamID, len(w.p), w.endStream)
-}
-
-func (w *writeData) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteData(w.streamID, w.endStream, w.p)
-}
-
-// handlerPanicRST is the message sent from handler goroutines when
-// the handler panics.
-type handlerPanicRST struct {
- StreamID uint32
-}
-
-func (hp handlerPanicRST) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteRSTStream(hp.StreamID, ErrCodeInternal)
-}
-
-func (se StreamError) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteRSTStream(se.StreamID, se.Code)
-}
-
-type writePingAck struct{ pf *PingFrame }
-
-func (w writePingAck) writeFrame(ctx writeContext) error {
- return ctx.Framer().WritePing(true, w.pf.Data)
-}
-
-type writeSettingsAck struct{}
-
-func (writeSettingsAck) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteSettingsAck()
-}
-
-// writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames
-// for HTTP response headers or trailers from a server handler.
-type writeResHeaders struct {
- streamID uint32
- httpResCode int // 0 means no ":status" line
- h http.Header // may be nil
- trailers []string // if non-nil, which keys of h to write. nil means all.
- endStream bool
-
- date string
- contentType string
- contentLength string
-}
-
-func encKV(enc *hpack.Encoder, k, v string) {
- if VerboseLogs {
- log.Printf("http2: server encoding header %q = %q", k, v)
- }
- enc.WriteField(hpack.HeaderField{Name: k, Value: v})
-}
-
-func (w *writeResHeaders) writeFrame(ctx writeContext) error {
- enc, buf := ctx.HeaderEncoder()
- buf.Reset()
-
- if w.httpResCode != 0 {
- encKV(enc, ":status", httpCodeString(w.httpResCode))
- }
-
- encodeHeaders(enc, w.h, w.trailers)
-
- if w.contentType != "" {
- encKV(enc, "content-type", w.contentType)
- }
- if w.contentLength != "" {
- encKV(enc, "content-length", w.contentLength)
- }
- if w.date != "" {
- encKV(enc, "date", w.date)
- }
-
- headerBlock := buf.Bytes()
- if len(headerBlock) == 0 && w.trailers == nil {
- panic("unexpected empty hpack")
- }
-
- // For now we're lazy and just pick the minimum MAX_FRAME_SIZE
- // that all peers must support (16KB). Later we could care
- // more and send larger frames if the peer advertised it, but
- // there's little point. Most headers are small anyway (so we
- // generally won't have CONTINUATION frames), and extra frames
- // only waste 9 bytes anyway.
- const maxFrameSize = 16384
-
- first := true
- for len(headerBlock) > 0 {
- frag := headerBlock
- if len(frag) > maxFrameSize {
- frag = frag[:maxFrameSize]
- }
- headerBlock = headerBlock[len(frag):]
- endHeaders := len(headerBlock) == 0
- var err error
- if first {
- first = false
- err = ctx.Framer().WriteHeaders(HeadersFrameParam{
- StreamID: w.streamID,
- BlockFragment: frag,
- EndStream: w.endStream,
- EndHeaders: endHeaders,
- })
- } else {
- err = ctx.Framer().WriteContinuation(w.streamID, endHeaders, frag)
- }
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-type write100ContinueHeadersFrame struct {
- streamID uint32
-}
-
-func (w write100ContinueHeadersFrame) writeFrame(ctx writeContext) error {
- enc, buf := ctx.HeaderEncoder()
- buf.Reset()
- encKV(enc, ":status", "100")
- return ctx.Framer().WriteHeaders(HeadersFrameParam{
- StreamID: w.streamID,
- BlockFragment: buf.Bytes(),
- EndStream: false,
- EndHeaders: true,
- })
-}
-
-type writeWindowUpdate struct {
- streamID uint32 // or 0 for conn-level
- n uint32
-}
-
-func (wu writeWindowUpdate) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n)
-}
-
-func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
- // TODO: garbage. pool sorters like http1? hot path for 1 key?
- if keys == nil {
- keys = make([]string, 0, len(h))
- for k := range h {
- keys = append(keys, k)
- }
- sort.Strings(keys)
- }
- for _, k := range keys {
- vv := h[k]
- k = lowerHeader(k)
- if !validHeaderFieldName(k) {
- // TODO: return an error? golang.org/issue/14048
- // For now just omit it.
- continue
- }
- isTE := k == "transfer-encoding"
- for _, v := range vv {
- if !validHeaderFieldValue(v) {
- // TODO: return an error? golang.org/issue/14048
- // For now just omit it.
- continue
- }
- // TODO: more of "8.1.2.2 Connection-Specific Header Fields"
- if isTE && v != "trailers" {
- continue
- }
- encKV(enc, k, v)
- }
- }
-}
diff --git a/kube2msb/src/vendor/golang.org/x/net/http2/writesched.go b/kube2msb/src/vendor/golang.org/x/net/http2/writesched.go
deleted file mode 100644
index c24316c..0000000
--- a/kube2msb/src/vendor/golang.org/x/net/http2/writesched.go
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2014 The Go 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 http2
-
-import "fmt"
-
-// frameWriteMsg is a request to write a frame.
-type frameWriteMsg struct {
- // write is the interface value that does the writing, once the
- // writeScheduler (below) has decided to select this frame
- // to write. The write functions are all defined in write.go.
- write writeFramer
-
- stream *stream // used for prioritization. nil for non-stream frames.
-
- // done, if non-nil, must be a buffered channel with space for
- // 1 message and is sent the return value from write (or an
- // earlier error) when the frame has been written.
- done chan error
-}
-
-// for debugging only:
-func (wm frameWriteMsg) String() string {
- var streamID uint32
- if wm.stream != nil {
- streamID = wm.stream.id
- }
- var des string
- if s, ok := wm.write.(fmt.Stringer); ok {
- des = s.String()
- } else {
- des = fmt.Sprintf("%T", wm.write)
- }
- return fmt.Sprintf("[frameWriteMsg stream=%d, ch=%v, type: %v]", streamID, wm.done != nil, des)
-}
-
-// writeScheduler tracks pending frames to write, priorities, and decides
-// the next one to use. It is not thread-safe.
-type writeScheduler struct {
- // zero are frames not associated with a specific stream.
- // They're sent before any stream-specific freams.
- zero writeQueue
-
- // maxFrameSize is the maximum size of a DATA frame
- // we'll write. Must be non-zero and between 16K-16M.
- maxFrameSize uint32
-
- // sq contains the stream-specific queues, keyed by stream ID.
- // when a stream is idle, it's deleted from the map.
- sq map[uint32]*writeQueue
-
- // canSend is a slice of memory that's reused between frame
- // scheduling decisions to hold the list of writeQueues (from sq)
- // which have enough flow control data to send. After canSend is
- // built, the best is selected.
- canSend []*writeQueue
-
- // pool of empty queues for reuse.
- queuePool []*writeQueue
-}
-
-func (ws *writeScheduler) putEmptyQueue(q *writeQueue) {
- if len(q.s) != 0 {
- panic("queue must be empty")
- }
- ws.queuePool = append(ws.queuePool, q)
-}
-
-func (ws *writeScheduler) getEmptyQueue() *writeQueue {
- ln := len(ws.queuePool)
- if ln == 0 {
- return new(writeQueue)
- }
- q := ws.queuePool[ln-1]
- ws.queuePool = ws.queuePool[:ln-1]
- return q
-}
-
-func (ws *writeScheduler) empty() bool { return ws.zero.empty() && len(ws.sq) == 0 }
-
-func (ws *writeScheduler) add(wm frameWriteMsg) {
- st := wm.stream
- if st == nil {
- ws.zero.push(wm)
- } else {
- ws.streamQueue(st.id).push(wm)
- }
-}
-
-func (ws *writeScheduler) streamQueue(streamID uint32) *writeQueue {
- if q, ok := ws.sq[streamID]; ok {
- return q
- }
- if ws.sq == nil {
- ws.sq = make(map[uint32]*writeQueue)
- }
- q := ws.getEmptyQueue()
- ws.sq[streamID] = q
- return q
-}
-
-// take returns the most important frame to write and removes it from the scheduler.
-// It is illegal to call this if the scheduler is empty or if there are no connection-level
-// flow control bytes available.
-func (ws *writeScheduler) take() (wm frameWriteMsg, ok bool) {
- if ws.maxFrameSize == 0 {
- panic("internal error: ws.maxFrameSize not initialized or invalid")
- }
-
- // If there any frames not associated with streams, prefer those first.
- // These are usually SETTINGS, etc.
- if !ws.zero.empty() {
- return ws.zero.shift(), true
- }
- if len(ws.sq) == 0 {
- return
- }
-
- // Next, prioritize frames on streams that aren't DATA frames (no cost).
- for id, q := range ws.sq {
- if q.firstIsNoCost() {
- return ws.takeFrom(id, q)
- }
- }
-
- // Now, all that remains are DATA frames with non-zero bytes to
- // send. So pick the best one.
- if len(ws.canSend) != 0 {
- panic("should be empty")
- }
- for _, q := range ws.sq {
- if n := ws.streamWritableBytes(q); n > 0 {
- ws.canSend = append(ws.canSend, q)
- }
- }
- if len(ws.canSend) == 0 {
- return
- }
- defer ws.zeroCanSend()
-
- // TODO: find the best queue
- q := ws.canSend[0]
-
- return ws.takeFrom(q.streamID(), q)
-}
-
-// zeroCanSend is defered from take.
-func (ws *writeScheduler) zeroCanSend() {
- for i := range ws.canSend {
- ws.canSend[i] = nil
- }
- ws.canSend = ws.canSend[:0]
-}
-
-// streamWritableBytes returns the number of DATA bytes we could write
-// from the given queue's stream, if this stream/queue were
-// selected. It is an error to call this if q's head isn't a
-// *writeData.
-func (ws *writeScheduler) streamWritableBytes(q *writeQueue) int32 {
- wm := q.head()
- ret := wm.stream.flow.available() // max we can write
- if ret == 0 {
- return 0
- }
- if int32(ws.maxFrameSize) < ret {
- ret = int32(ws.maxFrameSize)
- }
- if ret == 0 {
- panic("internal error: ws.maxFrameSize not initialized or invalid")
- }
- wd := wm.write.(*writeData)
- if len(wd.p) < int(ret) {
- ret = int32(len(wd.p))
- }
- return ret
-}
-
-func (ws *writeScheduler) takeFrom(id uint32, q *writeQueue) (wm frameWriteMsg, ok bool) {
- wm = q.head()
- // If the first item in this queue costs flow control tokens
- // and we don't have enough, write as much as we can.
- if wd, ok := wm.write.(*writeData); ok && len(wd.p) > 0 {
- allowed := wm.stream.flow.available() // max we can write
- if allowed == 0 {
- // No quota available. Caller can try the next stream.
- return frameWriteMsg{}, false
- }
- if int32(ws.maxFrameSize) < allowed {
- allowed = int32(ws.maxFrameSize)
- }
- // TODO: further restrict the allowed size, because even if
- // the peer says it's okay to write 16MB data frames, we might
- // want to write smaller ones to properly weight competing
- // streams' priorities.
-
- if len(wd.p) > int(allowed) {
- wm.stream.flow.take(allowed)
- chunk := wd.p[:allowed]
- wd.p = wd.p[allowed:]
- // Make up a new write message of a valid size, rather
- // than shifting one off the queue.
- return frameWriteMsg{
- stream: wm.stream,
- write: &writeData{
- streamID: wd.streamID,
- p: chunk,
- // even if the original had endStream set, there
- // arebytes remaining because len(wd.p) > allowed,
- // so we know endStream is false:
- endStream: false,
- },
- // our caller is blocking on the final DATA frame, not
- // these intermediates, so no need to wait:
- done: nil,
- }, true
- }
- wm.stream.flow.take(int32(len(wd.p)))
- }
-
- q.shift()
- if q.empty() {
- ws.putEmptyQueue(q)
- delete(ws.sq, id)
- }
- return wm, true
-}
-
-func (ws *writeScheduler) forgetStream(id uint32) {
- q, ok := ws.sq[id]
- if !ok {
- return
- }
- delete(ws.sq, id)
-
- // But keep it for others later.
- for i := range q.s {
- q.s[i] = frameWriteMsg{}
- }
- q.s = q.s[:0]
- ws.putEmptyQueue(q)
-}
-
-type writeQueue struct {
- s []frameWriteMsg
-}
-
-// streamID returns the stream ID for a non-empty stream-specific queue.
-func (q *writeQueue) streamID() uint32 { return q.s[0].stream.id }
-
-func (q *writeQueue) empty() bool { return len(q.s) == 0 }
-
-func (q *writeQueue) push(wm frameWriteMsg) {
- q.s = append(q.s, wm)
-}
-
-// head returns the next item that would be removed by shift.
-func (q *writeQueue) head() frameWriteMsg {
- if len(q.s) == 0 {
- panic("invalid use of queue")
- }
- return q.s[0]
-}
-
-func (q *writeQueue) shift() frameWriteMsg {
- if len(q.s) == 0 {
- panic("invalid use of queue")
- }
- wm := q.s[0]
- // TODO: less copy-happy queue.
- copy(q.s, q.s[1:])
- q.s[len(q.s)-1] = frameWriteMsg{}
- q.s = q.s[:len(q.s)-1]
- return wm
-}
-
-func (q *writeQueue) firstIsNoCost() bool {
- if df, ok := q.s[0].write.(*writeData); ok {
- return len(df.p) == 0
- }
- return true
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/AUTHORS b/kube2msb/src/vendor/golang.org/x/oauth2/AUTHORS
deleted file mode 100644
index 15167cd..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/CONTRIBUTING.md b/kube2msb/src/vendor/golang.org/x/oauth2/CONTRIBUTING.md
deleted file mode 100644
index 46aa2b1..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/CONTRIBUTING.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# Contributing to Go
-
-Go is an open source project.
-
-It is the work of hundreds of contributors. We appreciate your help!
-
-
-## Filing issues
-
-When [filing an issue](https://github.com/golang/oauth2/issues), make sure to answer these five questions:
-
-1. What version of Go are you using (`go version`)?
-2. What operating system and processor architecture are you using?
-3. What did you do?
-4. What did you expect to see?
-5. What did you see instead?
-
-General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
-The gophers there will answer or ask you to file an issue if you've tripped over a bug.
-
-## Contributing code
-
-Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
-before sending patches.
-
-**We do not accept GitHub pull requests**
-(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
-
-Unless otherwise noted, the Go source files are distributed under
-the BSD-style license found in the LICENSE file.
-
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/CONTRIBUTORS b/kube2msb/src/vendor/golang.org/x/oauth2/CONTRIBUTORS
deleted file mode 100644
index 1c4577e..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/LICENSE b/kube2msb/src/vendor/golang.org/x/oauth2/LICENSE
deleted file mode 100644
index d02f24f..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2009 The oauth2 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.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-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
-OWNER 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/kube2msb/src/vendor/golang.org/x/oauth2/README.md b/kube2msb/src/vendor/golang.org/x/oauth2/README.md
deleted file mode 100644
index 0d51417..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/README.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# OAuth2 for Go
-
-[![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2)
-
-oauth2 package contains a client implementation for OAuth 2.0 spec.
-
-## Installation
-
-~~~~
-go get golang.org/x/oauth2
-~~~~
-
-See godoc for further documentation and examples.
-
-* [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2)
-* [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google)
-
-
-## App Engine
-
-In change 96e89be (March 2015) we removed the `oauth2.Context2` type in favor
-of the [`context.Context`](https://golang.org/x/net/context#Context) type from
-the `golang.org/x/net/context` package
-
-This means its no longer possible to use the "Classic App Engine"
-`appengine.Context` type with the `oauth2` package. (You're using
-Classic App Engine if you import the package `"appengine"`.)
-
-To work around this, you may use the new `"google.golang.org/appengine"`
-package. This package has almost the same API as the `"appengine"` package,
-but it can be fetched with `go get` and used on "Managed VMs" and well as
-Classic App Engine.
-
-See the [new `appengine` package's readme](https://github.com/golang/appengine#updating-a-go-app-engine-app)
-for information on updating your app.
-
-If you don't want to update your entire app to use the new App Engine packages,
-you may use both sets of packages in parallel, using only the new packages
-with the `oauth2` package.
-
- import (
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/google"
- newappengine "google.golang.org/appengine"
- newurlfetch "google.golang.org/appengine/urlfetch"
-
- "appengine"
- )
-
- func handler(w http.ResponseWriter, r *http.Request) {
- var c appengine.Context = appengine.NewContext(r)
- c.Infof("Logging a message with the old package")
-
- var ctx context.Context = newappengine.NewContext(r)
- client := &http.Client{
- Transport: &oauth2.Transport{
- Source: google.AppEngineTokenSource(ctx, "scope"),
- Base: &newurlfetch.Transport{Context: ctx},
- },
- }
- client.Get("...")
- }
-
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/client_appengine.go b/kube2msb/src/vendor/golang.org/x/oauth2/client_appengine.go
deleted file mode 100644
index 4a554cb..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/client_appengine.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2014 The oauth2 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 appenginevm
-
-// App Engine hooks.
-
-package oauth2
-
-import (
- "net/http"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2/internal"
- "google.golang.org/appengine/urlfetch"
-)
-
-func init() {
- internal.RegisterContextClientFunc(contextClientAppEngine)
-}
-
-func contextClientAppEngine(ctx context.Context) (*http.Client, error) {
- return urlfetch.Client(ctx), nil
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/google/appengine.go b/kube2msb/src/vendor/golang.org/x/oauth2/google/appengine.go
deleted file mode 100644
index 65dc347..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/google/appengine.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2014 The oauth2 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 google
-
-import (
- "sort"
- "strings"
- "sync"
- "time"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
-)
-
-// Set at init time by appengine_hook.go. If nil, we're not on App Engine.
-var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error)
-
-// AppEngineTokenSource returns a token source that fetches tokens
-// issued to the current App Engine application's service account.
-// If you are implementing a 3-legged OAuth 2.0 flow on App Engine
-// that involves user accounts, see oauth2.Config instead.
-//
-// The provided context must have come from appengine.NewContext.
-func AppEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource {
- if appengineTokenFunc == nil {
- panic("google: AppEngineTokenSource can only be used on App Engine.")
- }
- scopes := append([]string{}, scope...)
- sort.Strings(scopes)
- return &appEngineTokenSource{
- ctx: ctx,
- scopes: scopes,
- key: strings.Join(scopes, " "),
- }
-}
-
-// aeTokens helps the fetched tokens to be reused until their expiration.
-var (
- aeTokensMu sync.Mutex
- aeTokens = make(map[string]*tokenLock) // key is space-separated scopes
-)
-
-type tokenLock struct {
- mu sync.Mutex // guards t; held while fetching or updating t
- t *oauth2.Token
-}
-
-type appEngineTokenSource struct {
- ctx context.Context
- scopes []string
- key string // to aeTokens map; space-separated scopes
-}
-
-func (ts *appEngineTokenSource) Token() (*oauth2.Token, error) {
- if appengineTokenFunc == nil {
- panic("google: AppEngineTokenSource can only be used on App Engine.")
- }
-
- aeTokensMu.Lock()
- tok, ok := aeTokens[ts.key]
- if !ok {
- tok = &tokenLock{}
- aeTokens[ts.key] = tok
- }
- aeTokensMu.Unlock()
-
- tok.mu.Lock()
- defer tok.mu.Unlock()
- if tok.t.Valid() {
- return tok.t, nil
- }
- access, exp, err := appengineTokenFunc(ts.ctx, ts.scopes...)
- if err != nil {
- return nil, err
- }
- tok.t = &oauth2.Token{
- AccessToken: access,
- Expiry: exp,
- }
- return tok.t, nil
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/google/appengine_hook.go b/kube2msb/src/vendor/golang.org/x/oauth2/google/appengine_hook.go
deleted file mode 100644
index 2f9b154..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/google/appengine_hook.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2015 The oauth2 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 appenginevm
-
-package google
-
-import "google.golang.org/appengine"
-
-func init() {
- appengineTokenFunc = appengine.AccessToken
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/google/default.go b/kube2msb/src/vendor/golang.org/x/oauth2/google/default.go
deleted file mode 100644
index 78f8089..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/google/default.go
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2015 The oauth2 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 google
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "io/ioutil"
- "net/http"
- "os"
- "path/filepath"
- "runtime"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/jwt"
- "google.golang.org/cloud/compute/metadata"
-)
-
-// DefaultClient returns an HTTP Client that uses the
-// DefaultTokenSource to obtain authentication credentials.
-//
-// This client should be used when developing services
-// that run on Google App Engine or Google Compute Engine
-// and use "Application Default Credentials."
-//
-// For more details, see:
-// https://developers.google.com/accounts/docs/application-default-credentials
-//
-func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
- ts, err := DefaultTokenSource(ctx, scope...)
- if err != nil {
- return nil, err
- }
- return oauth2.NewClient(ctx, ts), nil
-}
-
-// DefaultTokenSource is a token source that uses
-// "Application Default Credentials".
-//
-// It looks for credentials in the following places,
-// preferring the first location found:
-//
-// 1. A JSON file whose path is specified by the
-// GOOGLE_APPLICATION_CREDENTIALS environment variable.
-// 2. A JSON file in a location known to the gcloud command-line tool.
-// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
-// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
-// 3. On Google App Engine it uses the appengine.AccessToken function.
-// 4. On Google Compute Engine, it fetches credentials from the metadata server.
-// (In this final case any provided scopes are ignored.)
-//
-// For more details, see:
-// https://developers.google.com/accounts/docs/application-default-credentials
-//
-func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error) {
- // First, try the environment variable.
- const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
- if filename := os.Getenv(envVar); filename != "" {
- ts, err := tokenSourceFromFile(ctx, filename, scope)
- if err != nil {
- return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err)
- }
- return ts, nil
- }
-
- // Second, try a well-known file.
- filename := wellKnownFile()
- _, err := os.Stat(filename)
- if err == nil {
- ts, err2 := tokenSourceFromFile(ctx, filename, scope)
- if err2 == nil {
- return ts, nil
- }
- err = err2
- } else if os.IsNotExist(err) {
- err = nil // ignore this error
- }
- if err != nil {
- return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err)
- }
-
- // Third, if we're on Google App Engine use those credentials.
- if appengineTokenFunc != nil {
- return AppEngineTokenSource(ctx, scope...), nil
- }
-
- // Fourth, if we're on Google Compute Engine use the metadata server.
- if metadata.OnGCE() {
- return ComputeTokenSource(""), nil
- }
-
- // None are found; return helpful error.
- const url = "https://developers.google.com/accounts/docs/application-default-credentials"
- return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url)
-}
-
-func wellKnownFile() string {
- const f = "application_default_credentials.json"
- if runtime.GOOS == "windows" {
- return filepath.Join(os.Getenv("APPDATA"), "gcloud", f)
- }
- return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f)
-}
-
-func tokenSourceFromFile(ctx context.Context, filename string, scopes []string) (oauth2.TokenSource, error) {
- b, err := ioutil.ReadFile(filename)
- if err != nil {
- return nil, err
- }
- var d struct {
- // Common fields
- Type string
- ClientID string `json:"client_id"`
-
- // User Credential fields
- ClientSecret string `json:"client_secret"`
- RefreshToken string `json:"refresh_token"`
-
- // Service Account fields
- ClientEmail string `json:"client_email"`
- PrivateKeyID string `json:"private_key_id"`
- PrivateKey string `json:"private_key"`
- }
- if err := json.Unmarshal(b, &d); err != nil {
- return nil, err
- }
- switch d.Type {
- case "authorized_user":
- cfg := &oauth2.Config{
- ClientID: d.ClientID,
- ClientSecret: d.ClientSecret,
- Scopes: append([]string{}, scopes...), // copy
- Endpoint: Endpoint,
- }
- tok := &oauth2.Token{RefreshToken: d.RefreshToken}
- return cfg.TokenSource(ctx, tok), nil
- case "service_account":
- cfg := &jwt.Config{
- Email: d.ClientEmail,
- PrivateKey: []byte(d.PrivateKey),
- Scopes: append([]string{}, scopes...), // copy
- TokenURL: JWTTokenURL,
- }
- return cfg.TokenSource(ctx), nil
- case "":
- return nil, errors.New("missing 'type' field in credentials")
- default:
- return nil, fmt.Errorf("unknown credential type: %q", d.Type)
- }
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/google/google.go b/kube2msb/src/vendor/golang.org/x/oauth2/google/google.go
deleted file mode 100644
index 2077d98..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/google/google.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2014 The oauth2 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 google provides support for making OAuth2 authorized and
-// authenticated HTTP requests to Google APIs.
-// It supports the Web server flow, client-side credentials, service accounts,
-// Google Compute Engine service accounts, and Google App Engine service
-// accounts.
-//
-// For more information, please read
-// https://developers.google.com/accounts/docs/OAuth2
-// and
-// https://developers.google.com/accounts/docs/application-default-credentials.
-package google
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "strings"
- "time"
-
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/jwt"
- "google.golang.org/cloud/compute/metadata"
-)
-
-// Endpoint is Google's OAuth 2.0 endpoint.
-var Endpoint = oauth2.Endpoint{
- AuthURL: "https://accounts.google.com/o/oauth2/auth",
- TokenURL: "https://accounts.google.com/o/oauth2/token",
-}
-
-// JWTTokenURL is Google's OAuth 2.0 token URL to use with the JWT flow.
-const JWTTokenURL = "https://accounts.google.com/o/oauth2/token"
-
-// ConfigFromJSON uses a Google Developers Console client_credentials.json
-// file to construct a config.
-// client_credentials.json can be downloadable from https://console.developers.google.com,
-// under "APIs & Auth" > "Credentials". Download the Web application credentials in the
-// JSON format and provide the contents of the file as jsonKey.
-func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) {
- type cred struct {
- ClientID string `json:"client_id"`
- ClientSecret string `json:"client_secret"`
- RedirectURIs []string `json:"redirect_uris"`
- AuthURI string `json:"auth_uri"`
- TokenURI string `json:"token_uri"`
- }
- var j struct {
- Web *cred `json:"web"`
- Installed *cred `json:"installed"`
- }
- if err := json.Unmarshal(jsonKey, &j); err != nil {
- return nil, err
- }
- var c *cred
- switch {
- case j.Web != nil:
- c = j.Web
- case j.Installed != nil:
- c = j.Installed
- default:
- return nil, fmt.Errorf("oauth2/google: no credentials found")
- }
- if len(c.RedirectURIs) < 1 {
- return nil, errors.New("oauth2/google: missing redirect URL in the client_credentials.json")
- }
- return &oauth2.Config{
- ClientID: c.ClientID,
- ClientSecret: c.ClientSecret,
- RedirectURL: c.RedirectURIs[0],
- Scopes: scope,
- Endpoint: oauth2.Endpoint{
- AuthURL: c.AuthURI,
- TokenURL: c.TokenURI,
- },
- }, nil
-}
-
-// JWTConfigFromJSON uses a Google Developers service account JSON key file to read
-// the credentials that authorize and authenticate the requests.
-// Create a service account on "Credentials" page under "APIs & Auth" for your
-// project at https://console.developers.google.com to download a JSON key file.
-func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) {
- var key struct {
- Email string `json:"client_email"`
- PrivateKey string `json:"private_key"`
- }
- if err := json.Unmarshal(jsonKey, &key); err != nil {
- return nil, err
- }
- return &jwt.Config{
- Email: key.Email,
- PrivateKey: []byte(key.PrivateKey),
- Scopes: scope,
- TokenURL: JWTTokenURL,
- }, nil
-}
-
-// ComputeTokenSource returns a token source that fetches access tokens
-// from Google Compute Engine (GCE)'s metadata server. It's only valid to use
-// this token source if your program is running on a GCE instance.
-// If no account is specified, "default" is used.
-// Further information about retrieving access tokens from the GCE metadata
-// server can be found at https://cloud.google.com/compute/docs/authentication.
-func ComputeTokenSource(account string) oauth2.TokenSource {
- return oauth2.ReuseTokenSource(nil, computeSource{account: account})
-}
-
-type computeSource struct {
- account string
-}
-
-func (cs computeSource) Token() (*oauth2.Token, error) {
- if !metadata.OnGCE() {
- return nil, errors.New("oauth2/google: can't get a token from the metadata service; not running on GCE")
- }
- acct := cs.account
- if acct == "" {
- acct = "default"
- }
- tokenJSON, err := metadata.Get("instance/service-accounts/" + acct + "/token")
- if err != nil {
- return nil, err
- }
- var res struct {
- AccessToken string `json:"access_token"`
- ExpiresInSec int `json:"expires_in"`
- TokenType string `json:"token_type"`
- }
- err = json.NewDecoder(strings.NewReader(tokenJSON)).Decode(&res)
- if err != nil {
- return nil, fmt.Errorf("oauth2/google: invalid token JSON from metadata: %v", err)
- }
- if res.ExpiresInSec == 0 || res.AccessToken == "" {
- return nil, fmt.Errorf("oauth2/google: incomplete token received from metadata")
- }
- return &oauth2.Token{
- AccessToken: res.AccessToken,
- TokenType: res.TokenType,
- Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second),
- }, nil
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/google/sdk.go b/kube2msb/src/vendor/golang.org/x/oauth2/google/sdk.go
deleted file mode 100644
index 01ba0ec..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/google/sdk.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2015 The oauth2 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 google
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "net/http"
- "os"
- "os/user"
- "path/filepath"
- "runtime"
- "strings"
- "time"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/internal"
-)
-
-type sdkCredentials struct {
- Data []struct {
- Credential struct {
- ClientID string `json:"client_id"`
- ClientSecret string `json:"client_secret"`
- AccessToken string `json:"access_token"`
- RefreshToken string `json:"refresh_token"`
- TokenExpiry *time.Time `json:"token_expiry"`
- } `json:"credential"`
- Key struct {
- Account string `json:"account"`
- Scope string `json:"scope"`
- } `json:"key"`
- }
-}
-
-// An SDKConfig provides access to tokens from an account already
-// authorized via the Google Cloud SDK.
-type SDKConfig struct {
- conf oauth2.Config
- initialToken *oauth2.Token
-}
-
-// NewSDKConfig creates an SDKConfig for the given Google Cloud SDK
-// account. If account is empty, the account currently active in
-// Google Cloud SDK properties is used.
-// Google Cloud SDK credentials must be created by running `gcloud auth`
-// before using this function.
-// The Google Cloud SDK is available at https://cloud.google.com/sdk/.
-func NewSDKConfig(account string) (*SDKConfig, error) {
- configPath, err := sdkConfigPath()
- if err != nil {
- return nil, fmt.Errorf("oauth2/google: error getting SDK config path: %v", err)
- }
- credentialsPath := filepath.Join(configPath, "credentials")
- f, err := os.Open(credentialsPath)
- if err != nil {
- return nil, fmt.Errorf("oauth2/google: failed to load SDK credentials: %v", err)
- }
- defer f.Close()
-
- var c sdkCredentials
- if err := json.NewDecoder(f).Decode(&c); err != nil {
- return nil, fmt.Errorf("oauth2/google: failed to decode SDK credentials from %q: %v", credentialsPath, err)
- }
- if len(c.Data) == 0 {
- return nil, fmt.Errorf("oauth2/google: no credentials found in %q, run `gcloud auth login` to create one", credentialsPath)
- }
- if account == "" {
- propertiesPath := filepath.Join(configPath, "properties")
- f, err := os.Open(propertiesPath)
- if err != nil {
- return nil, fmt.Errorf("oauth2/google: failed to load SDK properties: %v", err)
- }
- defer f.Close()
- ini, err := internal.ParseINI(f)
- if err != nil {
- return nil, fmt.Errorf("oauth2/google: failed to parse SDK properties %q: %v", propertiesPath, err)
- }
- core, ok := ini["core"]
- if !ok {
- return nil, fmt.Errorf("oauth2/google: failed to find [core] section in %v", ini)
- }
- active, ok := core["account"]
- if !ok {
- return nil, fmt.Errorf("oauth2/google: failed to find %q attribute in %v", "account", core)
- }
- account = active
- }
-
- for _, d := range c.Data {
- if account == "" || d.Key.Account == account {
- if d.Credential.AccessToken == "" && d.Credential.RefreshToken == "" {
- return nil, fmt.Errorf("oauth2/google: no token available for account %q", account)
- }
- var expiry time.Time
- if d.Credential.TokenExpiry != nil {
- expiry = *d.Credential.TokenExpiry
- }
- return &SDKConfig{
- conf: oauth2.Config{
- ClientID: d.Credential.ClientID,
- ClientSecret: d.Credential.ClientSecret,
- Scopes: strings.Split(d.Key.Scope, " "),
- Endpoint: Endpoint,
- RedirectURL: "oob",
- },
- initialToken: &oauth2.Token{
- AccessToken: d.Credential.AccessToken,
- RefreshToken: d.Credential.RefreshToken,
- Expiry: expiry,
- },
- }, nil
- }
- }
- return nil, fmt.Errorf("oauth2/google: no such credentials for account %q", account)
-}
-
-// Client returns an HTTP client using Google Cloud SDK credentials to
-// authorize requests. The token will auto-refresh as necessary. The
-// underlying http.RoundTripper will be obtained using the provided
-// context. The returned client and its Transport should not be
-// modified.
-func (c *SDKConfig) Client(ctx context.Context) *http.Client {
- return &http.Client{
- Transport: &oauth2.Transport{
- Source: c.TokenSource(ctx),
- },
- }
-}
-
-// TokenSource returns an oauth2.TokenSource that retrieve tokens from
-// Google Cloud SDK credentials using the provided context.
-// It will returns the current access token stored in the credentials,
-// and refresh it when it expires, but it won't update the credentials
-// with the new access token.
-func (c *SDKConfig) TokenSource(ctx context.Context) oauth2.TokenSource {
- return c.conf.TokenSource(ctx, c.initialToken)
-}
-
-// Scopes are the OAuth 2.0 scopes the current account is authorized for.
-func (c *SDKConfig) Scopes() []string {
- return c.conf.Scopes
-}
-
-// sdkConfigPath tries to guess where the gcloud config is located.
-// It can be overridden during tests.
-var sdkConfigPath = func() (string, error) {
- if runtime.GOOS == "windows" {
- return filepath.Join(os.Getenv("APPDATA"), "gcloud"), nil
- }
- homeDir := guessUnixHomeDir()
- if homeDir == "" {
- return "", errors.New("unable to get current user home directory: os/user lookup failed; $HOME is empty")
- }
- return filepath.Join(homeDir, ".config", "gcloud"), nil
-}
-
-func guessUnixHomeDir() string {
- usr, err := user.Current()
- if err == nil {
- return usr.HomeDir
- }
- return os.Getenv("HOME")
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/internal/oauth2.go b/kube2msb/src/vendor/golang.org/x/oauth2/internal/oauth2.go
deleted file mode 100644
index dc8ebfc..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/internal/oauth2.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2014 The oauth2 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 internal contains support packages for oauth2 package.
-package internal
-
-import (
- "bufio"
- "crypto/rsa"
- "crypto/x509"
- "encoding/pem"
- "errors"
- "fmt"
- "io"
- "strings"
-)
-
-// ParseKey converts the binary contents of a private key file
-// to an *rsa.PrivateKey. It detects whether the private key is in a
-// PEM container or not. If so, it extracts the the private key
-// from PEM container before conversion. It only supports PEM
-// containers with no passphrase.
-func ParseKey(key []byte) (*rsa.PrivateKey, error) {
- block, _ := pem.Decode(key)
- if block != nil {
- key = block.Bytes
- }
- parsedKey, err := x509.ParsePKCS8PrivateKey(key)
- if err != nil {
- parsedKey, err = x509.ParsePKCS1PrivateKey(key)
- if err != nil {
- return nil, fmt.Errorf("private key should be a PEM or plain PKSC1 or PKCS8; parse error: %v", err)
- }
- }
- parsed, ok := parsedKey.(*rsa.PrivateKey)
- if !ok {
- return nil, errors.New("private key is invalid")
- }
- return parsed, nil
-}
-
-func ParseINI(ini io.Reader) (map[string]map[string]string, error) {
- result := map[string]map[string]string{
- "": map[string]string{}, // root section
- }
- scanner := bufio.NewScanner(ini)
- currentSection := ""
- for scanner.Scan() {
- line := strings.TrimSpace(scanner.Text())
- if strings.HasPrefix(line, ";") {
- // comment.
- continue
- }
- if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
- currentSection = strings.TrimSpace(line[1 : len(line)-1])
- result[currentSection] = map[string]string{}
- continue
- }
- parts := strings.SplitN(line, "=", 2)
- if len(parts) == 2 && parts[0] != "" {
- result[currentSection][strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
- }
- }
- if err := scanner.Err(); err != nil {
- return nil, fmt.Errorf("error scanning ini: %v", err)
- }
- return result, nil
-}
-
-func CondVal(v string) []string {
- if v == "" {
- return nil
- }
- return []string{v}
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/internal/token.go b/kube2msb/src/vendor/golang.org/x/oauth2/internal/token.go
deleted file mode 100644
index ea6716c..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/internal/token.go
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2014 The oauth2 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 internal contains support packages for oauth2 package.
-package internal
-
-import (
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "mime"
- "net/http"
- "net/url"
- "strconv"
- "strings"
- "time"
-
- "golang.org/x/net/context"
-)
-
-// Token represents the crendentials used to authorize
-// the requests to access protected resources on the OAuth 2.0
-// provider's backend.
-//
-// This type is a mirror of oauth2.Token and exists to break
-// an otherwise-circular dependency. Other internal packages
-// should convert this Token into an oauth2.Token before use.
-type Token struct {
- // AccessToken is the token that authorizes and authenticates
- // the requests.
- AccessToken string
-
- // TokenType is the type of token.
- // The Type method returns either this or "Bearer", the default.
- TokenType string
-
- // RefreshToken is a token that's used by the application
- // (as opposed to the user) to refresh the access token
- // if it expires.
- RefreshToken string
-
- // Expiry is the optional expiration time of the access token.
- //
- // If zero, TokenSource implementations will reuse the same
- // token forever and RefreshToken or equivalent
- // mechanisms for that TokenSource will not be used.
- Expiry time.Time
-
- // Raw optionally contains extra metadata from the server
- // when updating a token.
- Raw interface{}
-}
-
-// tokenJSON is the struct representing the HTTP response from OAuth2
-// providers returning a token in JSON form.
-type tokenJSON struct {
- AccessToken string `json:"access_token"`
- TokenType string `json:"token_type"`
- RefreshToken string `json:"refresh_token"`
- ExpiresIn expirationTime `json:"expires_in"` // at least PayPal returns string, while most return number
- Expires expirationTime `json:"expires"` // broken Facebook spelling of expires_in
-}
-
-func (e *tokenJSON) expiry() (t time.Time) {
- if v := e.ExpiresIn; v != 0 {
- return time.Now().Add(time.Duration(v) * time.Second)
- }
- if v := e.Expires; v != 0 {
- return time.Now().Add(time.Duration(v) * time.Second)
- }
- return
-}
-
-type expirationTime int32
-
-func (e *expirationTime) UnmarshalJSON(b []byte) error {
- var n json.Number
- err := json.Unmarshal(b, &n)
- if err != nil {
- return err
- }
- i, err := n.Int64()
- if err != nil {
- return err
- }
- *e = expirationTime(i)
- return nil
-}
-
-var brokenAuthHeaderProviders = []string{
- "https://accounts.google.com/",
- "https://www.googleapis.com/",
- "https://github.com/",
- "https://api.instagram.com/",
- "https://www.douban.com/",
- "https://api.dropbox.com/",
- "https://api.soundcloud.com/",
- "https://www.linkedin.com/",
- "https://api.twitch.tv/",
- "https://oauth.vk.com/",
- "https://api.odnoklassniki.ru/",
- "https://connect.stripe.com/",
- "https://api.pushbullet.com/",
- "https://oauth.sandbox.trainingpeaks.com/",
- "https://oauth.trainingpeaks.com/",
- "https://www.strava.com/oauth/",
- "https://app.box.com/",
- "https://test-sandbox.auth.corp.google.com",
- "https://user.gini.net/",
-}
-
-// providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL
-// implements the OAuth2 spec correctly
-// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
-// In summary:
-// - Reddit only accepts client secret in the Authorization header
-// - Dropbox accepts either it in URL param or Auth header, but not both.
-// - Google only accepts URL param (not spec compliant?), not Auth header
-// - Stripe only accepts client secret in Auth header with Bearer method, not Basic
-func providerAuthHeaderWorks(tokenURL string) bool {
- for _, s := range brokenAuthHeaderProviders {
- if strings.HasPrefix(tokenURL, s) {
- // Some sites fail to implement the OAuth2 spec fully.
- return false
- }
- }
-
- // Assume the provider implements the spec properly
- // otherwise. We can add more exceptions as they're
- // discovered. We will _not_ be adding configurable hooks
- // to this package to let users select server bugs.
- return true
-}
-
-func RetrieveToken(ctx context.Context, ClientID, ClientSecret, TokenURL string, v url.Values) (*Token, error) {
- hc, err := ContextClient(ctx)
- if err != nil {
- return nil, err
- }
- v.Set("client_id", ClientID)
- bustedAuth := !providerAuthHeaderWorks(TokenURL)
- if bustedAuth && ClientSecret != "" {
- v.Set("client_secret", ClientSecret)
- }
- req, err := http.NewRequest("POST", TokenURL, strings.NewReader(v.Encode()))
- if err != nil {
- return nil, err
- }
- req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
- if !bustedAuth {
- req.SetBasicAuth(ClientID, ClientSecret)
- }
- r, err := hc.Do(req)
- if err != nil {
- return nil, err
- }
- defer r.Body.Close()
- body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20))
- if err != nil {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
- }
- if code := r.StatusCode; code < 200 || code > 299 {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v\nResponse: %s", r.Status, body)
- }
-
- var token *Token
- content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
- switch content {
- case "application/x-www-form-urlencoded", "text/plain":
- vals, err := url.ParseQuery(string(body))
- if err != nil {
- return nil, err
- }
- token = &Token{
- AccessToken: vals.Get("access_token"),
- TokenType: vals.Get("token_type"),
- RefreshToken: vals.Get("refresh_token"),
- Raw: vals,
- }
- e := vals.Get("expires_in")
- if e == "" {
- // TODO(jbd): Facebook's OAuth2 implementation is broken and
- // returns expires_in field in expires. Remove the fallback to expires,
- // when Facebook fixes their implementation.
- e = vals.Get("expires")
- }
- expires, _ := strconv.Atoi(e)
- if expires != 0 {
- token.Expiry = time.Now().Add(time.Duration(expires) * time.Second)
- }
- default:
- var tj tokenJSON
- if err = json.Unmarshal(body, &tj); err != nil {
- return nil, err
- }
- token = &Token{
- AccessToken: tj.AccessToken,
- TokenType: tj.TokenType,
- RefreshToken: tj.RefreshToken,
- Expiry: tj.expiry(),
- Raw: make(map[string]interface{}),
- }
- json.Unmarshal(body, &token.Raw) // no error checks for optional fields
- }
- // Don't overwrite `RefreshToken` with an empty value
- // if this was a token refreshing request.
- if token.RefreshToken == "" {
- token.RefreshToken = v.Get("refresh_token")
- }
- return token, nil
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/internal/transport.go b/kube2msb/src/vendor/golang.org/x/oauth2/internal/transport.go
deleted file mode 100644
index 521e7b4..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/internal/transport.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2014 The oauth2 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 internal contains support packages for oauth2 package.
-package internal
-
-import (
- "net/http"
-
- "golang.org/x/net/context"
-)
-
-// HTTPClient is the context key to use with golang.org/x/net/context's
-// WithValue function to associate an *http.Client value with a context.
-var HTTPClient ContextKey
-
-// ContextKey is just an empty struct. It exists so HTTPClient can be
-// an immutable public variable with a unique type. It's immutable
-// because nobody else can create a ContextKey, being unexported.
-type ContextKey struct{}
-
-// ContextClientFunc is a func which tries to return an *http.Client
-// given a Context value. If it returns an error, the search stops
-// with that error. If it returns (nil, nil), the search continues
-// down the list of registered funcs.
-type ContextClientFunc func(context.Context) (*http.Client, error)
-
-var contextClientFuncs []ContextClientFunc
-
-func RegisterContextClientFunc(fn ContextClientFunc) {
- contextClientFuncs = append(contextClientFuncs, fn)
-}
-
-func ContextClient(ctx context.Context) (*http.Client, error) {
- for _, fn := range contextClientFuncs {
- c, err := fn(ctx)
- if err != nil {
- return nil, err
- }
- if c != nil {
- return c, nil
- }
- }
- if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok {
- return hc, nil
- }
- return http.DefaultClient, nil
-}
-
-func ContextTransport(ctx context.Context) http.RoundTripper {
- hc, err := ContextClient(ctx)
- // This is a rare error case (somebody using nil on App Engine).
- if err != nil {
- return ErrorTransport{err}
- }
- return hc.Transport
-}
-
-// ErrorTransport returns the specified error on RoundTrip.
-// This RoundTripper should be used in rare error cases where
-// error handling can be postponed to response handling time.
-type ErrorTransport struct{ Err error }
-
-func (t ErrorTransport) RoundTrip(*http.Request) (*http.Response, error) {
- return nil, t.Err
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/jws/jws.go b/kube2msb/src/vendor/golang.org/x/oauth2/jws/jws.go
deleted file mode 100644
index 396b3fa..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/jws/jws.go
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2014 The oauth2 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 jws provides encoding and decoding utilities for
-// signed JWS messages.
-package jws
-
-import (
- "bytes"
- "crypto"
- "crypto/rand"
- "crypto/rsa"
- "crypto/sha256"
- "encoding/base64"
- "encoding/json"
- "errors"
- "fmt"
- "strings"
- "time"
-)
-
-// ClaimSet contains information about the JWT signature including the
-// permissions being requested (scopes), the target of the token, the issuer,
-// the time the token was issued, and the lifetime of the token.
-type ClaimSet struct {
- Iss string `json:"iss"` // email address of the client_id of the application making the access token request
- Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests
- Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional).
- Exp int64 `json:"exp"` // the expiration time of the assertion
- Iat int64 `json:"iat"` // the time the assertion was issued.
- Typ string `json:"typ,omitempty"` // token type (Optional).
-
- // Email for which the application is requesting delegated access (Optional).
- Sub string `json:"sub,omitempty"`
-
- // The old name of Sub. Client keeps setting Prn to be
- // complaint with legacy OAuth 2.0 providers. (Optional)
- Prn string `json:"prn,omitempty"`
-
- // See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
- // This array is marshalled using custom code (see (c *ClaimSet) encode()).
- PrivateClaims map[string]interface{} `json:"-"`
-
- exp time.Time
- iat time.Time
-}
-
-func (c *ClaimSet) encode() (string, error) {
- if c.exp.IsZero() || c.iat.IsZero() {
- // Reverting time back for machines whose time is not perfectly in sync.
- // If client machine's time is in the future according
- // to Google servers, an access token will not be issued.
- now := time.Now().Add(-10 * time.Second)
- c.iat = now
- c.exp = now.Add(time.Hour)
- }
-
- c.Exp = c.exp.Unix()
- c.Iat = c.iat.Unix()
-
- b, err := json.Marshal(c)
- if err != nil {
- return "", err
- }
-
- if len(c.PrivateClaims) == 0 {
- return base64Encode(b), nil
- }
-
- // Marshal private claim set and then append it to b.
- prv, err := json.Marshal(c.PrivateClaims)
- if err != nil {
- return "", fmt.Errorf("jws: invalid map of private claims %v", c.PrivateClaims)
- }
-
- // Concatenate public and private claim JSON objects.
- if !bytes.HasSuffix(b, []byte{'}'}) {
- return "", fmt.Errorf("jws: invalid JSON %s", b)
- }
- if !bytes.HasPrefix(prv, []byte{'{'}) {
- return "", fmt.Errorf("jws: invalid JSON %s", prv)
- }
- b[len(b)-1] = ',' // Replace closing curly brace with a comma.
- b = append(b, prv[1:]...) // Append private claims.
- return base64Encode(b), nil
-}
-
-// Header represents the header for the signed JWS payloads.
-type Header struct {
- // The algorithm used for signature.
- Algorithm string `json:"alg"`
-
- // Represents the token type.
- Typ string `json:"typ"`
-}
-
-func (h *Header) encode() (string, error) {
- b, err := json.Marshal(h)
- if err != nil {
- return "", err
- }
- return base64Encode(b), nil
-}
-
-// Decode decodes a claim set from a JWS payload.
-func Decode(payload string) (*ClaimSet, error) {
- // decode returned id token to get expiry
- s := strings.Split(payload, ".")
- if len(s) < 2 {
- // TODO(jbd): Provide more context about the error.
- return nil, errors.New("jws: invalid token received")
- }
- decoded, err := base64Decode(s[1])
- if err != nil {
- return nil, err
- }
- c := &ClaimSet{}
- err = json.NewDecoder(bytes.NewBuffer(decoded)).Decode(c)
- return c, err
-}
-
-// Encode encodes a signed JWS with provided header and claim set.
-func Encode(header *Header, c *ClaimSet, signature *rsa.PrivateKey) (string, error) {
- head, err := header.encode()
- if err != nil {
- return "", err
- }
- cs, err := c.encode()
- if err != nil {
- return "", err
- }
- ss := fmt.Sprintf("%s.%s", head, cs)
- h := sha256.New()
- h.Write([]byte(ss))
- b, err := rsa.SignPKCS1v15(rand.Reader, signature, crypto.SHA256, h.Sum(nil))
- if err != nil {
- return "", err
- }
- sig := base64Encode(b)
- return fmt.Sprintf("%s.%s", ss, sig), nil
-}
-
-// base64Encode returns and Base64url encoded version of the input string with any
-// trailing "=" stripped.
-func base64Encode(b []byte) string {
- return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=")
-}
-
-// base64Decode decodes the Base64url encoded string
-func base64Decode(s string) ([]byte, error) {
- // add back missing padding
- switch len(s) % 4 {
- case 2:
- s += "=="
- case 3:
- s += "="
- }
- return base64.URLEncoding.DecodeString(s)
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/jwt/jwt.go b/kube2msb/src/vendor/golang.org/x/oauth2/jwt/jwt.go
deleted file mode 100644
index 205d23e..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/jwt/jwt.go
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2014 The oauth2 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 jwt implements the OAuth 2.0 JSON Web Token flow, commonly
-// known as "two-legged OAuth 2.0".
-//
-// See: https://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-12
-package jwt
-
-import (
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "net/http"
- "net/url"
- "strings"
- "time"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/internal"
- "golang.org/x/oauth2/jws"
-)
-
-var (
- defaultGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer"
- defaultHeader = &jws.Header{Algorithm: "RS256", Typ: "JWT"}
-)
-
-// Config is the configuration for using JWT to fetch tokens,
-// commonly known as "two-legged OAuth 2.0".
-type Config struct {
- // Email is the OAuth client identifier used when communicating with
- // the configured OAuth provider.
- Email string
-
- // PrivateKey contains the contents of an RSA private key or the
- // contents of a PEM file that contains a private key. The provided
- // private key is used to sign JWT payloads.
- // PEM containers with a passphrase are not supported.
- // Use the following command to convert a PKCS 12 file into a PEM.
- //
- // $ openssl pkcs12 -in key.p12 -out key.pem -nodes
- //
- PrivateKey []byte
-
- // Subject is the optional user to impersonate.
- Subject string
-
- // Scopes optionally specifies a list of requested permission scopes.
- Scopes []string
-
- // TokenURL is the endpoint required to complete the 2-legged JWT flow.
- TokenURL string
-}
-
-// TokenSource returns a JWT TokenSource using the configuration
-// in c and the HTTP client from the provided context.
-func (c *Config) TokenSource(ctx context.Context) oauth2.TokenSource {
- return oauth2.ReuseTokenSource(nil, jwtSource{ctx, c})
-}
-
-// Client returns an HTTP client wrapping the context's
-// HTTP transport and adding Authorization headers with tokens
-// obtained from c.
-//
-// The returned client and its Transport should not be modified.
-func (c *Config) Client(ctx context.Context) *http.Client {
- return oauth2.NewClient(ctx, c.TokenSource(ctx))
-}
-
-// jwtSource is a source that always does a signed JWT request for a token.
-// It should typically be wrapped with a reuseTokenSource.
-type jwtSource struct {
- ctx context.Context
- conf *Config
-}
-
-func (js jwtSource) Token() (*oauth2.Token, error) {
- pk, err := internal.ParseKey(js.conf.PrivateKey)
- if err != nil {
- return nil, err
- }
- hc := oauth2.NewClient(js.ctx, nil)
- claimSet := &jws.ClaimSet{
- Iss: js.conf.Email,
- Scope: strings.Join(js.conf.Scopes, " "),
- Aud: js.conf.TokenURL,
- }
- if subject := js.conf.Subject; subject != "" {
- claimSet.Sub = subject
- // prn is the old name of sub. Keep setting it
- // to be compatible with legacy OAuth 2.0 providers.
- claimSet.Prn = subject
- }
- payload, err := jws.Encode(defaultHeader, claimSet, pk)
- if err != nil {
- return nil, err
- }
- v := url.Values{}
- v.Set("grant_type", defaultGrantType)
- v.Set("assertion", payload)
- resp, err := hc.PostForm(js.conf.TokenURL, v)
- if err != nil {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
- }
- defer resp.Body.Close()
- body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
- if err != nil {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
- }
- if c := resp.StatusCode; c < 200 || c > 299 {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v\nResponse: %s", resp.Status, body)
- }
- // tokenRes is the JSON response body.
- var tokenRes struct {
- AccessToken string `json:"access_token"`
- TokenType string `json:"token_type"`
- IDToken string `json:"id_token"`
- ExpiresIn int64 `json:"expires_in"` // relative seconds from now
- }
- if err := json.Unmarshal(body, &tokenRes); err != nil {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
- }
- token := &oauth2.Token{
- AccessToken: tokenRes.AccessToken,
- TokenType: tokenRes.TokenType,
- }
- raw := make(map[string]interface{})
- json.Unmarshal(body, &raw) // no error checks for optional fields
- token = token.WithExtra(raw)
-
- if secs := tokenRes.ExpiresIn; secs > 0 {
- token.Expiry = time.Now().Add(time.Duration(secs) * time.Second)
- }
- if v := tokenRes.IDToken; v != "" {
- // decode returned id token to get expiry
- claimSet, err := jws.Decode(v)
- if err != nil {
- return nil, fmt.Errorf("oauth2: error decoding JWT token: %v", err)
- }
- token.Expiry = time.Unix(claimSet.Exp, 0)
- }
- return token, nil
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/oauth2.go b/kube2msb/src/vendor/golang.org/x/oauth2/oauth2.go
deleted file mode 100644
index dfcf238..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/oauth2.go
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright 2014 The oauth2 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 oauth2 provides support for making
-// OAuth2 authorized and authenticated HTTP requests.
-// It can additionally grant authorization with Bearer JWT.
-package oauth2
-
-import (
- "bytes"
- "errors"
- "net/http"
- "net/url"
- "strings"
- "sync"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2/internal"
-)
-
-// NoContext is the default context you should supply if not using
-// your own context.Context (see https://golang.org/x/net/context).
-var NoContext = context.TODO()
-
-// Config describes a typical 3-legged OAuth2 flow, with both the
-// client application information and the server's endpoint URLs.
-type Config struct {
- // ClientID is the application's ID.
- ClientID string
-
- // ClientSecret is the application's secret.
- ClientSecret string
-
- // Endpoint contains the resource server's token endpoint
- // URLs. These are constants specific to each server and are
- // often available via site-specific packages, such as
- // google.Endpoint or github.Endpoint.
- Endpoint Endpoint
-
- // RedirectURL is the URL to redirect users going through
- // the OAuth flow, after the resource owner's URLs.
- RedirectURL string
-
- // Scope specifies optional requested permissions.
- Scopes []string
-}
-
-// A TokenSource is anything that can return a token.
-type TokenSource interface {
- // Token returns a token or an error.
- // Token must be safe for concurrent use by multiple goroutines.
- // The returned Token must not be modified.
- Token() (*Token, error)
-}
-
-// Endpoint contains the OAuth 2.0 provider's authorization and token
-// endpoint URLs.
-type Endpoint struct {
- AuthURL string
- TokenURL string
-}
-
-var (
- // AccessTypeOnline and AccessTypeOffline are options passed
- // to the Options.AuthCodeURL method. They modify the
- // "access_type" field that gets sent in the URL returned by
- // AuthCodeURL.
- //
- // Online is the default if neither is specified. If your
- // application needs to refresh access tokens when the user
- // is not present at the browser, then use offline. This will
- // result in your application obtaining a refresh token the
- // first time your application exchanges an authorization
- // code for a user.
- AccessTypeOnline AuthCodeOption = SetAuthURLParam("access_type", "online")
- AccessTypeOffline AuthCodeOption = SetAuthURLParam("access_type", "offline")
-
- // ApprovalForce forces the users to view the consent dialog
- // and confirm the permissions request at the URL returned
- // from AuthCodeURL, even if they've already done so.
- ApprovalForce AuthCodeOption = SetAuthURLParam("approval_prompt", "force")
-)
-
-// An AuthCodeOption is passed to Config.AuthCodeURL.
-type AuthCodeOption interface {
- setValue(url.Values)
-}
-
-type setParam struct{ k, v string }
-
-func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) }
-
-// SetAuthURLParam builds an AuthCodeOption which passes key/value parameters
-// to a provider's authorization endpoint.
-func SetAuthURLParam(key, value string) AuthCodeOption {
- return setParam{key, value}
-}
-
-// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
-// that asks for permissions for the required scopes explicitly.
-//
-// State is a token to protect the user from CSRF attacks. You must
-// always provide a non-zero string and validate that it matches the
-// the state query parameter on your redirect callback.
-// See http://tools.ietf.org/html/rfc6749#section-10.12 for more info.
-//
-// Opts may include AccessTypeOnline or AccessTypeOffline, as well
-// as ApprovalForce.
-func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
- var buf bytes.Buffer
- buf.WriteString(c.Endpoint.AuthURL)
- v := url.Values{
- "response_type": {"code"},
- "client_id": {c.ClientID},
- "redirect_uri": internal.CondVal(c.RedirectURL),
- "scope": internal.CondVal(strings.Join(c.Scopes, " ")),
- "state": internal.CondVal(state),
- }
- for _, opt := range opts {
- opt.setValue(v)
- }
- if strings.Contains(c.Endpoint.AuthURL, "?") {
- buf.WriteByte('&')
- } else {
- buf.WriteByte('?')
- }
- buf.WriteString(v.Encode())
- return buf.String()
-}
-
-// PasswordCredentialsToken converts a resource owner username and password
-// pair into a token.
-//
-// Per the RFC, this grant type should only be used "when there is a high
-// degree of trust between the resource owner and the client (e.g., the client
-// is part of the device operating system or a highly privileged application),
-// and when other authorization grant types are not available."
-// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info.
-//
-// The HTTP client to use is derived from the context.
-// If nil, http.DefaultClient is used.
-func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) {
- return retrieveToken(ctx, c, url.Values{
- "grant_type": {"password"},
- "username": {username},
- "password": {password},
- "scope": internal.CondVal(strings.Join(c.Scopes, " ")),
- })
-}
-
-// Exchange converts an authorization code into a token.
-//
-// It is used after a resource provider redirects the user back
-// to the Redirect URI (the URL obtained from AuthCodeURL).
-//
-// The HTTP client to use is derived from the context.
-// If a client is not provided via the context, http.DefaultClient is used.
-//
-// The code will be in the *http.Request.FormValue("code"). Before
-// calling Exchange, be sure to validate FormValue("state").
-func (c *Config) Exchange(ctx context.Context, code string) (*Token, error) {
- return retrieveToken(ctx, c, url.Values{
- "grant_type": {"authorization_code"},
- "code": {code},
- "redirect_uri": internal.CondVal(c.RedirectURL),
- "scope": internal.CondVal(strings.Join(c.Scopes, " ")),
- })
-}
-
-// Client returns an HTTP client using the provided token.
-// The token will auto-refresh as necessary. The underlying
-// HTTP transport will be obtained using the provided context.
-// The returned client and its Transport should not be modified.
-func (c *Config) Client(ctx context.Context, t *Token) *http.Client {
- return NewClient(ctx, c.TokenSource(ctx, t))
-}
-
-// TokenSource returns a TokenSource that returns t until t expires,
-// automatically refreshing it as necessary using the provided context.
-//
-// Most users will use Config.Client instead.
-func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource {
- tkr := &tokenRefresher{
- ctx: ctx,
- conf: c,
- }
- if t != nil {
- tkr.refreshToken = t.RefreshToken
- }
- return &reuseTokenSource{
- t: t,
- new: tkr,
- }
-}
-
-// tokenRefresher is a TokenSource that makes "grant_type"=="refresh_token"
-// HTTP requests to renew a token using a RefreshToken.
-type tokenRefresher struct {
- ctx context.Context // used to get HTTP requests
- conf *Config
- refreshToken string
-}
-
-// WARNING: Token is not safe for concurrent access, as it
-// updates the tokenRefresher's refreshToken field.
-// Within this package, it is used by reuseTokenSource which
-// synchronizes calls to this method with its own mutex.
-func (tf *tokenRefresher) Token() (*Token, error) {
- if tf.refreshToken == "" {
- return nil, errors.New("oauth2: token expired and refresh token is not set")
- }
-
- tk, err := retrieveToken(tf.ctx, tf.conf, url.Values{
- "grant_type": {"refresh_token"},
- "refresh_token": {tf.refreshToken},
- })
-
- if err != nil {
- return nil, err
- }
- if tf.refreshToken != tk.RefreshToken {
- tf.refreshToken = tk.RefreshToken
- }
- return tk, err
-}
-
-// reuseTokenSource is a TokenSource that holds a single token in memory
-// and validates its expiry before each call to retrieve it with
-// Token. If it's expired, it will be auto-refreshed using the
-// new TokenSource.
-type reuseTokenSource struct {
- new TokenSource // called when t is expired.
-
- mu sync.Mutex // guards t
- t *Token
-}
-
-// Token returns the current token if it's still valid, else will
-// refresh the current token (using r.Context for HTTP client
-// information) and return the new one.
-func (s *reuseTokenSource) Token() (*Token, error) {
- s.mu.Lock()
- defer s.mu.Unlock()
- if s.t.Valid() {
- return s.t, nil
- }
- t, err := s.new.Token()
- if err != nil {
- return nil, err
- }
- s.t = t
- return t, nil
-}
-
-// StaticTokenSource returns a TokenSource that always returns the same token.
-// Because the provided token t is never refreshed, StaticTokenSource is only
-// useful for tokens that never expire.
-func StaticTokenSource(t *Token) TokenSource {
- return staticTokenSource{t}
-}
-
-// staticTokenSource is a TokenSource that always returns the same Token.
-type staticTokenSource struct {
- t *Token
-}
-
-func (s staticTokenSource) Token() (*Token, error) {
- return s.t, nil
-}
-
-// HTTPClient is the context key to use with golang.org/x/net/context's
-// WithValue function to associate an *http.Client value with a context.
-var HTTPClient internal.ContextKey
-
-// NewClient creates an *http.Client from a Context and TokenSource.
-// The returned client is not valid beyond the lifetime of the context.
-//
-// As a special case, if src is nil, a non-OAuth2 client is returned
-// using the provided context. This exists to support related OAuth2
-// packages.
-func NewClient(ctx context.Context, src TokenSource) *http.Client {
- if src == nil {
- c, err := internal.ContextClient(ctx)
- if err != nil {
- return &http.Client{Transport: internal.ErrorTransport{err}}
- }
- return c
- }
- return &http.Client{
- Transport: &Transport{
- Base: internal.ContextTransport(ctx),
- Source: ReuseTokenSource(nil, src),
- },
- }
-}
-
-// ReuseTokenSource returns a TokenSource which repeatedly returns the
-// same token as long as it's valid, starting with t.
-// When its cached token is invalid, a new token is obtained from src.
-//
-// ReuseTokenSource is typically used to reuse tokens from a cache
-// (such as a file on disk) between runs of a program, rather than
-// obtaining new tokens unnecessarily.
-//
-// The initial token t may be nil, in which case the TokenSource is
-// wrapped in a caching version if it isn't one already. This also
-// means it's always safe to wrap ReuseTokenSource around any other
-// TokenSource without adverse effects.
-func ReuseTokenSource(t *Token, src TokenSource) TokenSource {
- // Don't wrap a reuseTokenSource in itself. That would work,
- // but cause an unnecessary number of mutex operations.
- // Just build the equivalent one.
- if rt, ok := src.(*reuseTokenSource); ok {
- if t == nil {
- // Just use it directly.
- return rt
- }
- src = rt.new
- }
- return &reuseTokenSource{
- t: t,
- new: src,
- }
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/token.go b/kube2msb/src/vendor/golang.org/x/oauth2/token.go
deleted file mode 100644
index ebbdddb..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/token.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2014 The oauth2 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 oauth2
-
-import (
- "net/http"
- "net/url"
- "strings"
- "time"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2/internal"
-)
-
-// expiryDelta determines how earlier a token should be considered
-// expired than its actual expiration time. It is used to avoid late
-// expirations due to client-server time mismatches.
-const expiryDelta = 10 * time.Second
-
-// Token represents the crendentials used to authorize
-// the requests to access protected resources on the OAuth 2.0
-// provider's backend.
-//
-// Most users of this package should not access fields of Token
-// directly. They're exported mostly for use by related packages
-// implementing derivative OAuth2 flows.
-type Token struct {
- // AccessToken is the token that authorizes and authenticates
- // the requests.
- AccessToken string `json:"access_token"`
-
- // TokenType is the type of token.
- // The Type method returns either this or "Bearer", the default.
- TokenType string `json:"token_type,omitempty"`
-
- // RefreshToken is a token that's used by the application
- // (as opposed to the user) to refresh the access token
- // if it expires.
- RefreshToken string `json:"refresh_token,omitempty"`
-
- // Expiry is the optional expiration time of the access token.
- //
- // If zero, TokenSource implementations will reuse the same
- // token forever and RefreshToken or equivalent
- // mechanisms for that TokenSource will not be used.
- Expiry time.Time `json:"expiry,omitempty"`
-
- // raw optionally contains extra metadata from the server
- // when updating a token.
- raw interface{}
-}
-
-// Type returns t.TokenType if non-empty, else "Bearer".
-func (t *Token) Type() string {
- if strings.EqualFold(t.TokenType, "bearer") {
- return "Bearer"
- }
- if strings.EqualFold(t.TokenType, "mac") {
- return "MAC"
- }
- if strings.EqualFold(t.TokenType, "basic") {
- return "Basic"
- }
- if t.TokenType != "" {
- return t.TokenType
- }
- return "Bearer"
-}
-
-// SetAuthHeader sets the Authorization header to r using the access
-// token in t.
-//
-// This method is unnecessary when using Transport or an HTTP Client
-// returned by this package.
-func (t *Token) SetAuthHeader(r *http.Request) {
- r.Header.Set("Authorization", t.Type()+" "+t.AccessToken)
-}
-
-// WithExtra returns a new Token that's a clone of t, but using the
-// provided raw extra map. This is only intended for use by packages
-// implementing derivative OAuth2 flows.
-func (t *Token) WithExtra(extra interface{}) *Token {
- t2 := new(Token)
- *t2 = *t
- t2.raw = extra
- return t2
-}
-
-// Extra returns an extra field.
-// Extra fields are key-value pairs returned by the server as a
-// part of the token retrieval response.
-func (t *Token) Extra(key string) interface{} {
- if vals, ok := t.raw.(url.Values); ok {
- // TODO(jbd): Cast numeric values to int64 or float64.
- return vals.Get(key)
- }
- if raw, ok := t.raw.(map[string]interface{}); ok {
- return raw[key]
- }
- return nil
-}
-
-// expired reports whether the token is expired.
-// t must be non-nil.
-func (t *Token) expired() bool {
- if t.Expiry.IsZero() {
- return false
- }
- return t.Expiry.Add(-expiryDelta).Before(time.Now())
-}
-
-// Valid reports whether t is non-nil, has an AccessToken, and is not expired.
-func (t *Token) Valid() bool {
- return t != nil && t.AccessToken != "" && !t.expired()
-}
-
-// tokenFromInternal maps an *internal.Token struct into
-// a *Token struct.
-func tokenFromInternal(t *internal.Token) *Token {
- if t == nil {
- return nil
- }
- return &Token{
- AccessToken: t.AccessToken,
- TokenType: t.TokenType,
- RefreshToken: t.RefreshToken,
- Expiry: t.Expiry,
- raw: t.Raw,
- }
-}
-
-// retrieveToken takes a *Config and uses that to retrieve an *internal.Token.
-// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along
-// with an error..
-func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
- tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v)
- if err != nil {
- return nil, err
- }
- return tokenFromInternal(tk), nil
-}
diff --git a/kube2msb/src/vendor/golang.org/x/oauth2/transport.go b/kube2msb/src/vendor/golang.org/x/oauth2/transport.go
deleted file mode 100644
index 90db088..0000000
--- a/kube2msb/src/vendor/golang.org/x/oauth2/transport.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2014 The oauth2 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 oauth2
-
-import (
- "errors"
- "io"
- "net/http"
- "sync"
-)
-
-// Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests,
-// wrapping a base RoundTripper and adding an Authorization header
-// with a token from the supplied Sources.
-//
-// Transport is a low-level mechanism. Most code will use the
-// higher-level Config.Client method instead.
-type Transport struct {
- // Source supplies the token to add to outgoing requests'
- // Authorization headers.
- Source TokenSource
-
- // Base is the base RoundTripper used to make HTTP requests.
- // If nil, http.DefaultTransport is used.
- Base http.RoundTripper
-
- mu sync.Mutex // guards modReq
- modReq map[*http.Request]*http.Request // original -> modified
-}
-
-// RoundTrip authorizes and authenticates the request with an
-// access token. If no token exists or token is expired,
-// tries to refresh/fetch a new token.
-func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
- if t.Source == nil {
- return nil, errors.New("oauth2: Transport's Source is nil")
- }
- token, err := t.Source.Token()
- if err != nil {
- return nil, err
- }
-
- req2 := cloneRequest(req) // per RoundTripper contract
- token.SetAuthHeader(req2)
- t.setModReq(req, req2)
- res, err := t.base().RoundTrip(req2)
- if err != nil {
- t.setModReq(req, nil)
- return nil, err
- }
- res.Body = &onEOFReader{
- rc: res.Body,
- fn: func() { t.setModReq(req, nil) },
- }
- return res, nil
-}
-
-// CancelRequest cancels an in-flight request by closing its connection.
-func (t *Transport) CancelRequest(req *http.Request) {
- type canceler interface {
- CancelRequest(*http.Request)
- }
- if cr, ok := t.base().(canceler); ok {
- t.mu.Lock()
- modReq := t.modReq[req]
- delete(t.modReq, req)
- t.mu.Unlock()
- cr.CancelRequest(modReq)
- }
-}
-
-func (t *Transport) base() http.RoundTripper {
- if t.Base != nil {
- return t.Base
- }
- return http.DefaultTransport
-}
-
-func (t *Transport) setModReq(orig, mod *http.Request) {
- t.mu.Lock()
- defer t.mu.Unlock()
- if t.modReq == nil {
- t.modReq = make(map[*http.Request]*http.Request)
- }
- if mod == nil {
- delete(t.modReq, orig)
- } else {
- t.modReq[orig] = mod
- }
-}
-
-// cloneRequest returns a clone of the provided *http.Request.
-// The clone is a shallow copy of the struct and its Header map.
-func cloneRequest(r *http.Request) *http.Request {
- // shallow copy of the struct
- r2 := new(http.Request)
- *r2 = *r
- // deep copy of the Header
- r2.Header = make(http.Header, len(r.Header))
- for k, s := range r.Header {
- r2.Header[k] = append([]string(nil), s...)
- }
- return r2
-}
-
-type onEOFReader struct {
- rc io.ReadCloser
- fn func()
-}
-
-func (r *onEOFReader) Read(p []byte) (n int, err error) {
- n, err = r.rc.Read(p)
- if err == io.EOF {
- r.runFunc()
- }
- return
-}
-
-func (r *onEOFReader) Close() error {
- err := r.rc.Close()
- r.runFunc()
- return err
-}
-
-func (r *onEOFReader) runFunc() {
- if fn := r.fn; fn != nil {
- fn()
- r.fn = nil
- }
-}