|
function Invoke-Download ($url, $to, $cookies, $progress) { |
|
# download with filesize and progress indicator |
|
$reqUrl = ($url -split '#')[0] |
|
$wreq = [Net.WebRequest]::Create($reqUrl) |
|
if ($wreq -is [Net.HttpWebRequest]) { |
|
$wreq.UserAgent = Get-UserAgent |
|
if (-not ($url -match 'sourceforge\.net' -or $url -match 'portableapps\.com')) { |
|
$wreq.Referer = strip_filename $url |
|
} |
|
if ($url -match 'api\.github\.com/repos') { |
|
$wreq.Accept = 'application/octet-stream' |
|
$wreq.Headers['Authorization'] = "Bearer $(Get-GitHubToken)" |
|
$wreq.Headers['X-GitHub-Api-Version'] = '2022-11-28' |
|
} |
|
if ($cookies) { |
|
$wreq.Headers.Add('Cookie', (cookie_header $cookies)) |
|
} |
|
|
|
get_config PRIVATE_HOSTS | Where-Object { $_ -ne $null -and $url -match $_.match } | ForEach-Object { |
|
(ConvertFrom-StringData -StringData $_.Headers).GetEnumerator() | ForEach-Object { |
|
$wreq.Headers[$_.Key] = $_.Value |
|
} |
|
} |
|
} |
|
|
|
try { |
|
$wres = $wreq.GetResponse() |
|
} catch [System.Net.WebException] { |
|
$exc = $_.Exception |
|
$handledCodes = @( |
|
[System.Net.HttpStatusCode]::MovedPermanently, # HTTP 301 |
|
[System.Net.HttpStatusCode]::Found, # HTTP 302 |
|
[System.Net.HttpStatusCode]::SeeOther, # HTTP 303 |
|
[System.Net.HttpStatusCode]::TemporaryRedirect # HTTP 307 |
|
) |
|
|
|
# Only handle redirection codes |
|
$redirectRes = $exc.Response |
|
if ($handledCodes -notcontains $redirectRes.StatusCode) { |
|
throw $exc |
|
} |
|
|
|
# Get the new location of the file |
|
if ((-not $redirectRes.Headers) -or ($redirectRes.Headers -notcontains 'Location')) { |
|
throw $exc |
|
} |
|
|
|
$newUrl = $redirectRes.Headers['Location'] |
|
info "Following redirect to $newUrl..." |
|
|
|
# Handle manual file rename |
|
if ($url -like '*#/*') { |
|
$null, $postfix = $url -split '#/' |
|
$newUrl = "$newUrl`#/$postfix" |
|
} |
|
|
|
Invoke-Download $newUrl $to $cookies $progress |
|
return |
|
} |
|
|
|
$total = $wres.ContentLength |
|
if ($total -eq -1 -and $wreq -is [net.ftpwebrequest]) { |
|
$total = ftp_file_size($url) |
|
} |
|
|
|
if ($progress -and ($total -gt 0)) { |
|
[console]::CursorVisible = $false |
|
function Trace-DownloadProgress ($read) { |
|
Write-DownloadProgress $read $total $url |
|
} |
|
} else { |
|
Write-Host "Downloading $url ($(filesize $total))..." |
|
function Trace-DownloadProgress { |
|
#no op |
|
} |
|
} |
|
|
|
try { |
|
$s = $wres.getresponsestream() |
|
$fs = [io.file]::openwrite($to) |
|
$buffer = New-Object byte[] 2048 |
|
$totalRead = 0 |
|
$sw = [diagnostics.stopwatch]::StartNew() |
|
|
|
Trace-DownloadProgress $totalRead |
|
while (($read = $s.read($buffer, 0, $buffer.length)) -gt 0) { |
|
$fs.write($buffer, 0, $read) |
|
$totalRead += $read |
|
if ($sw.elapsedmilliseconds -gt 100) { |
|
$sw.restart() |
|
Trace-DownloadProgress $totalRead |
|
} |
|
} |
|
$sw.stop() |
|
Trace-DownloadProgress $totalRead |
|
} finally { |
|
if ($progress) { |
|
[console]::CursorVisible = $true |
|
Write-Host |
|
} |
|
if ($fs) { |
|
$fs.close() |
|
} |
|
if ($s) { |
|
$s.close() |
|
} |
|
$wres.close() |
|
} |
|
} |
Feature Request
Is your feature request related to a problem? Please describe.
It seems that Scoop does not add GitHub token when downloading GitHub release assets, only for API calls.
Scoop/lib/download.ps1
Lines 89 to 197 in 0d0334c
Related:
Describe the solution you'd like
Add GitHub token when downloading release assets from GitHub releases too.
asset.urlinstead ofasset.browser_download_url.Accept: application/octet-stream, else it won't download the file.Looks like this requires Scoop to download using the API, instead of the browser download URL?
Example: AzCopy v10.32.1:
Invoke-RestMethod -Method 'Get' -Uri 'https://api.github.com/repos/Azure/azure-storage-azcopy/releases/assets/358222966' -Headers @{Accept = 'application/octet-stream'} -OutFile ('{0}/file.zip' -f [System.Environment]::GetFolderPath('Desktop'))Minimal example for downloading a GitHub release asset using the API instead:
Describe alternatives you've considered