• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package internal contains support packages for oauth2 package.
6package internal
7
8import (
9	"net/http"
10
11	"golang.org/x/net/context"
12)
13
14// HTTPClient is the context key to use with golang.org/x/net/context's
15// WithValue function to associate an *http.Client value with a context.
16var HTTPClient ContextKey
17
18// ContextKey is just an empty struct. It exists so HTTPClient can be
19// an immutable public variable with a unique type. It's immutable
20// because nobody else can create a ContextKey, being unexported.
21type ContextKey struct{}
22
23// ContextClientFunc is a func which tries to return an *http.Client
24// given a Context value. If it returns an error, the search stops
25// with that error.  If it returns (nil, nil), the search continues
26// down the list of registered funcs.
27type ContextClientFunc func(context.Context) (*http.Client, error)
28
29var contextClientFuncs []ContextClientFunc
30
31func RegisterContextClientFunc(fn ContextClientFunc) {
32	contextClientFuncs = append(contextClientFuncs, fn)
33}
34
35func ContextClient(ctx context.Context) (*http.Client, error) {
36	if ctx != nil {
37		if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok {
38			return hc, nil
39		}
40	}
41	for _, fn := range contextClientFuncs {
42		c, err := fn(ctx)
43		if err != nil {
44			return nil, err
45		}
46		if c != nil {
47			return c, nil
48		}
49	}
50	return http.DefaultClient, nil
51}
52
53func ContextTransport(ctx context.Context) http.RoundTripper {
54	hc, err := ContextClient(ctx)
55	// This is a rare error case (somebody using nil on App Engine).
56	if err != nil {
57		return ErrorTransport{err}
58	}
59	return hc.Transport
60}
61
62// ErrorTransport returns the specified error on RoundTrip.
63// This RoundTripper should be used in rare error cases where
64// error handling can be postponed to response handling time.
65type ErrorTransport struct{ Err error }
66
67func (t ErrorTransport) RoundTrip(*http.Request) (*http.Response, error) {
68	return nil, t.Err
69}
70