开发者

Download an unknown file using basic authentication and compensating for redirects

开发者 https://www.devze.com 2023-02-06 00:35 出处:网络
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 si

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号