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
}