Browse code

Refactor put image function's redirect loop

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Michael Crosby authored on 2014/12/11 11:08:40
Showing 1 changed files
... ...
@@ -462,7 +462,6 @@ func (r *Session) PushRegistryTag(remote, revision, tag, registry string, token
462 462
 
463 463
 func (r *Session) PushImageJSONIndex(remote string, imgList []*ImgData, validate bool, regs []string) (*RepositoryData, error) {
464 464
 	cleanImgList := []*ImgData{}
465
-
466 465
 	if validate {
467 466
 		for _, elem := range imgList {
468 467
 			if elem.Checksum != "" {
... ...
@@ -484,44 +483,28 @@ func (r *Session) PushImageJSONIndex(remote string, imgList []*ImgData, validate
484 484
 	u := fmt.Sprintf("%srepositories/%s/%s", r.indexEndpoint.VersionString(1), remote, suffix)
485 485
 	log.Debugf("[registry] PUT %s", u)
486 486
 	log.Debugf("Image list pushed to index:\n%s", imgListJSON)
487
-	req, err := r.reqFactory.NewRequest("PUT", u, bytes.NewReader(imgListJSON))
488
-	if err != nil {
489
-		return nil, err
487
+	headers := map[string][]string{
488
+		"Content-type":   {"application/json"},
489
+		"X-Docker-Token": {"true"},
490 490
 	}
491
-	req.Header.Add("Content-type", "application/json")
492
-	req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password)
493
-	req.ContentLength = int64(len(imgListJSON))
494
-	req.Header.Set("X-Docker-Token", "true")
495 491
 	if validate {
496
-		req.Header["X-Docker-Endpoints"] = regs
497
-	}
498
-
499
-	res, _, err := r.doRequest(req)
500
-	if err != nil {
501
-		return nil, err
492
+		headers["X-Docker-Endpoints"] = regs
502 493
 	}
503
-	defer res.Body.Close()
504 494
 
505 495
 	// Redirect if necessary
506
-	for res.StatusCode >= 300 && res.StatusCode < 400 {
507
-		log.Debugf("Redirected to %s", res.Header.Get("Location"))
508
-		req, err := r.reqFactory.NewRequest("PUT", res.Header.Get("Location"), bytes.NewReader(imgListJSON))
509
-		if err != nil {
496
+	var res *http.Response
497
+	for {
498
+		if res, err = r.putImageRequest(u, headers, imgListJSON); err != nil {
510 499
 			return nil, err
511 500
 		}
512
-		req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password)
513
-		req.ContentLength = int64(len(imgListJSON))
514
-		req.Header.Set("X-Docker-Token", "true")
515
-		if validate {
516
-			req.Header["X-Docker-Endpoints"] = regs
517
-		}
518
-		redirect, _, err := r.doRequest(req)
519
-		if err != nil {
520
-			return nil, err
501
+		if !shouldRedirect(res) {
502
+			break
521 503
 		}
522
-		res = redirect
523
-		defer res.Body.Close()
504
+		res.Body.Close()
505
+		u = res.Header.Get("Location")
506
+		log.Debugf("Redirected to %s", u)
524 507
 	}
508
+	defer res.Body.Close()
525 509
 
526 510
 	var tokens, endpoints []string
527 511
 	if !validate {
... ...
@@ -564,6 +547,27 @@ func (r *Session) PushImageJSONIndex(remote string, imgList []*ImgData, validate
564 564
 	}, nil
565 565
 }
566 566
 
567
+func (r *Session) putImageRequest(u string, headers map[string][]string, body []byte) (*http.Response, error) {
568
+	req, err := r.reqFactory.NewRequest("PUT", u, bytes.NewReader(body))
569
+	if err != nil {
570
+		return nil, err
571
+	}
572
+	req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password)
573
+	req.ContentLength = int64(len(body))
574
+	for k, v := range headers {
575
+		req.Header[k] = v
576
+	}
577
+	response, _, err := r.doRequest(req)
578
+	if err != nil {
579
+		return nil, err
580
+	}
581
+	return response, nil
582
+}
583
+
584
+func shouldRedirect(response *http.Response) bool {
585
+	return response.StatusCode >= 300 && response.StatusCode < 400
586
+}
587
+
567 588
 func (r *Session) SearchRepositories(term string) (*SearchResults, error) {
568 589
 	log.Debugf("Index server: %s", r.indexEndpoint)
569 590
 	u := r.indexEndpoint.VersionString(1) + "search?q=" + url.QueryEscape(term)