694df3ff |
package distribution
import ( |
8dce8e99 |
"fmt" |
694df3ff |
"net"
"net/http"
"time"
"github.com/docker/distribution" |
4d437a29 |
distreference "github.com/docker/distribution/reference" |
694df3ff |
"github.com/docker/distribution/registry/client"
"github.com/docker/distribution/registry/client/auth"
"github.com/docker/distribution/registry/client/transport" |
61a49bb6 |
"github.com/docker/docker/dockerversion" |
694df3ff |
"github.com/docker/docker/registry" |
907407d0 |
"github.com/docker/engine-api/types" |
20702708 |
"github.com/docker/go-connections/sockets" |
694df3ff |
"golang.org/x/net/context"
)
|
c1be45fa |
// NewV2Repository returns a repository (v2 only). It creates an HTTP transport |
694df3ff |
// providing timeout settings and authentication support, and also verifies the
// remote API version. |
a57478d6 |
func NewV2Repository(ctx context.Context, repoInfo *registry.RepositoryInfo, endpoint registry.APIEndpoint, metaHeaders http.Header, authConfig *types.AuthConfig, actions ...string) (repo distribution.Repository, foundVersion bool, err error) { |
ffded61d |
repoName := repoInfo.FullName() |
694df3ff |
// If endpoint does not support CanonicalName, use the RemoteName instead
if endpoint.TrimHostname { |
ffded61d |
repoName = repoInfo.RemoteName() |
694df3ff |
}
|
20702708 |
direct := &net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}
|
694df3ff |
// TODO(dmcgowan): Call close idle connections when complete, use keep alive
base := &http.Transport{ |
20702708 |
Proxy: http.ProxyFromEnvironment,
Dial: direct.Dial, |
694df3ff |
TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: endpoint.TLSConfig,
// TODO(dmcgowan): Call close idle connections when complete and use keep alive
DisableKeepAlives: true,
}
|
20702708 |
proxyDialer, err := sockets.DialerFromEnvironment(direct)
if err == nil {
base.Dial = proxyDialer.Dial
}
|
c44e7a3e |
modifiers := registry.DockerHeaders(dockerversion.DockerUserAgent(ctx), metaHeaders) |
694df3ff |
authTransport := transport.NewTransport(base, modifiers...) |
5e8af46f |
|
e678d9fb |
challengeManager, foundVersion, err := registry.PingV2Registry(endpoint.URL, authTransport) |
f2d481a2 |
if err != nil {
transportOK := false
if responseErr, ok := err.(registry.PingResponseError); ok {
transportOK = true
err = responseErr.Err |
694df3ff |
} |
5e8af46f |
return nil, foundVersion, fallbackError{
err: err,
confirmedV2: foundVersion, |
f2d481a2 |
transportOK: transportOK, |
5e8af46f |
} |
694df3ff |
}
|
8dce8e99 |
if authConfig.RegistryToken != "" {
passThruTokenHandler := &existingTokenHandler{token: authConfig.RegistryToken}
modifiers = append(modifiers, auth.NewAuthorizer(challengeManager, passThruTokenHandler))
} else { |
e678d9fb |
creds := registry.NewStaticCredentialStore(authConfig) |
e896d1d7 |
tokenHandlerOptions := auth.TokenHandlerOptions{
Transport: authTransport,
Credentials: creds,
Scopes: []auth.Scope{
auth.RepositoryScope{
Repository: repoName,
Actions: actions,
},
},
ClientID: registry.AuthClientID,
}
tokenHandler := auth.NewTokenHandlerWithOptions(tokenHandlerOptions) |
8dce8e99 |
basicHandler := auth.NewBasicHandler(creds)
modifiers = append(modifiers, auth.NewAuthorizer(challengeManager, tokenHandler, basicHandler))
} |
694df3ff |
tr := transport.NewTransport(base, modifiers...)
|
4d437a29 |
repoNameRef, err := distreference.ParseNamed(repoName)
if err != nil { |
5e8af46f |
return nil, foundVersion, fallbackError{
err: err,
confirmedV2: foundVersion,
transportOK: true,
} |
4d437a29 |
}
|
79db131a |
repo, err = client.NewRepository(ctx, repoNameRef, endpoint.URL.String(), tr) |
5e8af46f |
if err != nil {
err = fallbackError{
err: err,
confirmedV2: foundVersion,
transportOK: true,
}
}
return |
694df3ff |
}
|
8dce8e99 |
type existingTokenHandler struct {
token string
}
func (th *existingTokenHandler) Scheme() string {
return "bearer"
}
func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, params map[string]string) error {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", th.token))
return nil
} |