Download an unknown file using basic authentication and compensating for redirects
Seriously? It can't be this much code to simply download a file. Basic authentication and redirects seem like simple stuff. After I got through this code, I sat back and thought there has got to be a simpler approach that I am overlooking. I think there are even problems with this code (Doesn't compensate for开发者_JS百科 all successful status codes, not robust on header parsing, etc.)
Edit: I need to know the file name supplied by the web server to save it locally as the same name.
Do I really have to keep adding code to this solution or am I overlooking a simpler approach?
Function DownloadFile ([String]$Source, [String]$Destination, [String]$Domain = $Null, [String]$User = $Null, [String]$Password = $Null)
{
$Request = [System.Net.WebRequest]::Create($Source)
If ($User)
{
$Credential = New-Object System.Net.NetworkCredential($User, $Password, $Domain)
$CCache = New-Object System.Net.CredentialCache
$CCache.Add($Request.RequestURI, "Basic", $Credential)
$Request.Credentials = $CCache
}
$Request.AllowAutoRedirect = $False
$Response = $Request.GetResponse()
Switch ([Int]$Response.StatusCode)
{
302
{
If ($Response.Headers['Content-Disposition'])
{
#attachment; filename=something.ext
$FileName = $Response.Headers['Content-Disposition'].Split('=')[-1]
}
Else
{
#/foo/bar/something.ext
$FileName = $Response.Headers['Location'].Split('/')[-1]
}
$Response.Close()
$Location = New-Object System.URI($Request.RequestURI, $Response.Headers['Location'])
DownloadFile ($Location) ($Destination + '\' + $FileName) $Domain $User $Password
}
200
{
$ResponseStream = $Response.GetResponseStream()
$FileStream = New-Object System.IO.FileStream($Destination, [System.IO.FileMode]::Create)
$Buffer = New-Object Byte[] 1024
Do
{
$ReadLength = $ResponseStream.Read($Buffer, 0, 1024)
$FileStream.Write($Buffer, 0, $ReadLength)
} While ($ReadLength -ne 0)
$FileStream.Close()
}
Default
{
$Response.Close()
Throw "Unexpected HTTP Status Code $([Int]$Response.StatusCode)"
}
}
$Response.Close()
}
I use this function to download a file:
function download-file {
param([string]$url, [string]$filePath, [string]$user, [string]$pass)
if ($url -notmatch '^http://') {
$url = "http://$url"
write-host "Url corrected to $url"
}
$w = New-Object net.webclient
if ($user) {
write-debug "setting credentials, user name: $user"
$w.Credentials = New-Object System.Net.NetworkCredential($user,$pass)
}
$w.DownloadFile($url, $filePath)
}
It downloads the file and stores it to path $filePath
. Example:
download-file 'http://www.gravatar.com/avatar/c3ba8d5e440f00f11c7df365a19342b4?s=32&d=identicon&r=PG' c:\tempfile.jpg
ii c:\tempfile.jpg
It should handle redirects, but throws exception when any unexpected error occures.
精彩评论