private/Get-FileFromUrlOrCache.ps1
function Get-FileFromUrlOrCache { <# .Synopsis Gets a file from the download cache or (if unavailable) download and cache it (if the cache is enabled) .Parameter Url The URL to be downloaded from. .Parameter CachedFileName The name of the file to be used to store the downloaded resource in the cache. .Example Get-FileFromUrlOrCache 'http://www.example.com/test.zip' .Example Get-FileFromUrlOrCache 'http://www.example.com/test.zip' 'cached-file-name.zip' .Outputs [System.Array] #> [OutputType([string], [bool])] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingBrokenHashAlgorithms','')] param ( [Parameter(Mandatory = $true, Position = 0)] [ValidateNotNull()] [ValidateLength(1, [int]::MaxValue)] [string] $Url, [Parameter(Mandatory = $false, Position = 1)] [string] $CachedFileName ) begin { $localFile = $null $fromCache = $null } process { $extension = '' if ($null -ne $CachedFileName -and $CachedFileName -ne '') { $match = $CachedFileName | Select-String -Pattern '.(\.[A-Za-z0-9_\-]+)$' if ($match) { $extension = $match.Matches.Groups[1].Value } } else { $CachedFileName = '' $match = $Url | Select-String -Pattern '^[^:]+:/+[^?#/]+/(?:[^?#/]*/)*([^?#/]+)(?:$|^|#)' if ($match) { $nameFromUrl = $match.Matches.Groups[1].Value $match = $nameFromUrl | Select-String -Pattern '.(\.[A-Za-z0-9_\-]+)$' if ($match) { $extension = $match.Matches.Groups[1].Value } if ($nameFromUrl -imatch '^[a-z0-9_\-][a-z0-9_\-\.]*[a-z0-9_\-]$') { $CachedFileName = $nameFromUrl; } } if ($CachedFileName -eq '') { $stream = New-Object System.IO.MemoryStream try { $streamWriter = New-Object -TypeName System.IO.BinaryWriter -ArgumentList @($stream) try { $streamWriter.Write([System.Text.Encoding]::UTF8.GetBytes($Url)) $streamWriter.Flush() $stream.Position = 0 $hash = Get-FileHash -InputStream $stream -Algorithm SHA1 $CachedFileName = $hash.Hash } finally { $streamWriter.Dispose() } } finally { $stream.Dispose() } } } $downloadCachePath = Get-PhpDownloadCache if ($downloadCachePath -eq '') { $fullCachePath = '' } else { if (-Not(Test-Path -LiteralPath $downloadCachePath -PathType Container)) { New-Item -Path $downloadCachePath -ItemType Directory | Out-Null } $fullCachePath = Join-Path -Path $downloadCachePath -ChildPath $CachedFileName } if ($fullCachePath -ne '' -and (Test-Path -LiteralPath $fullCachePath -PathType Leaf)) { Write-Verbose "Using cached file for $Url" $localFile = $fullCachePath $fromCache = $true } else { $temporaryFile = Get-TemporaryFileWithExtension -Extension $extension try { Write-Verbose "Downloading from $Url" Get-WebResource -Uri $Url -OutFile $temporaryFile if ($fullCachePath -ne '') { Move-Item -LiteralPath $temporaryFile -Destination $fullCachePath $localFile = $fullCachePath $fromCache = $true } else { $localFile = $temporaryFile $fromCache = $false } } catch { try { Remove-Item -LiteralPath $temporaryFile } catch { Write-Debug 'Failed to remove a temporary file' } throw } } } end { $localFile $fromCache } } |