1
0
Fork 1
mirror of https://github.com/distribution/distribution synced 2024-10-14 11:35:12 +00:00

Add base transport to interface

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
Derek McGowan 2015-05-12 12:04:18 -07:00
parent c6b51970cd
commit a15806ed9c
2 changed files with 33 additions and 22 deletions

View file

@ -37,16 +37,15 @@ type RepositoryConfig struct {
Header http.Header Header http.Header
AuthSource Authorizer AuthSource Authorizer
//TODO(dmcgowan): Add tls config BaseTransport http.RoundTripper
} }
// HTTPClient returns a new HTTP client configured for this configuration // HTTPClient returns a new HTTP client configured for this configuration
func (rc *RepositoryConfig) HTTPClient() (*http.Client, error) { func (rc *RepositoryConfig) HTTPClient() (*http.Client, error) {
// TODO(dmcgowan): create base http.Transport with proper TLS configuration
transport := &Transport{ transport := &Transport{
ExtraHeader: rc.Header, ExtraHeader: rc.Header,
AuthSource: rc.AuthSource, AuthSource: rc.AuthSource,
Base: rc.BaseTransport,
} }
client := &http.Client{ client := &http.Client{
@ -62,25 +61,27 @@ func (rc *RepositoryConfig) HTTPClient() (*http.Client, error) {
// requested. Basic authentication may either be done to the token source or // requested. Basic authentication may either be done to the token source or
// directly with the requested endpoint depending on the endpoint's // directly with the requested endpoint depending on the endpoint's
// WWW-Authenticate header. // WWW-Authenticate header.
func NewTokenAuthorizer(creds CredentialStore, header http.Header, scope TokenScope) Authorizer { func NewTokenAuthorizer(creds CredentialStore, transport http.RoundTripper, header http.Header, scope TokenScope) Authorizer {
return &tokenAuthorizer{ return &tokenAuthorizer{
header: header, header: header,
challenges: map[string]map[string]authorizationChallenge{}, challenges: map[string]map[string]authorizationChallenge{},
handlers: []AuthenticationHandler{ handlers: []AuthenticationHandler{
NewTokenHandler(creds, scope, header), NewTokenHandler(transport, creds, scope, header),
NewBasicHandler(creds), NewBasicHandler(creds),
}, },
transport: transport,
} }
} }
// NewAuthorizer creates an authorizer which can handle multiple authentication // NewAuthorizer creates an authorizer which can handle multiple authentication
// schemes. The handlers are tried in order, the higher priority authentication // schemes. The handlers are tried in order, the higher priority authentication
// methods should be first. // methods should be first.
func NewAuthorizer(header http.Header, handlers ...AuthenticationHandler) Authorizer { func NewAuthorizer(transport http.RoundTripper, header http.Header, handlers ...AuthenticationHandler) Authorizer {
return &tokenAuthorizer{ return &tokenAuthorizer{
header: header, header: header,
challenges: map[string]map[string]authorizationChallenge{}, challenges: map[string]map[string]authorizationChallenge{},
handlers: handlers, handlers: handlers,
transport: transport,
} }
} }
@ -88,11 +89,7 @@ type tokenAuthorizer struct {
header http.Header header http.Header
challenges map[string]map[string]authorizationChallenge challenges map[string]map[string]authorizationChallenge
handlers []AuthenticationHandler handlers []AuthenticationHandler
} transport http.RoundTripper
func (ta *tokenAuthorizer) client() *http.Client {
// TODO(dmcgowan): Use same transport which has properly configured TLS
return &http.Client{Transport: &Transport{ExtraHeader: ta.header}}
} }
func (ta *tokenAuthorizer) ping(endpoint string) (map[string]authorizationChallenge, error) { func (ta *tokenAuthorizer) ping(endpoint string) (map[string]authorizationChallenge, error) {
@ -101,7 +98,16 @@ func (ta *tokenAuthorizer) ping(endpoint string) (map[string]authorizationChalle
return nil, err return nil, err
} }
resp, err := ta.client().Do(req) client := &http.Client{
Transport: &Transport{
ExtraHeader: ta.header,
Base: ta.transport,
},
// Ping should fail fast
Timeout: 5 * time.Second,
}
resp, err := client.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -171,9 +177,10 @@ func (ta *tokenAuthorizer) Authorize(req *http.Request) error {
} }
type tokenHandler struct { type tokenHandler struct {
header http.Header header http.Header
creds CredentialStore creds CredentialStore
scope TokenScope scope TokenScope
transport http.RoundTripper
tokenLock sync.Mutex tokenLock sync.Mutex
tokenCache string tokenCache string
@ -190,7 +197,7 @@ type TokenScope struct {
// NewTokenHandler creates a new AuthenicationHandler which supports // NewTokenHandler creates a new AuthenicationHandler which supports
// fetching tokens from a remote token server. // fetching tokens from a remote token server.
func NewTokenHandler(creds CredentialStore, scope TokenScope, header http.Header) AuthenticationHandler { func NewTokenHandler(transport http.RoundTripper, creds CredentialStore, scope TokenScope, header http.Header) AuthenticationHandler {
return &tokenHandler{ return &tokenHandler{
header: header, header: header,
creds: creds, creds: creds,
@ -203,8 +210,12 @@ func (ts TokenScope) String() string {
} }
func (ts *tokenHandler) client() *http.Client { func (ts *tokenHandler) client() *http.Client {
// TODO(dmcgowan): Use same transport which has properly configured TLS return &http.Client{
return &http.Client{Transport: &Transport{ExtraHeader: ts.header}} Transport: &Transport{
ExtraHeader: ts.header,
Base: ts.transport,
},
}
} }
func (ts *tokenHandler) Scheme() string { func (ts *tokenHandler) Scheme() string {

View file

@ -117,7 +117,7 @@ func TestEndpointAuthorizeToken(t *testing.T) {
defer c() defer c()
repo1Config := &RepositoryConfig{ repo1Config := &RepositoryConfig{
AuthSource: NewTokenAuthorizer(nil, nil, tokenScope1), AuthSource: NewTokenAuthorizer(nil, nil, nil, tokenScope1),
} }
client, err := repo1Config.HTTPClient() client, err := repo1Config.HTTPClient()
@ -142,7 +142,7 @@ func TestEndpointAuthorizeToken(t *testing.T) {
defer c2() defer c2()
repo2Config := &RepositoryConfig{ repo2Config := &RepositoryConfig{
AuthSource: NewTokenAuthorizer(nil, nil, tokenScope2), AuthSource: NewTokenAuthorizer(nil, nil, nil, tokenScope2),
} }
client2, err := repo2Config.HTTPClient() client2, err := repo2Config.HTTPClient()
if err != nil { if err != nil {
@ -221,7 +221,7 @@ func TestEndpointAuthorizeTokenBasic(t *testing.T) {
password: password, password: password,
} }
repoConfig := &RepositoryConfig{ repoConfig := &RepositoryConfig{
AuthSource: NewTokenAuthorizer(creds, nil, tokenScope), AuthSource: NewTokenAuthorizer(creds, nil, nil, tokenScope),
} }
client, err := repoConfig.HTTPClient() client, err := repoConfig.HTTPClient()
@ -266,7 +266,7 @@ func TestEndpointAuthorizeBasic(t *testing.T) {
password: password, password: password,
} }
repoConfig := &RepositoryConfig{ repoConfig := &RepositoryConfig{
AuthSource: NewTokenAuthorizer(creds, nil, TokenScope{}), AuthSource: NewTokenAuthorizer(creds, nil, nil, TokenScope{}),
} }
client, err := repoConfig.HTTPClient() client, err := repoConfig.HTTPClient()