2011-01-23 11 views
1

真剣に?単純にファイルをダウンロードするのは、このようなコードではありません。基本認証とリダイレクトは単純なもののようです。私がこのコードを読んだ後、私は戻ってきて、私が見落としている簡単なアプローチが必要だと考えました。私はこのコードにも問題があると考えています(ヘッダーの解析など、すべての成功したステータスコードを補うことはできません)基本認証を使用して不明なファイルをダウンロードし、リダイレクトを補償します

編集:保存するためにWebサーバーから提供されたファイル名を知る必要がありますローカルで同じ名前を使用します。

本当にこのソリューションにコードを追加する必要がありますか、簡単なアプローチを見落としていますか?

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

} 
+0

Webclient.Download()を使用しますか?それはあなたのためにすべてを処理します。 (AFAIKはデフォルトの認証情報キャッシュをサポートしていますが、私は本当にわかりません) –

+0

それは私が始めた単純な解決策でしたが、ファイル名がダウンロードされたことを検出できなかったので、同じ名前ローカルに。 – EdGruberman

答えて

0

私は、ファイルをダウンロードするには、この機能を使用します。

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 

リダイレクトは処理する必要がありますが、予期しないエラーが発生した場合は例外をスローします。

+0

私はこれに類似したものから始めました。ただし、リダイレクトはサーバー側で最新のファイルをダウンロードするように設計されています。私は同じように私のローカルファイルを保存するためにWebサーバーによって提供されたファイル名をつかむ必要があります。私は、間にあるリダイレクトヘッダーを解析することができないほど簡単な方法を見つけられませんでした。 また、私は基本的な認証に巻き込まれました。私はCredentialCacheを使用し、 "Basic"で使用するための資格証明を明確に識別したときにのみ動作するようにしました。 – EdGruberman

関連する問題