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