Check the URL path for .zip to see if we can auto-decompress
This commit is contained in:
@@ -821,6 +821,40 @@ describe('download-artifact', () => {
|
|||||||
await expectExtractedArchive(fixtures.workspaceDir)
|
await expectExtractedArchive(fixtures.workspaceDir)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should extract zip when URL ends with .zip even if content-type is not application/zip', async () => {
|
||||||
|
const blobUrlWithZipExtension =
|
||||||
|
'https://blob-storage.local/artifact.zip?sig=abc123'
|
||||||
|
|
||||||
|
const mockGetZipByUrl = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
// Azure Blob Storage may return a generic content-type
|
||||||
|
message.headers['content-type'] = 'application/octet-stream'
|
||||||
|
message.push(fs.readFileSync(fixtures.exampleArtifact.path))
|
||||||
|
message.push(null)
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockGetZipByUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await streamExtractExternal(
|
||||||
|
blobUrlWithZipExtension,
|
||||||
|
fixtures.workspaceDir
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
// Verify files were extracted based on URL .zip extension
|
||||||
|
await expectExtractedArchive(fixtures.workspaceDir)
|
||||||
|
})
|
||||||
|
|
||||||
it('should skip decompression when skipDecompress option is true even for zip content-type', async () => {
|
it('should skip decompression when skipDecompress option is true even for zip content-type', async () => {
|
||||||
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
() => {
|
() => {
|
||||||
|
|||||||
@@ -81,10 +81,16 @@ export async function streamExtractExternal(
|
|||||||
|
|
||||||
const contentType = response.message.headers['content-type'] || ''
|
const contentType = response.message.headers['content-type'] || ''
|
||||||
const mimeType = contentType.split(';', 1)[0].trim().toLowerCase()
|
const mimeType = contentType.split(';', 1)[0].trim().toLowerCase()
|
||||||
|
|
||||||
|
// Check if the URL path ends with .zip (ignoring query parameters)
|
||||||
|
const urlPath = new URL(url).pathname.toLowerCase()
|
||||||
|
const urlEndsWithZip = urlPath.endsWith('.zip')
|
||||||
|
|
||||||
const isZip =
|
const isZip =
|
||||||
mimeType === 'application/zip' ||
|
mimeType === 'application/zip' ||
|
||||||
mimeType === 'application/x-zip-compressed' ||
|
mimeType === 'application/x-zip-compressed' ||
|
||||||
mimeType === 'application/zip-compressed'
|
mimeType === 'application/zip-compressed' ||
|
||||||
|
urlEndsWithZip
|
||||||
|
|
||||||
// Extract filename from Content-Disposition header
|
// Extract filename from Content-Disposition header
|
||||||
const contentDisposition =
|
const contentDisposition =
|
||||||
@@ -100,7 +106,7 @@ export async function streamExtractExternal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
core.debug(
|
core.debug(
|
||||||
`Content-Type: ${contentType}, isZip: ${isZip}, skipDecompress: ${skipDecompress}`
|
`Content-Type: ${contentType}, mimeType: ${mimeType}, urlEndsWithZip: ${urlEndsWithZip}, isZip: ${isZip}, skipDecompress: ${skipDecompress}`
|
||||||
)
|
)
|
||||||
core.debug(
|
core.debug(
|
||||||
`Content-Disposition: ${contentDisposition}, fileName: ${fileName}`
|
`Content-Disposition: ${contentDisposition}, fileName: ${fileName}`
|
||||||
|
|||||||
Reference in New Issue
Block a user