Загрузите неизвестный файл, используя обычную аутентификацию и компенсируя перенаправления - PullRequest
1 голос
/ 23 января 2011

Серьезно?Это не может быть так много кода, чтобы просто загрузить файл.Обычная аутентификация и перенаправления кажутся простыми вещами.После того, как я прошел через этот код, я сел и подумал, что должен быть более простой подход, который я пропускаю.Я думаю, что есть даже проблемы с этим кодом (не компенсирует все успешные коды состояния, не надежен при разборе заголовка и т. Д.)

Редактировать: мне нужно знать имя файла, предоставленное веб-сервером длясохранить его локально под тем же именем.

Действительно ли мне нужно добавлять код в это решение или я упускаю более простой подход?

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()

}

1 Ответ

0 голосов
/ 24 января 2011

Я использую эту функцию для загрузки файла:

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)
}

Загружает файл и сохраняет его по пути $filePath. Пример:

download-file 'http://www.gravatar.com/avatar/c3ba8d5e440f00f11c7df365a19342b4?s=32&d=identicon&r=PG' c:\tempfile.jpg
ii c:\tempfile.jpg

Он должен обрабатывать перенаправления, но выдает исключение при возникновении непредвиденной ошибки.

...