diff --git a/src/spec-configuration/containerCollectionsOCIPush.ts b/src/spec-configuration/containerCollectionsOCIPush.ts index 575597240..eabf1df57 100644 --- a/src/spec-configuration/containerCollectionsOCIPush.ts +++ b/src/spec-configuration/containerCollectionsOCIPush.ts @@ -311,7 +311,7 @@ async function postUploadSessionId(output: Log, ociRef: OCIRef | OCICollectionRe const url = `https://${ociRef.registry}/v2/${ociRef.path}/blobs/uploads/`; output.write(`Generating Upload URL -> ${url}`, LogLevel.Trace); - const { statusCode, resHeaders } = await requestResolveHeaders({ type: 'POST', url, headers }, output); + const { statusCode, resHeaders, resBody } = await requestResolveHeaders({ type: 'POST', url, headers }, output); output.write(`${url}: ${statusCode}`, LogLevel.Trace); if (statusCode === 202) { const locationHeader = resHeaders['location'] || resHeaders['Location']; @@ -320,8 +320,13 @@ async function postUploadSessionId(output: Log, ociRef: OCIRef | OCICollectionRe return undefined; } return locationHeader; + } else { + // Any other statusCode besides 202 is unexpected + // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#error-codes + const displayResBody = resBody ? ` -> ${resBody}` : ''; + output.write(`${url}: Unexpected status code '${statusCode}'${displayResBody}`, LogLevel.Error); + return undefined; } - return undefined; } export async function calculateManifestAndContentDigest(output: Log, dataLayer: OCILayer, annotations: { [key: string]: string } | undefined) { diff --git a/src/spec-utils/httpRequest.ts b/src/spec-utils/httpRequest.ts index dee65e8cc..62c16be1a 100644 --- a/src/spec-utils/httpRequest.ts +++ b/src/spec-utils/httpRequest.ts @@ -65,9 +65,10 @@ export function headRequest(options: { url: string; headers: Record; data?: Buffer }, _output?: Log) { - return new Promise<{ statusCode: number; resHeaders: Record }>((resolve, reject) => { + return new Promise<{ statusCode: number; resHeaders: Record; resBody: Buffer }>((resolve, reject) => { const parsed = new url.URL(options.url); const reqOptions: RequestOptions = { hostname: parsed.hostname, @@ -79,16 +80,21 @@ export function requestResolveHeaders(options: { type: string; url: string; head }; const req = https.request(reqOptions, res => { res.on('error', reject); - const result = { - statusCode: res.statusCode!, - resHeaders: res.headers! as Record - }; - resolve(result); + + // Resolve response body + const chunks: Buffer[] = []; + res.on('data', chunk => chunks.push(chunk as Buffer)); + res.on('end', () => { + resolve({ + statusCode: res.statusCode!, + resHeaders: res.headers! as Record, + resBody: Buffer.concat(chunks) + }); + }); + if (options.data) { + req.write(options.data); + } + req.end(); }); - req.on('error', reject); - if (options.data) { - req.write(options.data); - } - req.end(); }); } \ No newline at end of file