Add a CheckRedirect function to the HTTP client

Use it to preserve Accept and Range headers that were added to the
original request.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
Aaron Lehmann 2016-01-27 10:57:58 -08:00
parent a58b7625ba
commit 8e571dff41

View file

@ -27,6 +27,26 @@ type Registry interface {
Repositories(ctx context.Context, repos []string, last string) (n int, err error) Repositories(ctx context.Context, repos []string, last string) (n int, err error)
} }
// checkHTTPRedirect is a callback that can manipulate redirected HTTP
// requests. It is used to preserve Accept and Range headers.
func checkHTTPRedirect(req *http.Request, via []*http.Request) error {
if len(via) >= 10 {
return errors.New("stopped after 10 redirects")
}
if len(via) > 0 {
for headerName, headerVals := range via[0].Header {
if headerName == "Accept" || headerName == "Range" {
for _, val := range headerVals {
req.Header.Add(headerName, val)
}
}
}
}
return nil
}
// NewRegistry creates a registry namespace which can be used to get a listing of repositories // NewRegistry creates a registry namespace which can be used to get a listing of repositories
func NewRegistry(ctx context.Context, baseURL string, transport http.RoundTripper) (Registry, error) { func NewRegistry(ctx context.Context, baseURL string, transport http.RoundTripper) (Registry, error) {
ub, err := v2.NewURLBuilderFromString(baseURL) ub, err := v2.NewURLBuilderFromString(baseURL)
@ -37,6 +57,7 @@ func NewRegistry(ctx context.Context, baseURL string, transport http.RoundTrippe
client := &http.Client{ client := &http.Client{
Transport: transport, Transport: transport,
Timeout: 1 * time.Minute, Timeout: 1 * time.Minute,
CheckRedirect: checkHTTPRedirect,
} }
return &registry{ return &registry{
@ -106,6 +127,7 @@ func NewRepository(ctx context.Context, name reference.Named, baseURL string, tr
client := &http.Client{ client := &http.Client{
Transport: transport, Transport: transport,
CheckRedirect: checkHTTPRedirect,
// TODO(dmcgowan): create cookie jar // TODO(dmcgowan): create cookie jar
} }