From e5f60fe9ddc52c954fbb4c2722af450e7ff72b2a Mon Sep 17 00:00:00 2001
From: Eric Chiang <eric.chiang@coreos.com>
Date: Wed, 8 Mar 2017 10:33:36 -0800
Subject: [PATCH] vendor: revendor

---
 glide.lock                                    |   7 +-
 vendor/github.com/coreos/go-oidc/jwks.go      |   5 +-
 vendor/github.com/coreos/go-oidc/oidc.go      |  46 +++--
 vendor/github.com/coreos/go-oidc/verify.go    | 188 ++++++++----------
 .../x/net/context/ctxhttp/ctxhttp.go          |  74 -------
 .../x/net/context/ctxhttp/ctxhttp_pre17.go    | 147 --------------
 6 files changed, 118 insertions(+), 349 deletions(-)
 delete mode 100644 vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
 delete mode 100644 vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go

diff --git a/glide.lock b/glide.lock
index 3edb6fb3..97eb92d5 100644
--- a/glide.lock
+++ b/glide.lock
@@ -1,5 +1,5 @@
-hash: 1207c251a7dab3b824746d66219beabc40f0b1d3c08ed90ac50f5bbdb8872631
-updated: 2017-01-25T20:32:43.599648533+01:00
+hash: fbef1f81a0f86f519714bbe568692a92709c446ef487a3fa9875e58f86e14430
+updated: 2017-03-08T10:31:06.364335442-08:00
 imports:
 - name: github.com/beevik/etree
   version: 4cd0dd976db869f817248477718071a28e978df0
@@ -8,7 +8,7 @@ imports:
   subpackages:
   - crdb
 - name: github.com/coreos/go-oidc
-  version: 2b5d73091ea4b7ddb15e3ac00077f153120b5b61
+  version: be73733bb8cc830d0205609b95d125215f8e9c70
 - name: github.com/ghodss/yaml
   version: bea76d6a4713e18b7f5321a2b020738552def3ea
 - name: github.com/go-sql-driver/mysql
@@ -62,7 +62,6 @@ imports:
   version: 6a513affb38dc9788b449d59ffed099b8de18fa0
   subpackages:
   - context
-  - context/ctxhttp
   - http2
   - http2/hpack
   - internal/timeseries
diff --git a/vendor/github.com/coreos/go-oidc/jwks.go b/vendor/github.com/coreos/go-oidc/jwks.go
index 413f392f..0f3cf0c9 100644
--- a/vendor/github.com/coreos/go-oidc/jwks.go
+++ b/vendor/github.com/coreos/go-oidc/jwks.go
@@ -1,6 +1,7 @@
 package oidc
 
 import (
+	"context"
 	"encoding/json"
 	"fmt"
 	"io/ioutil"
@@ -9,8 +10,6 @@ import (
 	"time"
 
 	"github.com/pquerna/cachecontrol"
-	"golang.org/x/net/context"
-	"golang.org/x/net/context/ctxhttp"
 	jose "gopkg.in/square/go-jose.v2"
 )
 
@@ -163,7 +162,7 @@ func (r *remoteKeySet) updateKeys(ctx context.Context) error {
 		return fmt.Errorf("oidc: can't create request: %v", err)
 	}
 
-	resp, err := ctxhttp.Do(ctx, clientFromContext(ctx), req)
+	resp, err := doRequest(ctx, req)
 	if err != nil {
 		return fmt.Errorf("oidc: get keys failed %v", err)
 	}
diff --git a/vendor/github.com/coreos/go-oidc/oidc.go b/vendor/github.com/coreos/go-oidc/oidc.go
index 62be15d3..a14dca0c 100644
--- a/vendor/github.com/coreos/go-oidc/oidc.go
+++ b/vendor/github.com/coreos/go-oidc/oidc.go
@@ -2,6 +2,7 @@
 package oidc
 
 import (
+	"context"
 	"encoding/json"
 	"errors"
 	"fmt"
@@ -10,8 +11,6 @@ import (
 	"strings"
 	"time"
 
-	"golang.org/x/net/context"
-	"golang.org/x/net/context/ctxhttp"
 	"golang.org/x/oauth2"
 	jose "gopkg.in/square/go-jose.v2"
 )
@@ -46,11 +45,12 @@ func ClientContext(ctx context.Context, client *http.Client) context.Context {
 	return context.WithValue(ctx, oauth2.HTTPClient, client)
 }
 
-func clientFromContext(ctx context.Context) *http.Client {
-	if client, ok := ctx.Value(oauth2.HTTPClient).(*http.Client); ok {
-		return client
+func doRequest(ctx context.Context, req *http.Request) (*http.Response, error) {
+	client := http.DefaultClient
+	if c, ok := ctx.Value(oauth2.HTTPClient).(*http.Client); ok {
+		client = c
 	}
-	return http.DefaultClient
+	return client.Do(req.WithContext(ctx))
 }
 
 // Provider represents an OpenID Connect server's configuration.
@@ -85,7 +85,11 @@ type providerJSON struct {
 // or "https://login.salesforce.com".
 func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
 	wellKnown := strings.TrimSuffix(issuer, "/") + "/.well-known/openid-configuration"
-	resp, err := ctxhttp.Get(ctx, clientFromContext(ctx), wellKnown)
+	req, err := http.NewRequest("GET", wellKnown, nil)
+	if err != nil {
+		return nil, err
+	}
+	resp, err := doRequest(ctx, req)
 	if err != nil {
 		return nil, err
 	}
@@ -174,7 +178,7 @@ func (p *Provider) UserInfo(ctx context.Context, tokenSource oauth2.TokenSource)
 	}
 	token.SetAuthHeader(req)
 
-	resp, err := ctxhttp.Do(ctx, clientFromContext(ctx), req)
+	resp, err := doRequest(ctx, req)
 	if err != nil {
 		return nil, err
 	}
@@ -201,19 +205,35 @@ func (p *Provider) UserInfo(ctx context.Context, tokenSource oauth2.TokenSource)
 // The ID Token only holds fields OpenID Connect requires. To access additional
 // claims returned by the server, use the Claims method.
 type IDToken struct {
-	// The URL of the server which issued this token. This will always be the same
-	// as the URL used for initial discovery.
+	// The URL of the server which issued this token. OpenID Connect
+	// requires this value always be identical to the URL used for
+	// initial discovery.
+	//
+	// Note: Because of a known issue with Google Accounts' implementation
+	// this value may differ when using Google.
+	//
+	// See: https://developers.google.com/identity/protocols/OpenIDConnect#obtainuserinfo
 	Issuer string
 
-	// The client, or set of clients, that this token is issued for.
+	// The client ID, or set of client IDs, that this token is issued for. For
+	// common uses, this is the client that initialized the auth flow.
+	//
+	// This package ensures the audience contains an expected value.
 	Audience []string
 
 	// A unique string which identifies the end user.
 	Subject string
 
+	// Expiry of the token. Ths package will not process tokens that have
+	// expired unless that validation is explicitly turned off.
+	Expiry time.Time
+	// When the token was issued by the provider.
 	IssuedAt time.Time
-	Expiry   time.Time
-	Nonce    string
+
+	// Initial nonce provided during the authentication redirect.
+	//
+	// If present, this package ensures this is a valid nonce.
+	Nonce string
 
 	// Raw payload of the id_token.
 	claims []byte
diff --git a/vendor/github.com/coreos/go-oidc/verify.go b/vendor/github.com/coreos/go-oidc/verify.go
index 67185a26..2b67aa9c 100644
--- a/vendor/github.com/coreos/go-oidc/verify.go
+++ b/vendor/github.com/coreos/go-oidc/verify.go
@@ -2,6 +2,7 @@ package oidc
 
 import (
 	"bytes"
+	"context"
 	"encoding/base64"
 	"encoding/json"
 	"errors"
@@ -9,61 +10,71 @@ import (
 	"strings"
 	"time"
 
-	"golang.org/x/net/context"
 	"golang.org/x/oauth2"
 	jose "gopkg.in/square/go-jose.v2"
 )
 
+const (
+	issuerGoogleAccounts         = "https://accounts.google.com"
+	issuerGoogleAccountsNoScheme = "accounts.google.com"
+)
+
 // IDTokenVerifier provides verification for ID Tokens.
 type IDTokenVerifier struct {
 	keySet *remoteKeySet
-	config *verificationConfig
-}
-
-// verificationConfig is the unexported configuration for an IDTokenVerifier.
-//
-// Users interact with this struct using a VerificationOption.
-type verificationConfig struct {
+	config *Config
 	issuer string
-	// If provided, this value must be in the ID Token audiences.
-	audience string
-	// If not nil, check the expiry of the id token.
-	checkExpiry func() time.Time
-	// If specified, only these sets of algorithms may be used to sign the JWT.
-	requiredAlgs []string
-	// If not nil, don't verify nonce.
-	nonceSource NonceSource
 }
 
-// VerificationOption provides additional checks on ID Tokens.
-type VerificationOption interface {
-	// Unexport this method so other packages can't implement this interface.
-	updateConfig(c *verificationConfig)
+// Config is the configuration for an IDTokenVerifier.
+type Config struct {
+	// Expected audience of the token. For a majority of the cases this is expected to be
+	// the ID of the client that initialized the login flow. It may occasionally differ if
+	// the provider supports the authorizing party (azp) claim.
+	//
+	// If not provided, users must explicitly set SkipClientIDCheck.
+	ClientID string
+	// Method to verify the ID Token nonce. If a nonce is present and this method
+	// is nil, users must explicitly set SkipNonceCheck.
+	//
+	// If the ID Token nonce is empty, for example if the client didn't provide a nonce in
+	// the initial redirect, this may be nil.
+	ClaimNonce func(nonce string) error
+	// If specified, only this set of algorithms may be used to sign the JWT.
+	//
+	// Since many providers only support RS256, SupportedSigningAlgs defaults to this value.
+	SupportedSigningAlgs []string
+
+	// If true, no ClientID check performed. Must be true if ClientID field is empty.
+	SkipClientIDCheck bool
+	// If true, token expiry is not checked.
+	SkipExpiryCheck bool
+	// If true, nonce claim is not checked. Must be true if ClaimNonce field is empty.
+	SkipNonceCheck bool
+
+	// Time function to check Token expiry. Defaults to time.Now
+	Now func() time.Time
 }
 
 // Verifier returns an IDTokenVerifier that uses the provider's key set to verify JWTs.
 //
 // The returned IDTokenVerifier is tied to the Provider's context and its behavior is
 // undefined once the Provider's context is canceled.
-func (p *Provider) Verifier(options ...VerificationOption) *IDTokenVerifier {
-	config := &verificationConfig{issuer: p.issuer}
-	for _, option := range options {
-		option.updateConfig(config)
-	}
+func (p *Provider) Verifier(config *Config) *IDTokenVerifier {
 
-	return newVerifier(p.remoteKeySet, config)
+	return newVerifier(p.remoteKeySet, config, p.issuer)
 }
 
-func newVerifier(keySet *remoteKeySet, config *verificationConfig) *IDTokenVerifier {
-	// As discussed in the godocs for VerifrySigningAlg, because almost all providers
-	// only support RS256, default to only allowing it.
-	if len(config.requiredAlgs) == 0 {
-		config.requiredAlgs = []string{RS256}
+func newVerifier(keySet *remoteKeySet, config *Config, issuer string) *IDTokenVerifier {
+	// If SupportedSigningAlgs is empty defaults to only support RS256.
+	if len(config.SupportedSigningAlgs) == 0 {
+		config.SupportedSigningAlgs = []string{RS256}
 	}
 
 	return &IDTokenVerifier{
 		keySet: keySet,
 		config: config,
+		issuer: issuer,
 	}
 }
 
@@ -89,7 +100,7 @@ func contains(sli []string, ele string) bool {
 }
 
 // Verify parses a raw ID Token, verifies it's been signed by the provider, preforms
-// any additional checks passed as VerifictionOptions, and returns the payload.
+// any additional checks depending on the Config, and returns the payload.
 //
 // See: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
 //
@@ -134,20 +145,38 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
 	}
 
 	// Check issuer.
-	if t.Issuer != v.config.issuer {
-		return nil, fmt.Errorf("oidc: id token issued by a different provider, expected %q got %q", v.config.issuer, t.Issuer)
+	if t.Issuer != v.issuer {
+		// Google sometimes returns "accounts.google.com" as the issuer claim instead of
+		// the required "https://accounts.google.com". Detect this case and allow it only
+		// for Google.
+		//
+		// We will not add hooks to let other providers go off spec like this.
+		if !(v.issuer == issuerGoogleAccounts && t.Issuer == issuerGoogleAccountsNoScheme) {
+			return nil, fmt.Errorf("oidc: id token issued by a different provider, expected %q got %q", v.issuer, t.Issuer)
+		}
 	}
 
-	// If a client ID has been provided, make sure it's part of the audience.
-	if v.config.audience != "" {
-		if !contains(t.Audience, v.config.audience) {
-			return nil, fmt.Errorf("oidc: expected audience %q got %q", v.config.audience, t.Audience)
+	// If a client ID has been provided, make sure it's part of the audience. SkipClientIDCheck must be true if ClientID is empty.
+	//
+	// This check DOES NOT ensure that the ClientID is the party to which the ID Token was issued (i.e. Authorized party).
+	if !v.config.SkipClientIDCheck {
+		if v.config.ClientID != "" {
+			if !contains(t.Audience, v.config.ClientID) {
+				return nil, fmt.Errorf("oidc: expected audience %q got %q", v.config.ClientID, t.Audience)
+			}
+		} else {
+			return nil, fmt.Errorf("oidc: Invalid configuration. ClientID must be provided or SkipClientIDCheck must be set.")
 		}
 	}
 
-	// If a checkExpiry is specified, make sure token is not expired.
-	if v.config.checkExpiry != nil {
-		if t.Expiry.Before(v.config.checkExpiry()) {
+	// If a SkipExpiryCheck is false, make sure token is not expired.
+	if !v.config.SkipExpiryCheck {
+		now := time.Now
+		if v.config.Now != nil {
+			now = v.config.Now
+		}
+
+		if t.Expiry.Before(now()) {
 			return nil, fmt.Errorf("oidc: token is expired (Token Expiry: %v)", t.Expiry)
 		}
 	}
@@ -155,14 +184,14 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
 	// If a set of required algorithms has been provided, ensure that the signatures use those.
 	var keyIDs, gotAlgs []string
 	for _, sig := range jws.Signatures {
-		if len(v.config.requiredAlgs) == 0 || contains(v.config.requiredAlgs, sig.Header.Algorithm) {
+		if len(v.config.SupportedSigningAlgs) == 0 || contains(v.config.SupportedSigningAlgs, sig.Header.Algorithm) {
 			keyIDs = append(keyIDs, sig.Header.KeyID)
 		} else {
 			gotAlgs = append(gotAlgs, sig.Header.Algorithm)
 		}
 	}
 	if len(keyIDs) == 0 {
-		return nil, fmt.Errorf("oidc: no signatures use a require algorithm, expected %q got %q", v.config.requiredAlgs, gotAlgs)
+		return nil, fmt.Errorf("oidc: no signatures use a supported algorithm, expected %q got %q", v.config.SupportedSigningAlgs, gotAlgs)
 	}
 
 	// Get keys from the remote key set. This may trigger a re-sync.
@@ -192,79 +221,22 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
 
 	// Check the nonce after we've verified the token. We don't want to allow unverified
 	// payloads to trigger a nonce lookup.
-	if v.config.nonceSource != nil {
-		if err := v.config.nonceSource.ClaimNonce(t.Nonce); err != nil {
-			return nil, err
+	// If SkipNonceCheck is not set ClaimNonce cannot be Nil.
+	if !v.config.SkipNonceCheck && t.Nonce != "" {
+		if v.config.ClaimNonce != nil {
+			if err := v.config.ClaimNonce(t.Nonce); err != nil {
+				return nil, err
+			}
+		} else {
+			return nil, fmt.Errorf("oidc: Invalid configuration. ClaimNonce must be provided or SkipNonceCheck must be set.")
 		}
 	}
 
 	return t, nil
 }
 
-// VerifyAudience ensures that an ID Token was issued for the specific client.
-//
-// Note that a verified token may be valid for other clients, as OpenID Connect allows a token to have
-// multiple audiences.
-func VerifyAudience(clientID string) VerificationOption {
-	return clientVerifier{clientID}
-}
-
-type clientVerifier struct {
-	clientID string
-}
-
-func (v clientVerifier) updateConfig(c *verificationConfig) {
-	c.audience = v.clientID
-}
-
-// VerifyExpiry ensures that an ID Token has not expired.
-func VerifyExpiry() VerificationOption {
-	return expiryVerifier{}
-}
-
-type expiryVerifier struct{}
-
-func (v expiryVerifier) updateConfig(c *verificationConfig) {
-	c.checkExpiry = time.Now
-}
-
-// VerifySigningAlg enforces that an ID Token is signed by a specific signing algorithm.
-//
-// Because so many providers only support RS256, if this verifiction option isn't used,
-// the IDTokenVerifier defaults to only allowing RS256.
-func VerifySigningAlg(allowedAlgs ...string) VerificationOption {
-	return algVerifier{allowedAlgs}
-}
-
-type algVerifier struct {
-	algs []string
-}
-
-func (v algVerifier) updateConfig(c *verificationConfig) {
-	c.requiredAlgs = v.algs
-}
-
 // Nonce returns an auth code option which requires the ID Token created by the
 // OpenID Connect provider to contain the specified nonce.
 func Nonce(nonce string) oauth2.AuthCodeOption {
 	return oauth2.SetAuthURLParam("nonce", nonce)
 }
-
-// NonceSource represents a source which can verify a nonce is valid and has not
-// been claimed before.
-type NonceSource interface {
-	ClaimNonce(nonce string) error
-}
-
-// VerifyNonce ensures that the ID Token contains a nonce which can be claimed by the nonce source.
-func VerifyNonce(source NonceSource) VerificationOption {
-	return nonceVerifier{source}
-}
-
-type nonceVerifier struct {
-	nonceSource NonceSource
-}
-
-func (n nonceVerifier) updateConfig(c *verificationConfig) {
-	c.nonceSource = n.nonceSource
-}
diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
deleted file mode 100644
index 606cf1f9..00000000
--- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2016 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.7
-
-// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
-package ctxhttp // import "golang.org/x/net/context/ctxhttp"
-
-import (
-	"io"
-	"net/http"
-	"net/url"
-	"strings"
-
-	"golang.org/x/net/context"
-)
-
-// Do sends an HTTP request with the provided http.Client and returns
-// an HTTP response.
-//
-// If the client is nil, http.DefaultClient is used.
-//
-// The provided ctx must be non-nil. If it 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
-	}
-	resp, err := client.Do(req.WithContext(ctx))
-	// If we got an error, and the context has been canceled,
-	// the context's error is probably more useful.
-	if err != nil {
-		select {
-		case <-ctx.Done():
-			err = ctx.Err()
-		default:
-		}
-	}
-	return resp, err
-}
-
-// 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()))
-}
diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
deleted file mode 100644
index 926870cc..00000000
--- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
+++ /dev/null
@@ -1,147 +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.7
-
-package ctxhttp // import "golang.org/x/net/context/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
-	}
-
-	// TODO(djd): Respect any existing value of req.Cancel.
-	cancel := make(chan struct{})
-	req.Cancel = cancel
-
-	type responseAndError struct {
-		resp *http.Response
-		err  error
-	}
-	result := make(chan responseAndError, 1)
-
-	// Make local copies of test hooks closed over by goroutines below.
-	// Prevents data races in tests.
-	testHookDoReturned := testHookDoReturned
-	testHookDidBodyClose := testHookDidBodyClose
-
-	go func() {
-		resp, err := client.Do(req)
-		testHookDoReturned()
-		result <- responseAndError{resp, err}
-	}()
-
-	var resp *http.Response
-
-	select {
-	case <-ctx.Done():
-		testHookContextDoneBeforeHeaders()
-		close(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():
-			close(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
-}
-- 
GitLab