when uploading layers reuse token so reader isn't closed premature. (#103)

This commit is contained in:
Jan-Otto Kröpke 2018-07-08 15:42:04 +02:00 committed by Jess Frazelle
parent d25a2c83ae
commit a8549a2c40
3 changed files with 14 additions and 7 deletions

View file

@ -15,7 +15,7 @@ type BasicTransport struct {
// RoundTrip defines the round tripper for basic auth transport. // RoundTrip defines the round tripper for basic auth transport.
func (t *BasicTransport) RoundTrip(req *http.Request) (*http.Response, error) { func (t *BasicTransport) RoundTrip(req *http.Request) (*http.Response, error) {
if strings.HasPrefix(req.URL.String(), t.URL) { if strings.HasPrefix(req.URL.String(), t.URL) && req.Header.Get("Authorization") == "" {
if t.Username != "" || t.Password != "" { if t.Username != "" || t.Password != "" {
req.SetBasicAuth(t.Username, t.Password) req.SetBasicAuth(t.Username, t.Password)
} }

View file

@ -5,6 +5,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"fmt"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
) )
@ -24,7 +25,7 @@ func (r *Registry) DownloadLayer(repository string, digest digest.Digest) (io.Re
// UploadLayer uploads a specific layer by digest for a repository. // UploadLayer uploads a specific layer by digest for a repository.
func (r *Registry) UploadLayer(repository string, digest reference.Reference, content io.Reader) error { func (r *Registry) UploadLayer(repository string, digest reference.Reference, content io.Reader) error {
uploadURL, err := r.initiateUpload(repository) uploadURL, token, err := r.initiateUpload(repository)
if err != nil { if err != nil {
return err return err
} }
@ -39,6 +40,7 @@ func (r *Registry) UploadLayer(repository string, digest reference.Reference, co
return err return err
} }
upload.Header.Set("Content-Type", "application/octet-stream") upload.Header.Set("Content-Type", "application/octet-stream")
upload.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
_, err = r.Client.Do(upload) _, err = r.Client.Do(upload)
return err return err
@ -70,20 +72,21 @@ func (r *Registry) HasLayer(repository string, digest digest.Digest) (bool, erro
return false, err return false, err
} }
func (r *Registry) initiateUpload(repository string) (*url.URL, error) { func (r *Registry) initiateUpload(repository string) (*url.URL, string, error) {
initiateURL := r.url("/v2/%s/blobs/uploads/", repository) initiateURL := r.url("/v2/%s/blobs/uploads/", repository)
r.Logf("registry.layer.initiate-upload url=%s repository=%s", initiateURL, repository) r.Logf("registry.layer.initiate-upload url=%s repository=%s", initiateURL, repository)
resp, err := r.Client.Post(initiateURL, "application/octet-stream", nil) resp, err := r.Client.Post(initiateURL, "application/octet-stream", nil)
if err != nil { if err != nil {
return nil, err return nil, "", err
} }
token := resp.Header.Get("Request-Token")
defer resp.Body.Close() defer resp.Body.Close()
location := resp.Header.Get("Location") location := resp.Header.Get("Location")
locationURL, err := url.Parse(location) locationURL, err := url.Parse(location)
if err != nil { if err != nil {
return nil, err return nil, token, err
} }
return locationURL, nil return locationURL, token, nil
} }

View file

@ -47,7 +47,11 @@ func (t *TokenTransport) authAndRetry(authService *authService, req *http.Reques
return authResp, err return authResp, err
} }
return t.retry(req, token) response, err := t.retry(req, token)
if response != nil {
response.Header.Set("request-token", token)
}
return response, err
} }
func (t *TokenTransport) auth(authService *authService) (string, *http.Response, error) { func (t *TokenTransport) auth(authService *authService) (string, *http.Response, error) {