func()

in proxy/proxyserver/prefetch.go [208:262]


func (ph *PrefetchHandler) preparePrefetch(w http.ResponseWriter, r *http.Request) (res *prefetchInput, errOccurred bool) {
	ph.metrics.Counter("requests").Inc(1)
	var reqBody prefetchBody
	if err := json.NewDecoder(r.Body).Decode(&reqBody); err != nil {
		writeBadRequestError(w, fmt.Sprintf("failed to decode request body: %s", err), "")
		log.With("error", err).Error("Failed to decode request body")
		return nil, true
	}
	logger := log.
		With("trace_id", reqBody.TraceId).
		With("image_tag", reqBody.Tag)

	namespace, tag, err := ph.tagParser.ParseTag(reqBody.Tag)
	if err != nil {
		writeBadRequestError(w, fmt.Sprintf("tag: %s, invalid tag format: %s", reqBody.Tag, err), reqBody.TraceId)
		return nil, true
	}

	tagRequest := url.QueryEscape(fmt.Sprintf("%s/%s", namespace, tag))
	startTime := time.Now()
	digest, err := ph.tagClient.Get(tagRequest)
	if err != nil {
		ph.metrics.Counter("get_tag_error").Inc(1)
		logger.With("error", err).Error("Failed to get manifest tag")
		writeInternalError(w, fmt.Sprintf("tag request: %s, failed to get tag: %s", tagRequest, err), reqBody.TraceId)
		return nil, true
	}
	ph.getTagLatency.RecordDuration(time.Since(startTime))
	logger.Infof("Namespace: %s, Tag: %s", namespace, tag)

	buf := &bytes.Buffer{}
	startTime = time.Now()
	if err := ph.clusterClient.DownloadBlob(context.Background(), namespace, digest, buf); err != nil {
		ph.metrics.Counter("download_manifest_error").Inc(1)
		logger.With("error", err).Error("Failed to download manifest blob")
		writeInternalError(w, fmt.Sprintf("error downloading manifest blob: %s", err), reqBody.TraceId)
		return nil, true
	}
	ph.getManifestLatency.RecordDuration(time.Since(startTime))

	// Process manifest (ManifestList or single Manifest)
	blobs, err := ph.processManifest(logger, namespace, buf.Bytes())
	if err != nil {
		writeInternalError(w, fmt.Sprintf("failed to process manifest: %s", err), reqBody.TraceId)
		return nil, true
	}

	return &prefetchInput{
		blobs:     blobs,
		namespace: namespace,
		logger:    logger,
		tag:       tag,
		traceID:   reqBody.TraceId,
	}, false
}