| ■No74871 (DSC渡邊 さん) に返信
> 大きなデータをアップロードする際の注意点について書かれたURLを見つけて、そこには「AlowWriteStreamBuffering プロパティに Falseを設定して認証機能と共に利用すると 「この要求には、データのバッファが必要です」というエラーが発生する 」と書かれていましたが…
それは認証方式、AllowAutoRedirect、ContentLength、SendChunked等の設定によります。
プロトコル上、「長さ」の送信が必要になる場合と「再送」する可能性がある場合にバッファリングが必要になります。
> 結局、何が原因でアップロードエラーが発生したのか、はっきりしませんでした。
認証方式を書いていないのでわかりませんが、
設定を一切いじっていないということであればNTLMかKerberos等の接続指向の認証プロトコルを使っていたのではないですか?
通常HTTPはリクエスト毎に認証しますが、これらはTCP接続単位で認証するため、他の接続の影響を受けます。
認証用の空PUTはRFCに軽く述べられていますが、"Allow: PUT"とヘッダーを送り、書き込みたいURLと同じURLを使うべきです。
また、リダイレクトが発生することも考慮し、2回目のPUTではURLを書き換えておかなければなりません。
サーバーによってはセッションを保持しなければいけない場合もあります。
その他いくつかオマジナイを入れ、下記のようなコードがよいでしょう。(動作未確認ですが。
Dim fileToUpload As String
Dim fileLength As Long
Dim url As Uri
Dim nc As New NetworkCredential(ユーザー名, パスワード)
Dim cc As New CookieContainer 'for tracking session
Dim request As HttpWebRequest
'空ファイルPUT
fileToUpload = アップロードしたい大容量ファイルのフルパス
Using fs As New IO.FileStream(fileToUpload, IO.FileMode.Open, IO.FileAccess.Read)
fileLength = fs.Length
url = New Uri(サーバーのURL, "/" & サーバーのアップロード先フォルダ & IO.Path.GetFileName(fileToUpload))
request = DirectCast(System.Net.HttpWebRequest.Create(url), HttpWebRequest)
request.Method = WebRequestMethods.Http.Put
request.UnsafeAuthenticatedConnectionSharing = True 'for Nego/NTLM/Kerberos
request.KeepAlive = True
request.Headers.Add(HttpRequestHeader.Allow, "PUT") ' for EmptyPUT
request.AllowWriteStreamBuffering = True
request.PreAuthenticate = True
request.Headers.Add("Translate: f") ' for IIS
request.Credentials = nc
request.CookieContainer = cc
Using res As HttpWebResponse = request.GetResponse()
url = res.ResponseUri
End Using
request = DirectCast(System.Net.HttpWebRequest.Create(url), HttpWebRequest)
request.Method = WebRequestMethods.Http.Put
request.UnsafeAuthenticatedConnectionSharing = True
request.KeepAlive = True
request.ContentLength = fileLength
request.SendChunked = True
request.AllowWriteStreamBuffering = False 'no-buffering
request.PreAuthenticate = True ' for sharing auth info
request.AllowAutoRedirect = False
request.Headers.Add("Translate: f")
request.Credentials = nc
request.CookieContainer = cc
Using reqst As IO.Stream = request.GetRequestStream()
Dim buf As Byte() = New Byte(64 * 1024 - 1) {}
Dim r As Byte
While True
r = fs.Read(buf, 0, buf.Length)
If r = 0 Then Exit While
reqst.Write(buf, 0, r)
End While
End Using
End Using
Dim code As HttpStatusCode
Using response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
code = response.StatusCode
If code >= 300 AndAlso code < 400 Then Throw New Exception
End Using
|