Skip to content

Commit

Permalink
Merge branch 'stable'
Browse files Browse the repository at this point in the history
* stable:
  (maint) rename Get-FileName to Get-WebFileName
  (maint) Log host version as well.
  (GH-512) Exit with same code as installer
  (GH-707) Exit with specific exit codes
  (GH-649) Error if executable is text file
  (GH-709) Get Exit code from PowerShell Host
  (GH-512) Display exit code for packages
  (GH-710) prompt with timeout on some commands
  (maint) better error handling
  • Loading branch information
ferventcoder committed Apr 25, 2016
2 parents 47f8ec4 + 4b0558e commit 45b67c1
Show file tree
Hide file tree
Showing 17 changed files with 258 additions and 148 deletions.
5 changes: 4 additions & 1 deletion src/chocolatey.resources/chocolatey.resources.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
<EmbeddedResource Include="helpers\chocolateyScriptRunner.ps1" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="helpers\functions\Get-FileName.ps1" />
<EmbeddedResource Include="helpers\functions\Get-WebFileName.ps1" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="helpers\functions\Get-ToolsLocation.ps1" />
Expand All @@ -137,6 +137,9 @@
<ItemGroup>
<EmbeddedResource Include="helpers\ChocolateyTabExpansion.ps1" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="helpers\functions\Set-PowerShellExitCode.ps1" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand Down
2 changes: 1 addition & 1 deletion src/chocolatey.resources/helpers/chocolateyInstaller.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ $packageParameters = $env:chocolateyPackageParameters
# ensure module loading preference is on
$PSModuleAutoLoadingPreference = "All";

Write-Debug "PowerShell Version is '$($PSVersionTable.PSVersion)' and CLR Version is '$($PSVersionTable.CLRVersion)'."
Write-Debug "Host version is $($host.Version), PowerShell Version is '$($PSVersionTable.PSVersion)' and CLR Version is '$($PSVersionTable.CLRVersion)'."

# grab functions from files
Get-Item $helpersPath\functions\*.ps1 |
Expand Down
16 changes: 15 additions & 1 deletion src/chocolatey.resources/helpers/chocolateyScriptRunner.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,18 @@ $ShimGen = Join-Path $chocoTools 'shimgen.exe'
$checksumExe = Join-Path $chocoTools 'checksum.exe'

Write-Debug "Running `'$packageScript`'";
& "$packageScript"
& "$packageScript"

$scriptSuccess = $?

$exitCode = $LASTEXITCODE
if ($exitCode -eq 0 -and -not $scriptSuccess) {
$exitCode = 1
}

if ($env:ChocolateyExitCode -ne $null -and $env:ChocolateyExitCode -ne '') {
$exitCode = $env:ChocolateyExitCode
}


Exit $exitCode
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ param(
Unregister-Event -SourceIdentifier "LogErrors_ChocolateyZipProc"

$exitCode = $process.ExitCode
Set-PowerShellExitCode $exitCode
$process.Dispose()
Write-Debug "Command ['$7zip' $params] exited with `'$exitCode`'."

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ param(
try {
$fileDirectory = [System.IO.Path]::GetDirectoryName($fileFullPath)
$originalFileName = [System.IO.Path]::GetFileName($fileFullPath)
$fileFullPath = Get-FileName -url $url -defaultName $originalFileName
$fileFullPath = Get-WebFileName -url $url -defaultName $originalFileName
$fileFullPath = Join-Path $fileDirectory $fileFullPath
$fileFullPath = [System.IO.Path]::GetFullPath($fileFullPath)
} catch {
Expand All @@ -149,13 +149,17 @@ param(
$headers = @{}
if ($url.StartsWith('http')) {
try {
$headers = Get-WebHeaders $url
$headers = Get-WebHeaders $url -ErrorAction "Stop"
} catch {
if ($host.Version -lt (new-object 'Version' 3,0)) {
Write-Debug "Converting Security Protocol to SSL3 only for Powershell v2"
# this should last for the entire duration
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Ssl3
$headers = Get-WebHeaders $url
try {
$headers = Get-WebHeaders $url -ErrorAction "Stop"
} catch {
Write-Host "Attempt to get headers for $url failed.`n $($_.Exception.Message)"
}
} else {
Write-Host "Attempt to get headers for $url failed.`n $($_.Exception.Message)"
}
Expand Down
208 changes: 115 additions & 93 deletions src/chocolatey.resources/helpers/functions/Get-WebFile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -94,119 +94,141 @@ param(
}
}

$res = $req.GetResponse();
try {
[System.Net.HttpWebResponse]$res = $req.GetResponse();

try {
$headers = @{}
foreach ($key in $res.Headers) {
$value = $res.Headers[$key];
if ($value) {
$headers.Add("$key","$value")
try {
$headers = @{}
foreach ($key in $res.Headers) {
$value = $res.Headers[$key];
if ($value) {
$headers.Add("$key","$value")
}
}
}

if ($headers.ContainsKey("Content-Type")) {
$contentType = $headers['Content-Type']
if ($contentType -ne $null) {
if ($contentType.ToLower().Contains("text/html") -or $contentType.ToLower().Contains("text/plain")) {
Write-Warning "$fileName is of content type $contentType"
Set-Content -Path "$fileName.istext" -Value "$fileName has content type $contentType" -Encoding UTF8 -Force
if ($headers.ContainsKey("Content-Type")) {
$contentType = $headers['Content-Type']
if ($contentType -ne $null) {
if ($contentType.ToLower().Contains("text/html") -or $contentType.ToLower().Contains("text/plain")) {
Write-Warning "$fileName is of content type $contentType"
Set-Content -Path "$fileName.istext" -Value "$fileName has content type $contentType" -Encoding UTF8 -Force
}
}
}
} catch {
# not able to get content-type header
Write-Debug "Error getting content type - $($_.Exception.Message)"
}

if($fileName -and !(Split-Path $fileName)) {
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
}
elseif((!$Passthru -and ($fileName -eq $null)) -or (($fileName -ne $null) -and (Test-Path -PathType "Container" $fileName)))
{
[string]$fileName = ([regex]'(?i)filename=(.*)$').Match( $res.Headers["Content-Disposition"] ).Groups[1].Value
$fileName = $fileName.trim("\/""'")
if(!$fileName) {
$fileName = $res.ResponseUri.Segments[-1]
$fileName = $fileName.trim("\/")
if(!$fileName) {
$fileName = Read-Host "Please provide a file name"
}
$fileName = $fileName.trim("\/")
if(!([IO.FileInfo]$fileName).Extension) {
$fileName = $fileName + "." + $res.ContentType.Split(";")[0].Split("/")[1]
}
}
}
} catch {
# not able to get content-type header
Write-Debug "Error getting content type - $($_.Exception.Message)"
}
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
}
if($Passthru) {
$encoding = [System.Text.Encoding]::GetEncoding( $res.CharacterSet )
[string]$output = ""
}

if($fileName -and !(Split-Path $fileName)) {
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
}
elseif((!$Passthru -and ($fileName -eq $null)) -or (($fileName -ne $null) -and (Test-Path -PathType "Container" $fileName)))
{
[string]$fileName = ([regex]'(?i)filename=(.*)$').Match( $res.Headers["Content-Disposition"] ).Groups[1].Value
$fileName = $fileName.trim("\/""'")
if(!$fileName) {
$fileName = $res.ResponseUri.Segments[-1]
$fileName = $fileName.trim("\/")
if(!$fileName) {
$fileName = Read-Host "Please provide a file name"
}
$fileName = $fileName.trim("\/")
if(!([IO.FileInfo]$fileName).Extension) {
$fileName = $fileName + "." + $res.ContentType.Split(";")[0].Split("/")[1]
}
if($res.StatusCode -eq 401 -or $res.StatusCode -eq 403 -or $res.StatusCode -eq 404) {
$env:ChocolateyExitCode = $res.StatusCode
throw "Remote file either doesn't exist, is unauthorized, or is forbidden for '$url'."
}
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
}
if($Passthru) {
$encoding = [System.Text.Encoding]::GetEncoding( $res.CharacterSet )
[string]$output = ""
}

if($res.StatusCode -eq 200) {
[long]$goal = $res.ContentLength
$goalFormatted = Format-FileSize $goal
$reader = $res.GetResponseStream()
if($res.StatusCode -eq 200) {
[long]$goal = $res.ContentLength
$goalFormatted = Format-FileSize $goal
$reader = $res.GetResponseStream()

if ($fileName) {
$fileDirectory = $([System.IO.Path]::GetDirectoryName($fileName))
if (!(Test-Path($fileDirectory))) {
[System.IO.Directory]::CreateDirectory($fileDirectory) | Out-Null
}
if ($fileName) {
$fileDirectory = $([System.IO.Path]::GetDirectoryName($fileName))
if (!(Test-Path($fileDirectory))) {
[System.IO.Directory]::CreateDirectory($fileDirectory) | Out-Null
}

try {
$writer = new-object System.IO.FileStream $fileName, "Create"
} catch {
throw $_.Exception
try {
$writer = new-object System.IO.FileStream $fileName, "Create"
} catch {
throw $_.Exception
}
}
}

[byte[]]$buffer = new-object byte[] 1048576
[long]$total = [long]$count = [long]$iterLoop =0
[byte[]]$buffer = new-object byte[] 1048576
[long]$total = [long]$count = [long]$iterLoop =0

$originalEAP = $ErrorActionPreference
$ErrorActionPreference = 'Stop'
try {
do
{
$count = $reader.Read($buffer, 0, $buffer.Length);
if($fileName) {
$writer.Write($buffer, 0, $count);
}

if($Passthru){
$output += $encoding.GetString($buffer,0,$count)
} elseif(!$quiet) {
$total += $count
$totalFormatted = Format-FileSize $total
if($goal -gt 0 -and ++$iterLoop%10 -eq 0) {
Write-Progress "Downloading $url to $fileName" "Saving $totalFormatted of $goalFormatted ($total/$goal)" -id 0 -percentComplete (($total/$goal)*100)
$originalEAP = $ErrorActionPreference
$ErrorActionPreference = 'Stop'
try {
do
{
$count = $reader.Read($buffer, 0, $buffer.Length);
if($fileName) {
$writer.Write($buffer, 0, $count);
}

if($Passthru){
$output += $encoding.GetString($buffer,0,$count)
} elseif(!$quiet) {
$total += $count
$totalFormatted = Format-FileSize $total
if($goal -gt 0 -and ++$iterLoop%10 -eq 0) {
Write-Progress "Downloading $url to $fileName" "Saving $totalFormatted of $goalFormatted ($total/$goal)" -id 0 -percentComplete (($total/$goal)*100)
}

if ($total -eq $goal) {
Write-Progress "Completed download of $url." "Completed download of $fileName ($goalFormatted)." -id 0 -Completed
if ($total -eq $goal) {
Write-Progress "Completed download of $url." "Completed download of $fileName ($goalFormatted)." -id 0 -Completed
}
}
}
} while ($count -gt 0)
Write-Host ""
Write-Host "Download of $([System.IO.Path]::GetFileName($fileName)) ($goalFormatted) completed."
} catch {
throw $_.Exception
} finally {
$ErrorActionPreference = $originalEAP
}
} while ($count -gt 0)
Write-Host ""
Write-Host "Download of $([System.IO.Path]::GetFileName($fileName)) ($goalFormatted) completed."
} catch {
throw $_.Exception
} finally {
$ErrorActionPreference = $originalEAP
}

$reader.Close()
if($fileName) {
$writer.Flush()
$writer.Close()
$reader.Close()
if($fileName) {
$writer.Flush()
$writer.Close()
}
if($Passthru){
$output
}
}
} catch {
if ($req -ne $null) {
$req.ServicePoint.MaxIdleTime = 0
$req.Abort();
# ruthlessly remove $req to ensure it isn't reused
Remove-Variable req
Start-Sleep 1
[GC]::Collect()
}
if($Passthru){
$output

Set-PowerShellExitCode 404
throw "The remote file either doesn't exist, is unauthorized, or is forbidden for url '$url'. $($_.Exception.Message)"
} finally {
if ($res -ne $null) {
$res.Close()
}
}
$res.Close();
}

# this could be cleaned up with http://learn-powershell.net/2013/02/08/powershell-and-events-object-events/
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
# limitations under the License.
#
# Based on http://stackoverflow.com/a/13571471/18475
function Get-FileName {
function Get-WebFileName {
param(
[string]$url = '',
[string]$defaultName,
$userAgent = 'chocolatey command line'
)

Write-Debug "Running 'Get-FileName' to determine name with url:'$url', defaultName:'$defaultName'";
Write-Debug "Running 'Get-WebFileName' to determine name with url:'$url', defaultName:'$defaultName'";

$originalFileName = $defaultName
$fileName = $null
Expand Down Expand Up @@ -126,9 +126,6 @@ param(
$containsEquals = [System.IO.Path]::GetFileName($url).Contains('=')
$fileName = [System.IO.Path]::GetFileName($response.ResponseUri.ToString())
}

$response.Close()
$response.Dispose()

[System.Text.RegularExpressions.Regex]$containsABadCharacter = New-Object Regex("[" + [System.Text.RegularExpressions.Regex]::Escape([System.IO.Path]::GetInvalidFileNameChars()) + "]", [System.Text.RegularExpressions.RegexOptions]::IgnorePatternWhitespace);

Expand All @@ -141,12 +138,22 @@ param(
Write-Debug "File name determined from url is '$fileName'"

return $fileName
} catch
{
$request.ServicePoint.MaxIdleTime = 0
$request.Abort();
} catch {
if ($request -ne $null) {
$request.ServicePoint.MaxIdleTime = 0
$request.Abort();
# ruthlessly remove $request to ensure it isn't reused
Remove-Variable request
Start-Sleep 1
[GC]::Collect()
}

Write-Debug "Url request/response failed - file name will be '$originalFileName': $($_)"

return $originalFileName
} finally {
if ($response -ne $null) {
$response.Close();
}
}
}
Loading

0 comments on commit 45b67c1

Please sign in to comment.