diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.DownloadFile.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.DownloadFile.vb index 8bee94db45f..2290d1d9b62 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.DownloadFile.vb +++ b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.DownloadFile.vb @@ -2,9 +2,10 @@ ' The .NET Foundation licenses this file to you under the MIT license. Imports System.Net -Imports Microsoft.VisualBasic.CompilerServices +Imports System.Threading Imports Microsoft.VisualBasic.FileIO Imports Microsoft.VisualBasic.MyServices.Internal +Imports System.Windows.Forms Imports VbUtils = Microsoft.VisualBasic.CompilerServices.ExceptionUtils @@ -24,14 +25,21 @@ Namespace Microsoft.VisualBasic.Devices ''' Address to the remote file, http, ftp etc... ''' Name and path of file where download is saved. Public Sub DownloadFile(address As String, destinationFileName As String) - DownloadFile( - address, - destinationFileName, - userName:=DEFAULT_USERNAME, - password:=DEFAULT_PASSWORD, - showUI:=False, - connectionTimeout:=DEFAULT_TIMEOUT, - overwrite:=False) + Try + DownloadFileAsync( + address, + destinationFileName, + userName:=DEFAULT_USERNAME, + password:=DEFAULT_PASSWORD, + dialog:=Nothing, + connectionTimeout:=DEFAULT_TIMEOUT, + overwrite:=False).Wait() + Catch ex As Exception + If ex.InnerException IsNot Nothing Then + Throw ex.InnerException + End If + Throw + End Try End Sub ''' @@ -40,14 +48,22 @@ Namespace Microsoft.VisualBasic.Devices ''' to the remote file. ''' Name and path of file where download is saved. Public Sub DownloadFile(address As Uri, destinationFileName As String) - DownloadFile( - address, - destinationFileName, - userName:=DEFAULT_USERNAME, - password:=DEFAULT_PASSWORD, - showUI:=False, - connectionTimeout:=DEFAULT_TIMEOUT, - overwrite:=False) + Try + + DownloadFileAsync( + addressUri:=address, + destinationFileName, + userName:=DEFAULT_USERNAME, + password:=DEFAULT_PASSWORD, + dialog:=Nothing, + connectionTimeout:=DEFAULT_TIMEOUT, + overwrite:=False).Wait() + Catch ex As Exception + If ex.InnerException IsNot Nothing Then + Throw ex.InnerException + End If + Throw + End Try End Sub ''' @@ -63,14 +79,21 @@ Namespace Microsoft.VisualBasic.Devices userName As String, password As String) - DownloadFile( - address, - destinationFileName, - userName, - password, - showUI:=False, - connectionTimeout:=DEFAULT_TIMEOUT, - overwrite:=False) + Try + DownloadFileAsync( + address, + destinationFileName, + userName, + password, + dialog:=Nothing, + connectionTimeout:=DEFAULT_TIMEOUT, + overwrite:=False).Wait() + Catch ex As Exception + If ex.InnerException IsNot Nothing Then + Throw ex.InnerException + End If + Throw + End Try End Sub ''' @@ -86,14 +109,21 @@ Namespace Microsoft.VisualBasic.Devices userName As String, password As String) - DownloadFile( - address, - destinationFileName, - userName, - password, - showUI:=False, - connectionTimeout:=DEFAULT_TIMEOUT, - overwrite:=False) + Try + DownloadFileAsync( + addressUri:=address, + destinationFileName, + userName, + password, + dialog:=Nothing, + connectionTimeout:=DEFAULT_TIMEOUT, + overwrite:=False).Wait() + Catch ex As Exception + If ex.InnerException IsNot Nothing Then + Throw ex.InnerException + End If + Throw + End Try End Sub ''' @@ -117,97 +147,197 @@ Namespace Microsoft.VisualBasic.Devices connectionTimeout As Integer, overwrite As Boolean) - DownloadFile( - address, - destinationFileName, - userName, - password, - showUI, - connectionTimeout, - overwrite, - UICancelOption.ThrowException) + Dim dialog As ProgressDialog = Nothing + Try + dialog = GetProgressDialog(address, destinationFileName, showUI) + Dim cancelToken As New CancellationToken + Dim t As Task = DownloadFileAsync( + address, + destinationFileName, + userName, + password, + dialog, + connectionTimeout, + overwrite, + onUserCancel:=UICancelOption.ThrowException, + cancelToken) + + If t.IsFaulted Then + ' IsFaulted will be true if any parameters are bad + Throw t.Exception + Else + dialog?.ShowProgressDialog() + Do While Not (t.IsCompleted OrElse t.IsFaulted OrElse t.IsCanceled) + ' prevent UI freeze + Thread.Sleep(10) + Application.DoEvents() + Loop + If t.IsFaulted Then + Throw t.Exception + End If + If t.IsCanceled Then + Throw New OperationCanceledException + End If + End If + Catch ex As Exception + If ex.InnerException IsNot Nothing Then + If TryCast(ex.InnerException, OperationCanceledException) IsNot Nothing _ + AndAlso Environment.UserInteractive Then + + Try + IO.File.Delete(destinationFileName) + Catch + ' ignore error + End Try + End If + + Throw ex.InnerException + End If + Throw + Finally + CloseProgressDialog(dialog) + End Try End Sub ''' ''' Downloads a file from the network to the specified path. ''' - ''' Address to the remote file, http, ftp etc... - ''' Name and path of file where download is saved. + ''' to the remote file. + ''' + ''' Name and path of file where download is saved. + ''' ''' The name of the user performing the download. ''' The user's password. ''' Indicates whether or not to show a progress bar. ''' Time allotted before giving up on a connection. ''' - ''' Indicates whether or not the file should be overwritten - ''' if local file already exists. - ''' - ''' - ''' Indicates what to do if user cancels dialog (either or do nothing). + ''' Indicates whether or not the file should be overwritten if local file already exists. ''' Public Sub DownloadFile( - address As String, + address As Uri, destinationFileName As String, userName As String, password As String, showUI As Boolean, connectionTimeout As Integer, - overwrite As Boolean, - onUserCancel As UICancelOption) + overwrite As Boolean) - ' We're safe from DownloadFile(Nothing, ...) due to overload failure (DownloadFile(String,...) - ' vs. DownloadFile(Uri,...)). - ' However, it is good practice to verify address before calling Trim. - If String.IsNullOrWhiteSpace(address) Then + If address Is Nothing Then Throw VbUtils.GetArgumentNullException(NameOf(address)) End If - Dim addressUri As Uri = GetUri(address.Trim()) - - ' Get network credentials Dim networkCredentials As ICredentials = GetNetworkCredentials(userName, password) - - DownloadFile( - address:=addressUri, - destinationFileName, - networkCredentials, - showUI, - connectionTimeout, - overwrite, - onUserCancel) + Dim dialog As ProgressDialog = Nothing + Try + dialog = GetProgressDialog(address.AbsolutePath, destinationFileName, showUI) + Dim t As Task = DownloadFileAsync( + addressUri:=address, + destinationFileName, + networkCredentials, + dialog, + connectionTimeout, + overwrite, + onUserCancel:=UICancelOption.ThrowException) + + If t.IsFaulted Then + ' IsFaulted will be true if any parameters are bad + Throw t.Exception + Else + dialog?.ShowProgressDialog() + Do While Not (t.IsCompleted OrElse t.IsFaulted OrElse t.IsCanceled) + ' prevent UI freeze + Thread.Sleep(10) + Application.DoEvents() + Loop + If t.IsFaulted Then + Throw t.Exception + End If + If t.IsCanceled Then + Throw New OperationCanceledException + End If + End If + Catch ex As Exception + If ex.InnerException IsNot Nothing Then + Throw ex.InnerException + End If + Throw + Finally + CloseProgressDialog(dialog) + End Try End Sub ''' ''' Downloads a file from the network to the specified path. ''' - ''' to the remote file, - ''' - ''' Name and path of file where download is saved. - ''' + ''' Address to the remote file, http, ftp etc... + ''' Name and path of file where download is saved. ''' The name of the user performing the download. ''' The user's password. ''' Indicates whether or not to show a progress bar. ''' Time allotted before giving up on a connection. ''' - ''' Indicates whether or not the file should be overwritten if local file already exists. + ''' Indicates whether or not the file should be overwritten + ''' if local file already exists. + ''' + ''' + ''' Indicates what to do if user cancels dialog (either or do nothing). ''' Public Sub DownloadFile( - address As Uri, + address As String, destinationFileName As String, userName As String, password As String, showUI As Boolean, connectionTimeout As Integer, - overwrite As Boolean) + overwrite As Boolean, + onUserCancel As UICancelOption) + + ' We're safe from DownloadFile(Nothing, ...) due to overload failure (DownloadFile(String,...) + ' vs. DownloadFile(Uri,...)). + ' However, it is good practice to verify address before calling Trim. + If String.IsNullOrWhiteSpace(address) Then + Throw VbUtils.GetArgumentNullException(NameOf(address)) + End If - DownloadFile( - address, - destinationFileName, - userName, - password, - showUI, - connectionTimeout, - overwrite, - UICancelOption.ThrowException) + Dim addressUri As Uri = GetUri(address.Trim()) + Dim networkCredentials As ICredentials = GetNetworkCredentials(userName, password) + Dim dialog As ProgressDialog = Nothing + Try + dialog = GetProgressDialog(addressUri.AbsolutePath, destinationFileName, showUI) + Dim t As Task = DownloadFileAsync( + addressUri, + destinationFileName, + networkCredentials, + dialog, + connectionTimeout, + overwrite, + onUserCancel) + + If t.IsFaulted Then + ' IsFaulted will be true if any parameters are bad + Throw t.Exception + Else + dialog?.ShowProgressDialog() + Do While Not (t.IsCompleted OrElse t.IsFaulted OrElse t.IsCanceled) + ' prevent UI freeze + Thread.Sleep(10) + Application.DoEvents() + Loop + If t.IsFaulted Then + Throw t.Exception + End If + If t.IsCanceled Then + Throw New OperationCanceledException + End If + End If + Catch ex As Exception + If ex.InnerException IsNot Nothing Then + Throw ex.InnerException + End If + Throw + Finally + CloseProgressDialog(dialog) + End Try End Sub ''' @@ -240,17 +370,54 @@ Namespace Microsoft.VisualBasic.Devices overwrite As Boolean, onUserCancel As UICancelOption) - ' Get network credentials - Dim networkCredentials As ICredentials = GetNetworkCredentials(userName, password) + If connectionTimeout <= 0 Then + Throw VbUtils.GetArgumentExceptionWithArgName( + argumentName:=NameOf(connectionTimeout), + resourceKey:=SR.Network_BadConnectionTimeout) + End If - DownloadFile( - address, - destinationFileName, - networkCredentials, - showUI, - connectionTimeout, - overwrite, - onUserCancel) + If address Is Nothing Then + Throw VbUtils.GetArgumentNullException(NameOf(address)) + End If + + Dim dialog As ProgressDialog = Nothing + Try + dialog = GetProgressDialog(address.AbsolutePath, destinationFileName, showUI) + Dim t As Task = DownloadFileAsync( + addressUri:=address, + destinationFileName, + userName, + password, + dialog, + connectionTimeout, + overwrite, + onUserCancel) + + If t.IsFaulted Then + ' IsFaulted will be true if any parameters are bad + Throw t.Exception + Else + dialog?.ShowProgressDialog() + Do While Not (t.IsCompleted OrElse t.IsFaulted OrElse t.IsCanceled) + ' prevent UI freeze + Thread.Sleep(10) + Application.DoEvents() + Loop + If t.IsFaulted Then + Throw t.Exception + End If + If t.IsCanceled Then + Throw New OperationCanceledException + End If + End If + Catch ex As Exception + If ex.InnerException IsNot Nothing Then + Throw ex.InnerException + End If + Throw + Finally + CloseProgressDialog(dialog) + End Try End Sub ''' @@ -278,14 +445,46 @@ Namespace Microsoft.VisualBasic.Devices connectionTimeout As Integer, overwrite As Boolean) - DownloadFile( - address, - destinationFileName, - networkCredentials, - showUI, - connectionTimeout, - overwrite, - UICancelOption.ThrowException) + If address Is Nothing Then + Throw VbUtils.GetArgumentNullException(NameOf(address)) + End If + + Dim dialog As ProgressDialog = Nothing + Try + dialog = GetProgressDialog(address.AbsolutePath, destinationFileName, showUI) + Dim t As Task = DownloadFileAsync( + addressUri:=address, + destinationFileName, + networkCredentials, + dialog, + connectionTimeout, + overwrite) + + If t.IsFaulted Then + ' IsFaulted will be true if any parameters are bad + Throw t.Exception + Else + dialog?.ShowProgressDialog() + Do While Not (t.IsCompleted OrElse t.IsFaulted OrElse t.IsCanceled) + ' prevent UI freeze + Thread.Sleep(10) + Application.DoEvents() + Loop + If t.IsFaulted Then + Throw t.Exception + End If + If t.IsCanceled Then + Throw New OperationCanceledException + End If + End If + Catch ex As Exception + If ex.InnerException IsNot Nothing Then + Throw ex.InnerException + End If + Throw + Finally + CloseProgressDialog(dialog) + End Try End Sub ''' @@ -314,66 +513,52 @@ Namespace Microsoft.VisualBasic.Devices onUserCancel As UICancelOption) If connectionTimeout <= 0 Then - Throw VbUtils.GetArgumentExceptionWithArgName(NameOf(connectionTimeout), SR.Network_BadConnectionTimeout) + Throw VbUtils.GetArgumentExceptionWithArgName( + argumentName:=NameOf(connectionTimeout), + resourceKey:=SR.Network_BadConnectionTimeout) End If If address Is Nothing Then Throw VbUtils.GetArgumentNullException(NameOf(address)) End If - Using client As New WebClientExtended - client.Timeout = connectionTimeout - - ' Don't use passive mode if we're showing UI - client.UseNonPassiveFtp = showUI - - ' Construct the local file. This will validate the full name and path - Dim fullFilename As String = FileSystemUtils.NormalizeFilePath(destinationFileName, NameOf(destinationFileName)) - - ' Sometime a path that can't be parsed is normalized to the current directory. This makes sure we really - ' have a file and path - If IO.Directory.Exists(fullFilename) Then - Throw VbUtils.GetInvalidOperationException(SR.Network_DownloadNeedsFilename) - End If - - ' Throw if the file exists and the user doesn't want to overwrite - If IO.File.Exists(fullFilename) And Not overwrite Then - Throw New IO.IOException(VbUtils.GetResourceString(SR.IO_FileExists_Path, destinationFileName)) + Dim dialog As ProgressDialog = Nothing + Try + dialog = GetProgressDialog(address:=address.AbsolutePath, destinationFileName, showUI) + Dim t As Task = DownloadFileAsync( + addressUri:=address, + destinationFileName, + networkCredentials, + dialog, + connectionTimeout, + overwrite, + onUserCancel) + + If t.IsFaulted Then + ' IsFaulted will be true if any parameters are bad + Throw t.Exception + Else + dialog?.ShowProgressDialog() + Do While Not (t.IsCompleted OrElse t.IsFaulted OrElse t.IsCanceled) + ' prevent UI freeze + Thread.Sleep(10) + Application.DoEvents() + Loop + If t.IsFaulted Then + Throw t.Exception + End If + If t.IsCanceled Then + Throw New OperationCanceledException + End If End If - - ' Set credentials if we have any - If networkCredentials IsNot Nothing Then - client.Credentials = networkCredentials - End If - - Dim dialog As ProgressDialog = GetProgressDialog(address.AbsolutePath, fullFilename, showUI) - - ' Check to see if the target directory exists. If it doesn't, create it - Dim targetDirectory As String = IO.Path.GetDirectoryName(fullFilename) - - ' Make sure we have a meaningful directory. If we don't, the destinationFileName is suspect - If String.IsNullOrEmpty(targetDirectory) Then - Throw VbUtils.GetInvalidOperationException(SR.Network_DownloadNeedsFilename) - End If - - If Not IO.Directory.Exists(targetDirectory) Then - IO.Directory.CreateDirectory(targetDirectory) - End If - - ' Create the copier - Dim copier As New WebClientCopy(client, dialog) - - ' Download the file - copier.DownloadFile(address, fullFilename) - - ' Handle a dialog cancel - If showUI _ - AndAlso Environment.UserInteractive _ - AndAlso onUserCancel = UICancelOption.ThrowException _ - AndAlso dialog.UserCanceledTheDialog Then - Throw New OperationCanceledException() + Catch ex As Exception + If ex.InnerException IsNot Nothing Then + Throw ex.InnerException End If - End Using + Throw + Finally + CloseProgressDialog(dialog) + End Try End Sub End Class diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.DownloadFileAsync.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.DownloadFileAsync.vb new file mode 100644 index 00000000000..61b260e8470 --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.DownloadFileAsync.vb @@ -0,0 +1,374 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.Net +Imports System.Net.Http +Imports System.Threading +Imports Microsoft.VisualBasic.CompilerServices +Imports Microsoft.VisualBasic.FileIO +Imports Microsoft.VisualBasic.MyServices.Internal + +Imports VbUtils = Microsoft.VisualBasic.CompilerServices.ExceptionUtils + +Namespace Microsoft.VisualBasic.Devices + + Partial Public Class Network + + ''' + ''' Sends and receives a packet to and from the passed in Uri. + ''' Maps older networkCredentials to HttpClientHandler. + ''' + ''' Uri to the remote file. + ''' Name and path of file where download is saved. + ''' The credentials of the user performing the download. + ''' A ProgressDialog or Nothing. + ''' Time allotted before giving up on a connection. + ''' + ''' Indicates whether or not the file should be overwritten if local file already exists. + ''' + ''' + ''' + Friend Shared Function DownloadFileAsync( + addressUri As Uri, + destinationFileName As String, + networkCredentials As ICredentials, + dialog As ProgressDialog, + connectionTimeout As Integer, + overwrite As Boolean, + onUserCancel As UICancelOption, + Optional cancelToken As CancellationToken = Nothing) As Task + + Dim clientHandler As HttpClientHandler = + If(networkCredentials Is Nothing, + New HttpClientHandler, + New HttpClientHandler With {.Credentials = networkCredentials}) + Return DownloadFileAsync( + addressUri, + destinationFileName, + clientHandler, + dialog, + connectionTimeout, + overwrite, + onUserCancel, + cancelToken) + End Function + + ''' + ''' Downloads a file from the network to the specified path. + ''' + ''' Uri to the remote file + ''' Name and path of file where download is saved. + ''' The name of the user performing the download. + ''' The user's password. + ''' A ProgressDialog or Nothing. + ''' Time allotted before giving up on a connection. + ''' + ''' Indicates whether or not the file should be overwritten if local file already exists. + ''' + ''' + Friend Shared Async Function DownloadFileAsync( + addressUri As Uri, + destinationFileName As String, + userName As String, + password As String, + dialog As ProgressDialog, + connectionTimeout As Integer, + overwrite As Boolean, + Optional cancelToken As CancellationToken = Nothing) As Task + + Dim networkCredentials As ICredentials = GetNetworkCredentials(userName, password) + Dim clientHandler As HttpClientHandler = + If(networkCredentials Is Nothing, + New HttpClientHandler, + New HttpClientHandler With {.Credentials = networkCredentials}) + Await DownloadFileAsync( + addressUri, + destinationFileName, + clientHandler, + dialog, + connectionTimeout, + overwrite, + onUserCancel:=UICancelOption.ThrowException, + cancelToken).ConfigureAwait(continueOnCapturedContext:=False) + End Function + + ''' + ''' Downloads a file from the network to the specified path. + ''' + ''' Uri to the remote file + ''' Name and path of file where download is saved. + ''' The name of the user performing the download. + ''' The user's password. + ''' ProgressDialog or Nothing. + ''' Time allotted before giving up on a connection. + ''' + ''' Indicates whether or not the file should be overwritten if local file already exists. + ''' + ''' + ''' Indicates what to do if user cancels dialog (either throw or do nothing). + ''' + ''' + Friend Shared Async Function DownloadFileAsync( + addressUri As Uri, + destinationFileName As String, + userName As String, + password As String, + dialog As ProgressDialog, + connectionTimeout As Integer, + overwrite As Boolean, + onUserCancel As UICancelOption, + Optional cancelToken As CancellationToken = Nothing) As Task + + ' Get network credentials + Dim networkCredentials As ICredentials = GetNetworkCredentials(userName, password) + + Await DownloadFileAsync( + addressUri, + destinationFileName, + clientHandler:=If( + networkCredentials Is Nothing, + New HttpClientHandler, + New HttpClientHandler With {.Credentials = networkCredentials}), + dialog, + connectionTimeout, + overwrite, + onUserCancel, + cancelToken).ConfigureAwait(continueOnCapturedContext:=False) + End Function + + ''' + ''' Downloads a file from the network to the specified path. + ''' + ''' Address to the remote file, http, ftp etc... + ''' Name and path of file where download is saved. + ''' The name of the user performing the download. + ''' The user's password. + ''' A ProgressDialog or Nothing. + ''' Time allotted before giving up on a connection. + ''' + ''' Indicates whether or not the file should be overwritten if local file already exists. + ''' + ''' + Friend Shared Async Function DownloadFileAsync( + address As String, + destinationFileName As String, + userName As String, + password As String, + dialog As ProgressDialog, + connectionTimeout As Integer, + overwrite As Boolean, + Optional cancelToken As CancellationToken = Nothing) As Task + + If String.IsNullOrWhiteSpace(address) Then + Throw VbUtils.GetArgumentNullException(NameOf(address)) + End If + + Dim addressUri As Uri = GetUri(address.Trim()) + + ' Get network credentials + Dim networkCredentials As ICredentials = GetNetworkCredentials(userName, password) + + Dim clientHandler As HttpClientHandler = + If(networkCredentials Is Nothing, + New HttpClientHandler, + New HttpClientHandler With {.Credentials = networkCredentials}) + Await DownloadFileAsync( + addressUri, + destinationFileName, + clientHandler, + dialog, + connectionTimeout, + overwrite, + UICancelOption.ThrowException, + cancelToken).ConfigureAwait(continueOnCapturedContext:=False) + End Function + + ''' + ''' Downloads a file from the network to the specified path. + ''' + ''' Address to the remote file, http, ftp etc... + ''' Name and path of file where download is saved. + ''' The name of the user performing the download. + ''' The user's password. + ''' A ProgressDialog or Nothing. + ''' Time allotted before giving up on a connection. + ''' + ''' Indicates whether or not the file should be overwritten if local file already exists. + ''' + ''' + ''' Indicates what to do if user cancels dialog (either throw or do nothing). + ''' + ''' + Friend Shared Async Function DownloadFileAsync( + address As String, + destinationFileName As String, + userName As String, + password As String, + dialog As ProgressDialog, + connectionTimeout As Integer, + overwrite As Boolean, + onUserCancel As UICancelOption, + Optional cancelToken As CancellationToken = Nothing) As Task + + If String.IsNullOrWhiteSpace(address) Then + Throw VbUtils.GetArgumentNullException(NameOf(address)) + End If + + Dim addressUri As Uri = GetUri(address.Trim()) + + ' Get network credentials + Dim networkCredentials As ICredentials = GetNetworkCredentials(userName, password) + + Dim clientHandler As HttpClientHandler = + If(networkCredentials Is Nothing, + New HttpClientHandler, + New HttpClientHandler With {.Credentials = networkCredentials}) + Await DownloadFileAsync( + addressUri, + destinationFileName, + clientHandler, + dialog, + connectionTimeout, + overwrite, + onUserCancel, + cancelToken).ConfigureAwait(continueOnCapturedContext:=False) + End Function + + ''' + ''' Downloads a file from the network to the specified path. + ''' + ''' Uri to the remote file + ''' Name and path of file where download is saved. + ''' The credentials of the user performing the download. + ''' A ProgressDialog or Nothing. + ''' Time allotted before giving up on a connection. + ''' + ''' Indicates whether or not the file should be overwritten if local file already exists. + ''' + ''' + ''' + ''' Function will Throw on unhandled exceptions. + ''' + Friend Shared Async Function DownloadFileAsync( + addressUri As Uri, + destinationFileName As String, + networkCredentials As ICredentials, + dialog As ProgressDialog, + connectionTimeout As Integer, + overwrite As Boolean, + Optional cancelToken As CancellationToken = Nothing) As Task + + Dim clientHandler As HttpClientHandler = + If(networkCredentials Is Nothing, + New HttpClientHandler, + New HttpClientHandler With {.Credentials = networkCredentials}) + Await DownloadFileAsync( + addressUri, + destinationFileName, + clientHandler, + dialog, + connectionTimeout, + overwrite, + onUserCancel:=UICancelOption.ThrowException, + cancelToken).ConfigureAwait(continueOnCapturedContext:=False) + End Function + + ''' + ''' Downloads a file from the network to the specified path. + ''' + ''' Uri to the remote file + ''' Name and path of file where download is saved. + ''' An HttpClientHandler of the user performing the download. + ''' Progress Dialog. + ''' Time allotted before giving up on a connection. + ''' + ''' Indicates whether or not the file should be overwritten if local file already exists. + ''' + ''' + ''' Indicates what to do if user cancels dialog (either throw or do nothing). + ''' + ''' + ''' Calls to all the other overloads will come through here. + Friend Shared Async Function DownloadFileAsync( + addressUri As Uri, + destinationFileName As String, + clientHandler As HttpClientHandler, + dialog As ProgressDialog, + connectionTimeout As Integer, + overwrite As Boolean, + onUserCancel As UICancelOption, + cancelToken As CancellationToken) As Task + + If cancelToken = Nothing Then + cancelToken = New CancellationTokenSource().Token + End If + + If connectionTimeout <= 0 Then + Throw VbUtils.GetArgumentExceptionWithArgName( + argumentName:=NameOf(connectionTimeout), + resourceKey:=SR.Network_BadConnectionTimeout) + End If + + If addressUri Is Nothing Then + Throw VbUtils.GetArgumentNullException(NameOf(addressUri)) + End If + + ' Set credentials if we have any + Dim client As HttpClient + If clientHandler Is Nothing Then + client = New HttpClient() + Else + client = New HttpClient(clientHandler) + End If + + client.Timeout = New TimeSpan(0, 0, 0, 0, connectionTimeout) + + ' Construct the local file. This will validate the full name and path + Dim normalizedFilePath As String = FileSystemUtils.NormalizeFilePath( + path:=destinationFileName, + paramName:=NameOf(destinationFileName)) + + ' Sometime a path that can't be parsed is normalized to the current directory. + ' This makes sure we really have a file and path + If IO.Directory.Exists(normalizedFilePath) Then + Throw VbUtils.GetInvalidOperationException(SR.Network_DownloadNeedsFilename) + End If + + ' Throw if the file exists and the user doesn't want to overwrite + If Not overwrite AndAlso IO.File.Exists(normalizedFilePath) Then + Throw New IO.IOException( + message:=VbUtils.GetResourceString(SR.IO_FileExists_Path, destinationFileName)) + End If + + ' Check to see if the target directory exists. If it doesn't, create it + Dim targetDirectory As String = IO.Path.GetDirectoryName(normalizedFilePath) + + ' Make sure we have a meaningful directory. If we don't, the destinationFileName is suspect + If String.IsNullOrEmpty(targetDirectory) Then + Throw VbUtils.GetInvalidOperationException(SR.Network_DownloadNeedsFilename) + End If + + If Not IO.Directory.Exists(targetDirectory) Then + IO.Directory.CreateDirectory(targetDirectory) + End If + + ' Create the copier + Dim copier As New HttpClientCopy(client, dialog) + + ' Download the file + Try + Await copier.DownloadFileWorkerAsync( + addressUri, + normalizedFilePath, + externalToken:=cancelToken).ConfigureAwait(continueOnCapturedContext:=False) + Catch ex As Exception + If onUserCancel = UICancelOption.ThrowException OrElse Not dialog.UserCanceledTheDialog Then + CloseProgressDialog(dialog) + Throw + End If + End Try + + End Function + + End Class +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.UploadFile.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.UploadFile.vb index 9a2ee54c814..dcf939a4809 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.UploadFile.vb +++ b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.UploadFile.vb @@ -2,6 +2,9 @@ ' The .NET Foundation licenses this file to you under the MIT license. Imports System.Net +Imports System.Net.Http +Imports System.Threading +Imports System.Windows.Forms Imports Microsoft.VisualBasic.CompilerServices Imports Microsoft.VisualBasic.FileIO Imports Microsoft.VisualBasic.MyServices.Internal @@ -262,6 +265,7 @@ Namespace Microsoft.VisualBasic.Devices connectionTimeout As Integer, onUserCancel As UICancelOption) + ' Construct the local file. This will validate the full name and path sourceFileName = FileSystemUtils.NormalizeFilePath(sourceFileName, NameOf(sourceFileName)) ' Make sure the file exists @@ -280,15 +284,13 @@ Namespace Microsoft.VisualBasic.Devices Throw GetArgumentNullException(NameOf(address)) End If - Using client As New WebClientExtended() - client.Timeout = connectionTimeout - - ' Set credentials if we have any - If networkCredentials IsNot Nothing Then - client.Credentials = networkCredentials - End If - - Dim dialog As ProgressDialog = Nothing + Dim dialog As ProgressDialog = Nothing + Try + ' Get network credentials + Dim clientHandler As HttpClientHandler = + If(networkCredentials Is Nothing, + New HttpClientHandler, + New HttpClientHandler With {.Credentials = networkCredentials}) If InteractiveEnvironment(showUI) Then dialog = New ProgressDialog With { .Text = GetResourceString(SR.ProgressDialogUploadingTitle, sourceFileName), @@ -299,19 +301,39 @@ Namespace Microsoft.VisualBasic.Devices } End If - ' Create the copier - Dim copier As New WebClientCopy(client, dialog) - - ' Download the file - copier.UploadFile(sourceFileName, address) - - ' Handle a dialog cancel - If InteractiveEnvironment(showUI) Then - If onUserCancel = UICancelOption.ThrowException And dialog.UserCanceledTheDialog Then - Throw New OperationCanceledException() + Dim t As Task = UploadFileAsync( + sourceFileName, + addressUri:=address, + clientHandler, + dialog, + connectionTimeout, + onUserCancel) + + If t.IsFaulted Then + ' IsFaulted will be true if any parameters are bad + Throw t.Exception + Else + dialog?.ShowProgressDialog() + Do While Not (t.IsCompleted OrElse t.IsFaulted OrElse t.IsCanceled) + ' prevent UI freeze + Thread.Sleep(10) + Application.DoEvents() + Loop + If t.IsFaulted Then + Throw t.Exception End If + If t.IsCanceled Then + Throw New OperationCanceledException + End If + End If + Catch ex As Exception + If ex.InnerException IsNot Nothing Then + Throw ex.InnerException End If - End Using + Throw + Finally + CloseProgressDialog(dialog) + End Try End Sub diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.UploadFileAsync.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.UploadFileAsync.vb new file mode 100644 index 00000000000..b5fc3d91b2e --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/Network.UploadFileAsync.vb @@ -0,0 +1,89 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.Net +Imports System.Net.Http +Imports System.Threading +Imports Microsoft.VisualBasic.CompilerServices +Imports Microsoft.VisualBasic.FileIO +Imports Microsoft.VisualBasic.MyServices.Internal + +Imports VbUtils = Microsoft.VisualBasic.CompilerServices.ExceptionUtils + +Namespace Microsoft.VisualBasic.Devices + + Partial Public Class Network + ''' + ''' Uploads a file to the network to the specified path. + ''' + ''' Name and path of file to be uploaded. + ''' Uri to the remote file + ''' An HttpClientHandler of the user performing the download. + ''' Progress Dialog. + ''' Time allotted before giving up on a connection. + ''' Indicates what to do if user cancels dialog (either throw or do nothing). + ''' + ''' Calls to all the other overloads will come through here. + Friend Shared Async Function UploadFileAsync( + sourceFileName As String, + addressUri As Uri, + clientHandler As HttpClientHandler, + dialog As ProgressDialog, + connectionTimeout As Integer, + onUserCancel As UICancelOption, + Optional cancelToken As CancellationToken = Nothing) As Task + + If cancelToken = Nothing Then + cancelToken = New CancellationTokenSource().Token + End If + + If connectionTimeout <= 0 Then + Throw VbUtils.GetArgumentExceptionWithArgName(NameOf(connectionTimeout), SR.Network_BadConnectionTimeout) + End If + + If addressUri Is Nothing Then + Throw VbUtils.GetArgumentNullException(NameOf(addressUri)) + End If + + Dim normalizedFilePath As String = FileSystemUtils.NormalizeFilePath(sourceFileName, NameOf(sourceFileName)) + + ' Make sure we have a meaningful file. + If String.IsNullOrEmpty(normalizedFilePath) Then + Throw VbUtils.GetInvalidOperationException(SR.Network_DownloadNeedsFilename) + End If + + Dim client As HttpClient = If(clientHandler Is Nothing, + New HttpClient(), + New HttpClient(clientHandler)) + client.Timeout = New TimeSpan(0, 0, 0, 0, connectionTimeout) + + ' Create the copier + Dim copier As New HttpClientCopy(client, dialog) + + ' Upload the file + Try + Await copier.UploadFileWorkerAsync( + filePath:=normalizedFilePath, + requestURI:=addressUri, + externalToken:=cancelToken).ConfigureAwait(continueOnCapturedContext:=False) + Catch ioEx As IO.IOException + Throw + + Catch ex As Exception + If onUserCancel = UICancelOption.ThrowException OrElse (dialog IsNot Nothing AndAlso Not dialog.UserCanceledTheDialog) Then + If ex.Message.Contains("401") Then + Throw New WebException(SR.net_webstatus_Unauthorized, WebExceptionStatus.ProtocolError) + End If + Throw + End If + If ex.Message.Contains("401") Then + Throw New WebException(SR.net_webstatus_Unauthorized) + End If + Finally + CloseProgressDialog(dialog) + End Try + + End Function + + End Class +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/NetworkUtilities.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/NetworkUtilities.vb index fcfd6afa251..a5b264c37ac 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/NetworkUtilities.vb +++ b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/NetworkUtilities.vb @@ -68,7 +68,7 @@ Namespace Microsoft.VisualBasic.Devices showUI As Boolean) As ProgressDialog If InteractiveEnvironment(showUI) Then - 'Construct the local file. This will validate the full name and path + ' Construct the local file. This will validate the full name and path Dim fullFilename As String = FileSystemUtils.NormalizeFilePath( path:=destinationFileName, paramName:=NameOf(destinationFileName)) @@ -95,7 +95,7 @@ Namespace Microsoft.VisualBasic.Devices Try Return New Uri(address) Catch ex As UriFormatException - 'Throw an exception with an error message more appropriate to our API + ' Throw an exception with an error message more appropriate to our API Throw GetArgumentExceptionWithArgName( argumentName:=NameOf(address), resourceKey:=SR.Network_InvalidUriString, diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/WebClientExtended.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/WebClientExtended.vb deleted file mode 100644 index ca95e62b799..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/Devices/WebClientExtended.vb +++ /dev/null @@ -1,77 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Net - -Namespace Microsoft.VisualBasic.Devices - - ''' - ''' Temporary class used to provide WebClient with a timeout property. - ''' - ''' This class will be deleted when Timeout is added to WebClient. - Friend NotInheritable Class WebClientExtended - Inherits WebClient - - ' The Timeout value to be used by WebClient's WebRequest for Downloading or Uploading a file - Private _timeout As Integer = 100000 - - ' Flag used to indicate whether or not we should use passive mode when ftp downloading - Private _useNonPassiveFtp As Boolean - -#Disable Warning BC41004 ' First statement of this 'Sub New' should be an explicit call to 'MyBase.New' or 'MyClass.New' because the constructor in the base class is marked obsolete - - Friend Sub New() - End Sub - -#Enable Warning BC41004 ' First statement of this 'Sub New' should be an explicit call to 'MyBase.New' or 'MyClass.New' because the constructor in the base class is marked obsolete - - ''' - ''' Sets or indicates the timeout used by WebRequest used by WebClient - ''' - Public WriteOnly Property Timeout() As Integer - Set(value As Integer) - Debug.Assert(value > 0, "illegal value for timeout") - _timeout = value - End Set - End Property - - ''' - ''' Enables switching the server to non passive mode. - ''' - ''' We need this in order for the progress UI on a download to work - Public WriteOnly Property UseNonPassiveFtp() As Boolean - Set(value As Boolean) - _useNonPassiveFtp = value - End Set - End Property - - ''' - ''' Makes sure that the timeout value for WebRequests (used for all Download - ''' and Upload methods) is set to the Timeout value. - ''' - ''' - Protected Overrides Function GetWebRequest(address As Uri) As WebRequest - Dim request As WebRequest = MyBase.GetWebRequest(address) - - Debug.Assert(request IsNot Nothing, "Unable to get WebRequest from base class") - If request IsNot Nothing Then - request.Timeout = _timeout - If _useNonPassiveFtp Then - Dim ftpRequest As FtpWebRequest = TryCast(request, FtpWebRequest) - If ftpRequest IsNot Nothing Then - ftpRequest.UsePassive = False - End If - End If - - Dim httpRequest As HttpWebRequest = TryCast(request, HttpWebRequest) - If httpRequest IsNot Nothing Then - httpRequest.AllowAutoRedirect = False - End If - - End If - - Return request - End Function - - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/HttpClientCopy.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/HttpClientCopy.vb new file mode 100644 index 00000000000..4095b707292 --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/HttpClientCopy.vb @@ -0,0 +1,277 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.IO +Imports System.Net +Imports System.Net.Http +Imports System.Net.Http.Headers +Imports System.Threading +Imports Microsoft.VisualBasic.Devices.NetworkUtilities + +Namespace Microsoft.VisualBasic.MyServices.Internal + + ''' + ''' Class that controls the thread that does the actual work of downloading or uploading. + ''' + Friend NotInheritable Class HttpClientCopy + + ' Dialog shown if user wants to see progress UI. Allows the user to cancel the file transfer. + Private WithEvents _progressDialog As ProgressDialog + + Private Const BufferSize As Integer = 8192 + + ' The WebClient performs the downloading or uploading operations for us + Private ReadOnly _httpClient As HttpClient + + Private _cancelTokenSourceGet As CancellationTokenSource + Private _cancelTokenSourcePost As CancellationTokenSource + Private _cancelTokenSourceReadStream As CancellationTokenSource + Private _cancelTokenSourceWriteStream As CancellationTokenSource + + ' The percentage of the operation completed + Private _percentage As Integer + + ' Used for invoking ProgressDialog.Increment + Private Delegate Sub DoIncrement(Increment As Integer) + + ''' + ''' Creates an instance of a HttpClientCopy, used to download or upload a file. + ''' + ''' The HttpClient used to do the downloading or uploading. + ''' UI for indicating progress. + Public Sub New(client As HttpClient, dialog As ProgressDialog) + + Debug.Assert(client IsNot Nothing, "No HttpClient") + + _httpClient = client + _progressDialog = dialog + If _progressDialog IsNot Nothing Then + AddHandler _progressDialog.UserHitCancel, AddressOf _progressDialog_UserHitCancel + End If + + End Sub + + ''' + ''' If the user clicks cancel on the Progress dialog, we need to cancel + ''' the current async file transfer operation. + ''' + ''' + ''' Note that we don't want to close the progress dialog here. Wait until + ''' the actual file transfer cancel event comes through and do it there. + ''' + Private Sub _progressDialog_UserHitCancel() + ' Cancel the upload/download transfer. We'll close the ProgressDialog + ' as soon as the HttpClient cancels the xfer. + _cancelTokenSourceGet?.Cancel() + _cancelTokenSourceReadStream?.Cancel() + _cancelTokenSourcePost?.Cancel() + _cancelTokenSourceWriteStream?.Cancel() + End Sub + + ''' + ''' Notifies the progress dialog to increment the progress bar. + ''' + ''' The percentage of bytes read. + Private Sub InvokeIncrement(progressPercentage As Integer) + ' Don't invoke unless dialog is up and running + If _progressDialog IsNot Nothing Then + If _progressDialog.IsHandleCreated Then + + ' For performance, don't invoke if increment is 0 + Dim increment As Integer = progressPercentage - _percentage + _percentage = progressPercentage + If increment > 0 Then + _progressDialog.BeginInvoke(method:=New DoIncrement(AddressOf _progressDialog.Increment), increment) + End If + + End If + End If + End Sub + + ''' + ''' Downloads a file. + ''' + ''' The source for the file. + ''' The path and name where the file is to be saved. + Friend Async Function DownloadFileWorkerAsync(addressUri As Uri, normalizedFilePath As String, externalToken As CancellationToken) As Task + Debug.Assert(_httpClient IsNot Nothing, "No HttpClient") + Debug.Assert(addressUri IsNot Nothing, "No address") + Dim directoryPath As String = Path.GetDirectoryName(Path.GetFullPath(normalizedFilePath)) + Debug.Assert((Not String.IsNullOrWhiteSpace(normalizedFilePath)) AndAlso + Directory.Exists(directoryPath), "Invalid path") + + _cancelTokenSourceGet = New CancellationTokenSource() + _cancelTokenSourceReadStream = New CancellationTokenSource() + _cancelTokenSourceWriteStream = New CancellationTokenSource() + + Dim response As HttpResponseMessage = Nothing + Dim totalBytesRead As Long = 0 + Try + Using linkedCts As CancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_cancelTokenSourceGet.Token, externalToken) + response = Await _httpClient.GetAsync( + requestUri:=addressUri, + completionOption:=HttpCompletionOption.ResponseHeadersRead, + cancellationToken:=_cancelTokenSourceGet.Token).ConfigureAwait(continueOnCapturedContext:=False) + End Using + Catch ex As TaskCanceledException + If ex.CancellationToken = externalToken Then + externalToken.ThrowIfCancellationRequested() + ElseIf ex.CancellationToken = _cancelTokenSourceGet.Token Then + ' a real cancellation, triggered by the caller + Throw + Else + Throw New WebException(SR.net_webstatus_Timeout, WebExceptionStatus.Timeout) + End If + End Try + Select Case response.StatusCode + Case HttpStatusCode.OK + _cancelTokenSourceReadStream = CancellationTokenSource.CreateLinkedTokenSource(New CancellationTokenSource().Token, externalToken) + _cancelTokenSourceWriteStream = CancellationTokenSource.CreateLinkedTokenSource(New CancellationTokenSource().Token, externalToken) + Dim contentLength? As Long = response?.Content.Headers.ContentLength + If contentLength.HasValue Then + Using responseStream As Stream = Await response.Content.ReadAsStreamAsync( + cancellationToken:=_cancelTokenSourceReadStream.Token). + ConfigureAwait(continueOnCapturedContext:=False) + + Using fileStream As New FileStream( + path:=normalizedFilePath, + mode:=FileMode.Create, + access:=FileAccess.Write, + share:=FileShare.None) + + Dim buffer(BufferSize - 1) As Byte + Dim bytesRead As Integer + Try + bytesRead = Await responseStream.ReadAsync( + buffer:=buffer.AsMemory(start:=0, buffer.Length), + cancellationToken:=_cancelTokenSourceReadStream.Token). + ConfigureAwait(continueOnCapturedContext:=False) + + Do While bytesRead > 0 + totalBytesRead += bytesRead + + Await fileStream.WriteAsync( + buffer:=buffer.AsMemory(0, bytesRead), + cancellationToken:=_cancelTokenSourceWriteStream.Token). + ConfigureAwait(continueOnCapturedContext:=False) + + If _progressDialog IsNot Nothing Then + Dim percentage As Integer = CInt(totalBytesRead / contentLength.Value * 100) + InvokeIncrement(percentage) + End If + bytesRead = Await responseStream.ReadAsync( + buffer:=buffer.AsMemory(start:=0, buffer.Length), + cancellationToken:=_cancelTokenSourceReadStream.Token). + ConfigureAwait(continueOnCapturedContext:=False) + Loop + Finally + CloseProgressDialog(_progressDialog) + End Try + End Using + End Using + + If _progressDialog IsNot Nothing Then + RemoveHandler _progressDialog.UserHitCancel, AddressOf _progressDialog_UserHitCancel + End If + End If + Case HttpStatusCode.NotFound + Throw New WebException(SR.net_webstatus_NotFound) + Case HttpStatusCode.Found, + HttpStatusCode.Moved, + HttpStatusCode.NotModified, + HttpStatusCode.PermanentRedirect + Throw New WebException() + Case HttpStatusCode.Forbidden, + HttpStatusCode.NetworkAuthenticationRequired, + HttpStatusCode.Unauthorized + Throw New WebException(SR.net_webstatus_Unauthorized) + Case HttpStatusCode.RequestTimeout + Throw New WebException(SR.net_webstatus_Timeout) + Case Else + Throw New WebException() + End Select + response?.Dispose() + End Function + + ''' + ''' Uploads a file + ''' + ''' The name and path of the source file + ''' The address to which the file is uploaded + Public Async Function UploadFileWorkerAsync(filePath As String, requestURI As Uri, externalToken As CancellationToken) As Task + Debug.Assert(_httpClient IsNot Nothing, "No WebClient") + Debug.Assert(requestURI IsNot Nothing, "No address") + + _cancelTokenSourceReadStream = New CancellationTokenSource() + _cancelTokenSourcePost = New CancellationTokenSource() + Dim contentLength As Long = New FileInfo(filePath).Length + Dim totalBytesRead As Long = 0 + Dim progress As Action(Of Long, Long) = + Sub(bytesRead As Long, streamLength As Long) + totalBytesRead += bytesRead + If _progressDialog IsNot Nothing Then + Dim progressPercentage As Integer = CInt(totalBytesRead / streamLength * 100) + InvokeIncrement(progressPercentage) + Thread.Sleep(millisecondsTimeout:=1) + End If + End Sub + Using linkedStreamCts As CancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_cancelTokenSourceReadStream.Token, _cancelTokenSourcePost.Token, externalToken) + Try + Dim response As HttpResponseMessage + Using multipartContent As New MultipartFormDataContent("----boundary") + Dim fileStream As New FileStream(filePath, FileMode.Open, FileAccess.Read) + Dim fileContent As New StreamContent(fileStream) + fileContent.Headers.ContentType = New MediaTypeHeaderValue("application/octet-stream") + Dim fileName As String = Path.GetFileName(filePath) + multipartContent.Add(fileContent, "file", $"""{fileName}""") + If _progressDialog Is Nothing Then + response = + Await _httpClient.PostAsync(requestURI, multipartContent, cancellationToken:=linkedStreamCts.Token) _ + .ConfigureAwait(continueOnCapturedContext:=False) + Else + Dim progressContent As New ProgressableStreamContent(multipartContent, progress, BufferSize) + response = + Await _httpClient.PostAsync(requestURI, progressContent, cancellationToken:=linkedStreamCts.Token) _ + .ConfigureAwait(continueOnCapturedContext:=False) + End If + response.EnsureSuccessStatusCode() + Select Case response.StatusCode + Case HttpStatusCode.OK + Case HttpStatusCode.Found, + HttpStatusCode.Moved, + HttpStatusCode.NotModified, + HttpStatusCode.PermanentRedirect + Throw New WebException() + Case HttpStatusCode.Forbidden, + HttpStatusCode.NetworkAuthenticationRequired, + HttpStatusCode.Unauthorized + Throw New WebException(SR.net_webstatus_Unauthorized) + Case HttpStatusCode.RequestTimeout + Throw New WebException(SR.net_webstatus_Timeout) + Case Else + Throw New WebException() + End Select + response?.Dispose() + Await fileStream.DisposeAsync().ConfigureAwait(False) + End Using + Catch ex As HttpRequestException + Throw + Catch ex As TaskCanceledException + If ex.CancellationToken = externalToken Then + externalToken.ThrowIfCancellationRequested() + ElseIf linkedStreamCts.IsCancellationRequested Then + ' a real cancellation, triggered by the caller + Throw + Else + Throw New WebException(SR.net_webstatus_Timeout, WebExceptionStatus.Timeout) + End If + Finally + CloseProgressDialog(_progressDialog) + End Try + End Using + If _progressDialog IsNot Nothing Then + RemoveHandler _progressDialog.UserHitCancel, AddressOf _progressDialog_UserHitCancel + End If + End Function + End Class +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/ProgressableStreamContent.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/ProgressableStreamContent.vb new file mode 100644 index 00000000000..2edd4cd8332 --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/ProgressableStreamContent.vb @@ -0,0 +1,57 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.IO +Imports System.Net +Imports System.Net.Http + +Namespace Microsoft.VisualBasic.MyServices.Internal + + Friend Class ProgressableStreamContent + Inherits HttpContent + + Private ReadOnly _bufferSize As Integer + Private ReadOnly _content As HttpContent + Private ReadOnly _progress As Action(Of Long, Long) + Public Sub New(content As HttpContent, progress As Action(Of Long, Long), Optional bufferSize As Integer = 4096) + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(bufferSize) + ArgumentNullException.ThrowIfNull(content) + _content = content + _progress = progress + _bufferSize = bufferSize + For Each header As KeyValuePair(Of String, IEnumerable(Of String)) In content.Headers + Headers.TryAddWithoutValidation(header.Key, header.Value) + Next + End Sub + + Protected Overrides Sub Dispose(disposing As Boolean) + If disposing Then _content.Dispose() + MyBase.Dispose(disposing) + End Sub + + Protected Overrides Async Function SerializeToStreamAsync(stream As Stream, context As TransportContext) As Task + Dim buffer(_bufferSize - 1) As Byte + Dim size As Long + Dim uploaded As Long = 0 + TryComputeLength(size) + + Using sinput As Stream = Await _content.ReadAsStreamAsync().ConfigureAwait(False) + While True + Dim bytesRead As Long = Await sinput.ReadAsync(buffer).ConfigureAwait(False) + If bytesRead <= 0 Then Exit While + uploaded += bytesRead + _progress?.Invoke(uploaded, size) + Await stream.WriteAsync(buffer.AsMemory(0, CInt(bytesRead))).ConfigureAwait(False) + Await Stream.FlushAsync().ConfigureAwait(False) + End While + End Using + Await Stream.FlushAsync().ConfigureAwait(False) + End Function + + Protected Overrides Function TryComputeLength(ByRef length As Long) As Boolean + length = _content.Headers.ContentLength.GetValueOrDefault() + Return True + End Function + + End Class +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/WebClientCopy.vb b/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/WebClientCopy.vb deleted file mode 100644 index 5ebced7ff68..00000000000 --- a/src/Microsoft.VisualBasic.Forms/src/Microsoft/VisualBasic/MyServices/Internal/WebClientCopy.vb +++ /dev/null @@ -1,211 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. - -Imports System.Net -Imports Microsoft.VisualBasic.Devices - -Namespace Microsoft.VisualBasic.MyServices.Internal - - ''' - ''' Class that controls the thread that does the actual work of downloading or uploading. - ''' - Friend NotInheritable Class WebClientCopy - - ' Dialog shown if user wants to see progress UI. Allows the user to cancel the file transfer. - Private WithEvents _progressDialog As ProgressDialog - - ' The WebClient performs the downloading or uploading operations for us - Private WithEvents _webClient As WebClient - - ' Keeps track of the error that happened during upload/download so we can throw it - ' once we can guarantee we are back on the main thread - Private _exceptionEncounteredDuringFileTransfer As Exception - - ' The percentage of the operation completed - Private _percentage As Integer - - ' Used for invoking ProgressDialog.Increment - Private Delegate Sub DoIncrement(Increment As Integer) - - ''' - ''' Creates an instance of a WebClientCopy, used to download or upload a file. - ''' - ''' The used to do the downloading or uploading. - ''' UI for indicating progress. - Public Sub New(client As WebClient, dialog As ProgressDialog) - Debug.Assert(client IsNot Nothing, $"No {client}") - - _webClient = client - _progressDialog = dialog - End Sub - - ''' - ''' If the user clicks cancel on the Progress dialog, we need to cancel - ''' the current async file transfer operation. - ''' - ''' - ''' Note: that we don't want to close the progress dialog here. Wait until - ''' the actual file transfer cancel event comes through and do it there. - ''' - Private Sub _progressDialog_UserHitCancel() Handles _progressDialog.UserHitCancel - ' Cancel the upload/download transfer. We'll close the ProgressDialog - ' as soon as the WebClient cancels the xfer. - _webClient.CancelAsync() - End Sub - - ''' - ''' Handles the WebClient's DownloadFileCompleted event. - ''' - ''' - ''' - Private Sub _webClient_DownloadFileCompleted(sender As Object, e As ComponentModel.AsyncCompletedEventArgs) _ - Handles _webClient.DownloadFileCompleted - - Try - ' If the download was interrupted by an exception, keep track of the exception, - ' which we'll throw from the main thread - If e.Error IsNot Nothing Then - _exceptionEncounteredDuringFileTransfer = e.Error - End If - - If Not e.Cancelled AndAlso e.Error Is Nothing Then - InvokeIncrement(100) - End If - Finally - 'We don't close the dialog until we receive the WebClient.DownloadFileCompleted event - CloseProgressDialog(_progressDialog) - End Try - End Sub - - ''' - ''' Handles event WebClient fires whenever progress of download changes. - ''' - ''' - ''' - Private Sub _webClient_DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs) _ - Handles _webClient.DownloadProgressChanged - - InvokeIncrement(e.ProgressPercentage) - End Sub - - ''' - ''' Handles the WebClient's UploadFileCompleted event. - ''' - ''' - ''' - Private Sub _webClient_UploadFileCompleted(sender As Object, e As UploadFileCompletedEventArgs) _ - Handles _webClient.UploadFileCompleted - - ' If the upload was interrupted by an exception, keep track of the exception, - ' which we'll throw from the main thread - Try - If e.Error IsNot Nothing Then - _exceptionEncounteredDuringFileTransfer = e.Error - End If - If Not e.Cancelled AndAlso e.Error Is Nothing Then - InvokeIncrement(100) - End If - Finally - ' We don't close the dialog until we receive the - ' WebClient.DownloadFileCompleted event - CloseProgressDialog(_progressDialog) - End Try - End Sub - - ''' - ''' Handles event WebClient fires whenever progress of upload changes. - ''' - ''' - ''' - Private Sub _webClient_UploadProgressChanged(sender As Object, e As UploadProgressChangedEventArgs) _ - Handles _webClient.UploadProgressChanged - - Dim increment As Long = (e.BytesSent * 100) \ e.TotalBytesToSend - InvokeIncrement(CInt(increment)) - End Sub - - ''' - ''' Notifies the progress dialog to increment the progress bar. - ''' - ''' The percentage of bytes read. - Private Sub InvokeIncrement(progressPercentage As Integer) - ' Don't invoke unless dialog is up and running - If _progressDialog IsNot Nothing Then - If _progressDialog.IsHandleCreated Then - - ' For performance, don't invoke if increment is 0 - Dim increment As Integer = progressPercentage - _percentage - _percentage = progressPercentage - If increment > 0 Then - _progressDialog.BeginInvoke( - New DoIncrement(AddressOf _progressDialog.Increment), - increment) - End If - - End If - End If - End Sub - - ''' - ''' Downloads a file. - ''' - ''' The source for the file. - ''' The path and name where the file is saved. - Public Sub DownloadFile(address As Uri, destinationFileName As String) - Debug.Assert(_webClient IsNot Nothing, $"No {NameOf(_webClient)}") - Debug.Assert(address IsNot Nothing, $"No {NameOf(address)}") - Dim path As String = IO.Path.GetDirectoryName(IO.Path.GetFullPath(destinationFileName)) - Debug.Assert((Not String.IsNullOrWhiteSpace(destinationFileName)) _ - AndAlso IO.Directory.Exists(path), $"Invalid {NameOf(path)}") - - ' If we have a dialog we need to set up an async download - If _progressDialog IsNot Nothing Then - _webClient.DownloadFileAsync(address, destinationFileName) - 'returns when the download sequence is over, whether due to success, error, or being canceled - _progressDialog.ShowProgressDialog() - Else - _webClient.DownloadFile(address, destinationFileName) - End If - - 'Now that we are back on the main thread, throw the exception we encountered if the user didn't cancel. - If _exceptionEncounteredDuringFileTransfer IsNot Nothing Then - If _progressDialog Is Nothing OrElse Not _progressDialog.UserCanceledTheDialog Then - Throw _exceptionEncounteredDuringFileTransfer - End If - End If - - End Sub - - ''' - ''' Uploads a file. - ''' - ''' The name and path of the source file. - ''' The address to which the file is uploaded. - Public Sub UploadFile(sourceFileName As String, address As Uri) - Debug.Assert(_webClient IsNot Nothing, $"No {NameOf(_webClient)}") - Debug.Assert(address IsNot Nothing, $"No {NameOf(address)}") - Debug.Assert((Not String.IsNullOrWhiteSpace(sourceFileName)) _ - AndAlso IO.File.Exists(sourceFileName), "Invalid file") - - ' If we have a dialog we need to set up an async download - If _progressDialog IsNot Nothing Then - _webClient.UploadFileAsync(address, sourceFileName) - - ' Returns when the download sequence is over, - ' whether due to success, error, or being canceled - _progressDialog.ShowProgressDialog() - Else - _webClient.UploadFile(address, sourceFileName) - End If - - ' Now that we are back on the main thread, throw the exception we - ' encountered if the user didn't cancel. - If _exceptionEncounteredDuringFileTransfer IsNot Nothing Then - If _progressDialog Is Nothing OrElse Not _progressDialog.UserCanceledTheDialog Then - Throw _exceptionEncounteredDuringFileTransfer - End If - End If - End Sub - - End Class -End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/SR.resx b/src/Microsoft.VisualBasic.Forms/src/Resources/SR.resx index ff406c3aee6..a213f29af4f 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/SR.resx +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/SR.resx @@ -1,16 +1,17 @@ - - @@ -221,4 +222,13 @@ Environment variable is not defined: '{0}'. + + The remote server returned an error: (404) Not Found. + + + The operation has timed out. + + + The remote server returned an error: (401) Unauthorized. + diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.cs.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.cs.xlf index f737611c412..a8e991392b5 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.cs.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.cs.xlf @@ -177,6 +177,21 @@ Ukládání {0} + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.de.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.de.xlf index e4e2a7e5e3e..1f69d697049 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.de.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.de.xlf @@ -177,6 +177,21 @@ {0} wird hochgeladen + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.es.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.es.xlf index 006fe62ea7d..593cc3c4fe8 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.es.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.es.xlf @@ -177,6 +177,21 @@ Cargando {0} + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.fr.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.fr.xlf index 3e06f665f6a..28adb2042d7 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.fr.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.fr.xlf @@ -177,6 +177,21 @@ Chargement de {0} + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.it.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.it.xlf index cc73272c979..ff076a8ec82 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.it.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.it.xlf @@ -177,6 +177,21 @@ Caricamento di {0} + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ja.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ja.xlf index d9c1b872741..068bcfde92a 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ja.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ja.xlf @@ -177,6 +177,21 @@ {0} のアップロード中 + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ko.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ko.xlf index 5546130053f..38992a7020a 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ko.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ko.xlf @@ -177,6 +177,21 @@ {0} 업로드 중 + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pl.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pl.xlf index 35284bb512e..fa27aa35ef4 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pl.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pl.xlf @@ -177,6 +177,21 @@ Przekazywanie: {0} + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pt-BR.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pt-BR.xlf index 1e1b8f1416f..deffcc04396 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pt-BR.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.pt-BR.xlf @@ -177,6 +177,21 @@ Carregando {0} + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ru.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ru.xlf index e400e684656..f06353c3d18 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ru.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.ru.xlf @@ -177,6 +177,21 @@ Идет отправка {0} + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.tr.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.tr.xlf index 751c15e6832..d8b7045e74a 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.tr.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.tr.xlf @@ -177,6 +177,21 @@ {0} karşıya yükleniyor + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hans.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hans.xlf index af55164f9e7..ff6d043271e 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hans.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hans.xlf @@ -177,6 +177,21 @@ 正在上传 {0} + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hant.xlf b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hant.xlf index c3df5ab1fb7..0d405fb9a8c 100644 --- a/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hant.xlf +++ b/src/Microsoft.VisualBasic.Forms/src/Resources/xlf/SR.zh-Hant.xlf @@ -177,6 +177,21 @@ 正在上傳 {0} + + The remote server returned an error: (404) Not Found. + The remote server returned an error: (404) Not Found. + + + + The operation has timed out. + The operation has timed out. + + + + The remote server returned an error: (401) Unauthorized. + The remote server returned an error: (401) Unauthorized. + + \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/Microsoft.VisualBasic.Forms.Tests.vbproj b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/Microsoft.VisualBasic.Forms.Tests.vbproj index 6828820a702..1f4a62982ed 100644 --- a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/Microsoft.VisualBasic.Forms.Tests.vbproj +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/Microsoft.VisualBasic.Forms.Tests.vbproj @@ -16,6 +16,19 @@ + + + + + + + PreserveNewest + + + PreserveNewest + + + diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/DownloadFileAsyncTests.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/DownloadFileAsyncTests.vb new file mode 100644 index 00000000000..088a8ce39f4 --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/DownloadFileAsyncTests.vb @@ -0,0 +1,122 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.Net +Imports System.Net.Http +Imports System.Threading +Imports FluentAssertions +Imports Microsoft.VisualBasic.FileIO +Imports Xunit + +Namespace Microsoft.VisualBasic.Forms.Tests + + Public Class DownloadFileAsyncTests + Inherits VbFileCleanupTestBase + + + Public Sub DownloadFileAsync_AllOptions_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + Dim t As Task = Devices.Network.DownloadFileAsync( + addressUri:=New Uri(uriString:=webListener.Address), + destinationFileName, + clientHandler:=New HttpClientHandler, + dialog:=Nothing, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing, + cancelToken:=CancellationToken.None) + If t.IsFaulted Then + Throw t.Exception + End If + t.Wait() + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(FileSizes.FileSize1MB) + End Using + End Sub + + + Public Sub DownloadFileAsync_AllOptionsClientHandlerNothing_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + Dim t As Task = Devices.Network.DownloadFileAsync( + addressUri:=Nothing, + destinationFileName, + clientHandler:=Nothing, + dialog:=Nothing, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing, + cancelToken:=CancellationToken.None) + If t.IsFaulted Then + Throw t.Exception + End If + End Sub + + testCode.Should.Throw(Of ArgumentNullException)().WithParameterName("addressUri") + End Using + End Sub + + + Public Sub DownloadFileAsync_AllOptionsInvalidTimeout_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + Dim t As Task = Devices.Network.DownloadFileAsync( + addressUri:=New Uri(uriString:=webListener.Address), + destinationFileName, + clientHandler:=Nothing, + dialog:=Nothing, + connectionTimeout:=-1, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing, + cancelToken:=CancellationToken.None) + If t.IsFaulted Then + Throw t.Exception + End If + End Sub + + testCode.Should.Throw(Of ArgumentException)().WithParameterName("connectionTimeout") + End Using + End Sub + + + Public Sub DownloadFileAsync_UriWithAllOptions_ExceptOnUserCancelWhereUsernameIsNothing_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + Devices.Network.DownloadFileAsync( + addressUri:=New Uri(uriString:=webListener.Address), + destinationFileName, + userName:=Nothing, + password:=String.Empty, + dialog:=Nothing, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False, + cancelToken:=CancellationToken.None).Wait() + End Sub + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(FileSizes.FileSize1MB) + End Using + End Sub + + End Class +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/DownloadFileTests.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/DownloadFileTests.vb new file mode 100644 index 00000000000..fc27bc9d98a --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/DownloadFileTests.vb @@ -0,0 +1,1722 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.IO +Imports System.Net +Imports FluentAssertions +Imports Microsoft.VisualBasic.Devices +Imports Microsoft.VisualBasic.FileIO +Imports Xunit + +Namespace Microsoft.VisualBasic.Forms.Tests + + Public Class DownloadFileTests + Inherits VbFileCleanupTestBase + + + + + Public Sub DownloadFile_UnauthorizedUriWithAllOptionsExceptOnUserCancel_Throws(password As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + If webListener.ServerThrowsPasswordErrors Then + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + GetNetworkCredentials(webListener.ServerUserName, password), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End If + End Sub + + + + + Public Sub DownloadFile_UnauthorizedUriWithUserNamePassword_Throw(password As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=String.Empty) + If webListener.ServerThrowsPasswordErrors Then + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=webListener.ServerUserName, + password) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End If + End Sub + + + + + Public Sub DownloadFile_UnauthorizedUriWithUserNamePassword_Throws(password As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + If webListener.ServerThrowsPasswordErrors Then + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=webListener.ServerUserName, + password) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End If + End Sub + + + + + Public Sub DownloadFile_UnauthorizedUrlWithUserNamePassword_Throw(password As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=String.Empty) + If webListener.ServerThrowsPasswordErrors Then + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName, + userName:=webListener.ServerUserName, + password) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End If + End Sub + + + + + Public Sub DownloadFile_UnauthorizedUrlWithUserNamePassword_Throws(password As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + If webListener.ServerThrowsPasswordErrors Then + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=webListener.ServerUserName, + password) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End If + End Sub + + + Public Sub DownloadFile_UriOnly_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UriOnlyWhereAddressIsEmptyString_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(String.Empty), + destinationFileName) + End Sub + + testCode.Should.Throw(Of UriFormatException)() + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriOnlyWhereAddressIsNothing_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(Nothing), + destinationFileName) + End Sub + + testCode.Should.Throw(Of ArgumentNullException)() + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + + Public Sub DownloadFile_UriOnlyWhereDestinationFileNameInvalid_Throws(destinationFileName As String) + Dim testDirectory As String = CreateTempDirectory() + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionExceptOnUserCancelWhereShowUiFalseInvalidUrl_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(InvalidUrlAddress), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False) + End Sub + + testCode.Should.Throw(Of UriFormatException)() + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsAndNetworkCredentials_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.ThrowException) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsAndNetworkCredentialsWhereAddressNothing_Throw() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=Nothing, + destinationFileName, + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.ThrowException) + End Sub + + testCode.Should.Throw(Of ArgumentNullException)() + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsAndNetworkCredentialsWhereTimeout0_Throw() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=0, + overwrite:=True, + onUserCancel:=UICancelOption.ThrowException) + End Sub + + testCode.Should.Throw(Of ArgumentException)() + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsExceptOnUserCancel_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + + Public Sub DownloadFile_UriWithAllOptionsExceptOnUserCancelWhereAddressInvalid_Throw(address As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(address), + destinationFileName, + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True) + End Sub + If address Is Nothing Then + testCode.Should().Throw(Of ArgumentNullException)() + Else + testCode.Should().Throw(Of UriFormatException)() + End If + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + + Public Sub DownloadFile_UriWithAllOptionsExceptOnUserCancelWhereDestinationFileNameInvalid_Throws( + destinationFileName As String) + + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName:=Nothing, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + VerifyFailedDownload(testDirectory:=Nothing, destinationFileName, listener) + End Using + End Sub + + + + Public Sub DownloadFile_UriWithAllOptionsExceptOnUserCancelWhereOverwritePassed(overwrite As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1Byte) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite) + End Sub + If overwrite Then + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + Else + Dim value As String = SR.IO_FileExists_Path.Replace("{0}", destinationFileName) + testCode.Should() _ + .Throw(Of IOException)() _ + .Where(Function(e) e.Message.Equals(value)) + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should.Be(1) + End If + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsExceptOnUserCancelWhereOverwriteTrueAndDestinationFileExists_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1Byte) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsExceptOnUserCancelWhereShowUiTrue_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsExceptOnUserCancelWhereTimeoutNegative_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize100MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=-1, + overwrite:=False) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(Function(e) e.Message.StartsWith(SR.Network_BadConnectionTimeout)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsExceptOnUserCancelWhereTimeOutShort_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize100MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=1, + overwrite:=True) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Timeout) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsExceptOnUserCancelWhereUriIsNothing_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=CType(Nothing, Uri), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsExceptOnUserCancelWhereUrlInvalid_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(InvalidUrlAddress), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False) + End Sub + + testCode.Should().Throw(Of UriFormatException)() + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsExceptOnUserCancelWhereUsernameIsNothing_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=Nothing, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + + Public Sub DownloadFile_UriWithAllOptionsWhereCheckFilePathTrailingSeparators_Throw(separator As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName:=$"{destinationFileName}{separator}", + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(destinationFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsWhereConnectionTimeoutInvalid_Throw() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=-1, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(Function(e) e.Message.StartsWith(SR.Network_BadConnectionTimeout)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + + Public Sub DownloadFile_UriWithAllOptionsWhereDestinationFileNameInvalid_Throws(destinationFileName As String) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName:=Nothing, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should.Throw(Of ArgumentNullException)() + VerifyFailedDownload(testDirectory:=Nothing, destinationFileName, listener) + End Using + End Sub + + + + + Public Sub DownloadFile_UriWithAllOptionsWhereDestinationIsRootDirectory_Throw(root As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName:=root, ' This is a Root Directory! + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(destinationFileName)) + testCode.Should.Throw(Of ArgumentException)().Where(exceptionExpression) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + + Public Sub DownloadFile_UriWithAllOptionsWhereFilePathTrailingSeparatorsAreInvalid_Throw(separator As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName:=$"{destinationFileName}{separator}", + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(destinationFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsWhereOnUserCancelIsDoNothing_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsWhereOnUserCancelIsDoNothingShowUiTrue_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + + + Public Sub DownloadFile_UriWithAllOptionsWhereRootDirectoryInvalid_Throw(root As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName:=root, ' This is a Root Directory! + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of InvalidOperationException)() _ + .Where(Function(e) e.Message.StartsWith(SR.Network_DownloadNeedsFilename)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + + + Public Sub DownloadFile_UriWithAllOptionsWhereRootDirectoryTrailingSeparatorInvalid_Throw(root As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName:=root, ' This is a Root Directory! + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(destinationFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsWhereTargetDirectoryNonexistent_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Directory.Delete(testDirectory, recursive:=True) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsWhereUriIsNothing_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=CType(Nothing, Uri), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsWithAllOptions_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UriWithAllOptionsWithAllOptionsWithAllOptionsWhereDestinationIsDirectory_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName:=testDirectory, ' This is a Directory! + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of InvalidOperationException)() _ + .WithMessage(SR.Network_DownloadNeedsFilename) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UriWithUserNamePassword_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=webListener.ServerUserName, + password:=webListener.ServerPassword) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UrlOnly_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UrlOnlyFileDoesNotExist_Fail() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize0Bytes) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName) + End Sub + + testCode.Should. + Throw(Of WebException)(). + Where(Function(e) e.Message.Equals(SR.net_webstatus_NotFound)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + + Public Sub DownloadFile_UrlOnlyWhereAddressInvalid_Throws(address As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile(address, destinationFileName) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + + Public Sub DownloadFile_UrlOnlyWhereDestinationFileNameInvalidAddressOnly_Throws(destinationFileName As String) + Dim testDirectory As String = CreateTempDirectory() + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile(address:=webListener.Address, destinationFileName) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsAndNetworkCredentials_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.ThrowException) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsDoNotShowUIExceptOnUserCancelWhereInvalidUrl_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=InvalidUrlAddress, + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False) + End Sub + + Dim value As String = SR.Network_InvalidUriString.Replace("{0}", "invalidURL") + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(Function(e) e.Message.StartsWith(value)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + + Public Sub DownloadFile_UrlWithAllOptionsExceptOnUserCancelWhereDestinationFileNameInvalidOverwrite_Throws( + destinationFileName As String) + + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName:=Nothing, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + VerifyFailedDownload(testDirectory:=Nothing, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsExceptOnUserCancelWhereFileExistsNoOverwrite_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1Byte) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False) + End Sub + + Dim value As String = SR.IO_FileExists_Path.Replace("{0}", destinationFileName) + testCode.Should() _ + .Throw(Of IOException)() _ + .Where(Function(e) e.Message.Equals(value)) + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should.Be(1) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsExceptOnUserCancelWhereInvalidUrlDoNotShowUI_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=InvalidUrlAddress, + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False) + End Sub + + Dim value As String = SR.Network_InvalidUriString.Replace("{0}", "invalidURL") + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(Function(e) e.Message.StartsWith(value)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsExceptOnUserCancelWhereOverwriteTrue_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1Byte) + Dim webListener As New WebListener(FileSizes.FileSize100MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsExceptOnUserCancelWhereOverwriteTrue_Throw() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1GB) + Dim webListener As New WebListener(FileSizes.FileSize1GB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True) + End Sub + + testCode.Should() _ + .Throw(Of Exception)() _ + .Where(Function(ex) TypeOf ex Is OperationCanceledException OrElse TypeOf ex Is WebException) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsExceptOnUserCancelWhereOverwriteWhereDestinationFileExists_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1Byte) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsExceptOnUserCancelWhereTimeOut_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize100MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=1, + overwrite:=True) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Timeout) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsExceptOnUserCancelWhereTimeoutNegative_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize100MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=-1, + overwrite:=False) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(Function(e) e.Message.StartsWith(SR.Network_BadConnectionTimeout)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsExceptOnUserCancelWhereUrlInvalid_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=InvalidUrlAddress, + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False) + End Sub + + Dim value As String = SR.Network_InvalidUriString.Replace("{0}", "invalidURL") + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(Function(e) e.Message.StartsWith(value)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsExceptOnUserCancelWhereUsernameIsNothing_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName, + userName:=Nothing, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + + Public Sub DownloadFile_UrlWithAllOptionsWhereAddressIsNothingOrEmpty_Throws(address As String) + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address, + destinationFileName:=Nothing, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + End Sub + + + + Public Sub DownloadFile_UrlWithAllOptionsWhereDestinationFileNameInvalid_Throws(destinationFileName As String) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName:=Nothing, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + VerifyFailedDownload(testDirectory:=Nothing, destinationFileName, listener) + End Using + End Sub + + + + + Public Sub DownloadFile_UrlWithAllOptionsWhereDestinationIsRootDirectory_Throw(root As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName:=root, ' This is a Root Directory! + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(destinationFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + + Public Sub DownloadFile_UrlWithAllOptionsWhereFilePathTrailingSeparatorsAreInvalid_Throw(separator As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName:=$"{destinationFileName}{separator}", + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(destinationFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsWhereOnUserCancelIsDoNothing_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + + + Public Sub DownloadFile_UrlWithAllOptionsWhereRootDirectoryInvalid_Throw(root As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName:=root, ' This is a Root Directory! + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of InvalidOperationException)() _ + .Where(Function(e) e.Message.StartsWith(SR.Network_DownloadNeedsFilename)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + + + Public Sub DownloadFile_UrlWithAllOptionsWhereRootDirectoryTrailingSeparatorInvalid_Throw(root As String) + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName:=root, ' This is a Root Directory! + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(destinationFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsWhereTargetDirectoryNonexistent_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Directory.Delete(testDirectory, recursive:=True) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=New Uri(webListener.Address), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsWhereUriIsNothing_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=CType(Nothing, Uri), + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=False, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsWithAllOptionsWhereShowUiFalse_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsWithAllOptionsWhereShowUiTrue_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithAllOptionsWithAllOptionsWithAllOptionsWhereDestinationIsDirectory_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName:=testDirectory, ' This is a Directory! + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + overwrite:=True, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of InvalidOperationException)() _ + .WithMessage(SR.Network_DownloadNeedsFilename) + VerifyFailedDownload(testDirectory, destinationFileName, listener) + End Using + End Sub + + + Public Sub DownloadFile_UrlWithUserNamePassword_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim destinationFileName As String = GetUniqueFileNameWithPath(testDirectory) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.DownloadFile( + address:=webListener.Address, + destinationFileName, + userName:=webListener.ServerUserName, + password:=webListener.ServerPassword) + End Sub + + testCode.Should.NotThrow() + VerifySuccessfulDownload(testDirectory, destinationFileName, listener).Should() _ + .Be(webListener.FileSize) + End Using + End Sub + + End Class +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/FileSystemProxyTests.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/FileSystemProxyTests.vb index 523cf1fb5bd..7bd5b3d67ad 100644 --- a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/FileSystemProxyTests.vb +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/FileSystemProxyTests.vb @@ -96,7 +96,7 @@ Namespace Microsoft.VisualBasic.Forms.Tests Public Sub DeleteDirectoryRecycleWithUICancelOptionsProxyTest() Dim sourceDirectoryName As String = CreateTempDirectory() - Dim sourceFileName As String = CreateTempFile(sourceDirectoryName, NameOf(sourceFileName), size:=1) + Dim sourceFileName As String = CreateTempFile(sourceDirectoryName, NameOf(sourceFileName), size:=FileSizes.FileSize1Byte) Dim data As Byte() = {4} _fileSystem.WriteAllBytes(sourceFileName, data, append:=False) File.Exists(sourceFileName).Should.BeTrue() @@ -112,7 +112,7 @@ Namespace Microsoft.VisualBasic.Forms.Tests Public Sub DeleteDirectoryWithUIProxyRecycleTest() Dim sourceDirectoryName As String = CreateTempDirectory() - Dim sourceFileName As String = CreateTempFile(sourceDirectoryName, NameOf(sourceFileName), size:=1) + Dim sourceFileName As String = CreateTempFile(sourceDirectoryName, NameOf(sourceFileName), size:=FileSizes.FileSize1Byte) Dim data As Byte() = {4} _fileSystem.WriteAllBytes(sourceFileName, data, append:=False) File.Exists(sourceFileName).Should.BeTrue() @@ -127,7 +127,7 @@ Namespace Microsoft.VisualBasic.Forms.Tests Public Sub DeleteFileWithRecycleOptionProxyTest() Dim sourceDirectoryName As String = CreateTempDirectory() - Dim sourceFileName As String = CreateTempFile(sourceDirectoryName, NameOf(sourceFileName), size:=1) + Dim sourceFileName As String = CreateTempFile(sourceDirectoryName, NameOf(sourceFileName), size:=FileSizes.FileSize1Byte) Dim byteArray As Byte() = {4} _fileSystem.WriteAllBytes(sourceFileName, byteArray, append:=False) File.Exists(sourceFileName).Should.BeTrue() @@ -146,7 +146,7 @@ Namespace Microsoft.VisualBasic.Forms.Tests Public Sub DeleteFileWithUIProxyTest() Dim sourceDirectoryName As String = CreateTempDirectory() - Dim sourceFileName As String = CreateTempFile(sourceDirectoryName, NameOf(sourceFileName), size:=1) + Dim sourceFileName As String = CreateTempFile(sourceDirectoryName, NameOf(sourceFileName), size:=FileSizes.FileSize1Byte) Dim data As Byte() = {4} _fileSystem.WriteAllBytes(sourceFileName, data, append:=False) File.Exists(sourceFileName).Should.BeTrue() @@ -187,7 +187,7 @@ Namespace Microsoft.VisualBasic.Forms.Tests Dim sourceDirectoryName As String = CreateTempDirectory() Dim fileA As String = CreateTempFile(sourceDirectoryName, NameOf(fileA)) _fileSystem.WriteAllText(fileA, "A", append:=False) - Dim fileB As String = CreateTempFile(sourceDirectoryName, NameOf(fileB), size:=1) + Dim fileB As String = CreateTempFile(sourceDirectoryName, NameOf(fileB), size:=FileSizes.FileSize1Byte) Dim fileC As String = CreateTempFile(sourceDirectoryName, NameOf(fileC)) _fileSystem.WriteAllText(fileC, "C", append:=False) Dim filenames As ReadOnlyCollection(Of String) = _fileSystem.FindInFiles( diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/InteractionTests.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/InteractionTests.vb index de95203d6cc..a6a59d61d42 100644 --- a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/InteractionTests.vb +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/InteractionTests.vb @@ -2,7 +2,6 @@ ' The .NET Foundation licenses this file to you under the MIT license. Option Strict Off - Imports System.Windows.Forms Imports FluentAssertions Imports Xunit diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/ServerConfigurationTests.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/ServerConfigurationTests.vb new file mode 100644 index 00000000000..76bb0361468 --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/ServerConfigurationTests.vb @@ -0,0 +1,40 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.IO +Imports FluentAssertions +Imports Xunit + +Namespace Microsoft.VisualBasic.Forms.Tests + + Public Class ServerConfigurationTests + + Private Shared Sub Verify(uploading As Boolean, defaultConfiguration As ServerConfiguration, testConfiguration As ServerConfiguration) + defaultConfiguration.GetAcceptsAnonymousLogin(uploading).Should.Be(testConfiguration.GetAcceptsAnonymousLogin(uploading)) + defaultConfiguration.GetDefaultPassword(uploading).Should.Be(testConfiguration.GetDefaultPassword(uploading)) + defaultConfiguration.GetDefaultUserName(uploading).Should.Be(testConfiguration.GetDefaultUserName(uploading)) + defaultConfiguration.GetFileUrlPrefix(uploading).Should.Be(testConfiguration.GetFileUrlPrefix(uploading)) + defaultConfiguration.GetThrowsPasswordErrors(uploading).Should.Be(testConfiguration.GetThrowsPasswordErrors(uploading)) + End Sub + + + + Public Sub VerifyNew_Success(uploading As Boolean) + Dim defaultConfiguration As New ServerConfiguration + Dim testConfiguration As ServerConfiguration = ServerConfiguration.ServerConfigurationLoad + Verify(uploading, defaultConfiguration, testConfiguration) + End Sub + + + + Public Sub VerifySerialization_Success(uploading As Boolean) + Dim defaultConfiguration As New ServerConfiguration + Dim jsonFilePathBase As String = Path.GetTempPath + Dim jsonFullPath As String = defaultConfiguration.ServerConfigurationSave(jsonFilePathBase) + Dim testConfiguration As ServerConfiguration = ServerConfiguration.ServerConfigurationLoad(jsonFilePathBase) + Verify(uploading, defaultConfiguration, testConfiguration) + File.Delete(jsonFullPath) + End Sub + + End Class +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/UploadFileTests.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/UploadFileTests.vb new file mode 100644 index 00000000000..2eb0c22020f --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/Forms/UploadFileTests.vb @@ -0,0 +1,1472 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.IO +Imports System.Net +Imports FluentAssertions +Imports Microsoft.VisualBasic.Devices +Imports Microsoft.VisualBasic.FileIO +Imports Xunit + +Namespace Microsoft.VisualBasic.Forms.Tests + + Public Class UploadFileTests + Inherits VbFileCleanupTestBase + + + + + Public Sub UploadFile_UnauthorizedUriWithAllOptions_ExceptOnUserCancelWherePasswordWrong_Throws(password As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + If webListener.ServerThrowsPasswordErrors Then + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + New NetworkCredential(webListener.ServerUserName, password), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + webListener.FaultMessage.Should.BeNull() + End Using + End If + End Sub + + + + + Public Sub UploadFile_UnauthorizedUriWithUserNamePasswordWherePasswordWrong_Throws(password As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + If webListener.ServerThrowsPasswordErrors Then + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=webListener.ServerUserName, + password) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + webListener.FaultMessage.Should.BeNull() + End Using + End If + End Sub + + + + + Public Sub UploadFile_UnauthorizedUrlWithUserNamePasswordWherePasswordWrong_Throw(password As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=String.Empty) + If webListener.ServerThrowsPasswordErrors Then + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=webListener.Address, + userName:=webListener.ServerUserName, + password) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + webListener.FaultMessage.Should.BeNull() + End Using + End If + + End Sub + + + + + Public Sub UploadFile_UnauthorizedUrlWithUserNamePasswordWherePasswordWrong_Throws(password As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + If webListener.ServerThrowsPasswordErrors Then + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=webListener.ServerUserName, + password) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + webListener.FaultMessage.Should.BeNull() + End Using + End If + End Sub + + + + Public Sub UploadFile_UriOnly_Success(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address)) + End Sub + + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + Public Sub UploadFile_UriOnlyWhereAddressIsEmptyString_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(String.Empty)) + End Sub + + testCode.Should.Throw(Of UriFormatException)() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UriOnlyWhereAddressIsNothing_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(Nothing)) + End Sub + + testCode.Should.Throw(Of ArgumentNullException)() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UriOnlyWhereSourceFileNameInvalidAddressOnly_Throws(sourceFileName As String) + Dim testDirectory As String = CreateTempDirectory() + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address)) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UriOnlyWrongFileSize_Throw(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1Byte) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address)) + End Sub + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.StartWith("File size mismatch") + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + + End Using + End Sub + + + Public Sub UploadFile_UriWithAllOptions_ExceptOnUserCancel_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UriWithAllOptions_ExceptOnUserCancelWhereSourceFileNameInvalid_Throws( + sourceFileName As String) + + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=Nothing, + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UriWithAllOptions_ExceptOnUserCancelWhereTimeOut_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize100MB) + Dim webListener As New WebListener(fileSize:=FileSizes.FileSize100MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=1) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Timeout) + End Using + End Sub + + + Public Sub UploadFile_UriWithAllOptions_ExceptOnUserCancelWhereTimeoutNegative_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize100MB) + Dim webListener As New WebListener(FileSizes.FileSize100MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=-1) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(Function(e) e.Message.StartsWith(SR.Network_BadConnectionTimeout)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UriWithAllOptions_ExceptOnUserCancelWhereTrue_Success(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionLargeTimeout) + End Sub + + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + Public Sub UploadFile_UriWithAllOptions_ExceptOnUserCancelWhereUriIsNothing_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=CType(Nothing, Uri), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UriWithAllOptions_ExceptOnUserCancelWhereUrlInvalid_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(InvalidUrlAddress), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + testCode.Should().Throw(Of UriFormatException)() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UriWithAllOptions_ExceptOnUserCancelWhereUsernameIsNothing_Success(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=Nothing, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + + Public Sub UploadFile_UriWithAllOptions_ExceptOnUserCancelWhereWhereDestinationFileExists_Success(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + Public Sub UploadFile_UriWithAllOptionsAndNetworkCredentials_Fail() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=Nothing, + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.ThrowException) + End Sub + + testCode.Should.Throw(Of ArgumentNullException)() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UriWithAllOptionsAndNetworkCredentials_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.ThrowException) + End Sub + + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UriWithAllOptionsAndNetworkCredentialsTimeout0_Fail() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=0, + onUserCancel:=UICancelOption.ThrowException) + End Sub + + testCode.Should.Throw(Of ArgumentException)() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UriWithAllOptionsDoNotShowUI_ExceptOnUserCancelWhereInvalidUrl_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(InvalidUrlAddress), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + testCode.Should.Throw(Of UriFormatException)() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UriWithAllOptionsExceptOnUserCancelWhereSourceFileNameInvalidThrows( + sourceFileName As String) + + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=Nothing, + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UriWithAllOptionsWhereCheckFilePathTrailingSeparators_Throw(separator As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=$"{sourceFileName}{separator}", + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(sourceFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + + Public Sub UploadFile_UriWithAllOptionsWhereDestinationIsRootDirectory_Throw(root As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=root, ' This is a Root Directory! + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(sourceFileName)) + testCode.Should.Throw(Of ArgumentException)().Where(exceptionExpression) + End Using + End Sub + + + + Public Sub UploadFile_UriWithAllOptionsWhereFilePathTrailingSeparatorsAreInvalid_Throw(separator As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=$"{sourceFileName}{separator}", + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(sourceFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UriWithAllOptionsWhereOnUserCancelIsDoNothing_Success(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + + + Public Sub UploadFile_UriWithAllOptionsWhereRootDirectoryInvalid_Throw(root As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=root, ' This is a Root Directory! + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should().Throw(Of FileNotFoundException)() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + + Public Sub UploadFile_UriWithAllOptionsWhereRootDirectoryTrailingSeparatorInvalid_Throw(root As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=root, ' This is a Root Directory! + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(sourceFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UriWithAllOptionsWhereSourceFileNameInvalid_Throws(sourceFileName As String) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=Nothing, + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should.Throw(Of ArgumentNullException)() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UriWithAllOptionsWhereUriIsNothing_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=CType(Nothing, Uri), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UriWithAllOptionsWithAllOptions_Success(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + Public Sub UploadFile_UriWithUserNamePassword_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=webListener.ServerUserName, + password:=webListener.ServerPassword) + End Sub + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + + Public Sub UploadFile_UriWithUserNamePasswordWherePasswordWrong_Throw(password As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=String.Empty) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=webListener.ServerUserName, + password) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UrlOnly_Success(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=webListener.Address) + End Sub + + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + + Public Sub UploadFile_UrlOnlyWhereAddressInvalid_Throws(address As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile(sourceFileName, address) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UrlOnlyWhereSourceFileNameInvalidAddressOnly_Throws(sourceFileName As String) + Dim testDirectory As String = CreateTempDirectory() + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile(sourceFileName, address:=webListener.Address) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UrlWithAllOptions_ExceptOnUserCancelWhereInvalidUrlDoNotShowUI_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=InvalidUrlAddress, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + Dim value As String = SR.Network_InvalidUriString.Replace("{0}", "invalidURL") + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(Function(e) e.Message.StartsWith(value)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UrlWithAllOptions_ExceptOnUserCancelWhereSourceFileNameInvalid_Throws( + sourceFileName As String) + + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=Nothing, + address:=webListener.Address, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UrlWithAllOptions_ExceptOnUserCancelWhereTimeOut_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize100MB) + Dim webListener As New WebListener(FileSizes.FileSize100MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=webListener.Address, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=1) + End Sub + + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Timeout) + End Using + End Sub + + + Public Sub UploadFile_UrlWithAllOptions_ExceptOnUserCancelWhereTimeoutNegative_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize100MB) + Dim webListener As New WebListener(FileSizes.FileSize100MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=-1) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(Function(e) e.Message.StartsWith(SR.Network_BadConnectionTimeout)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UrlWithAllOptions_ExceptOnUserCancelWhereTrue_Fail() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1GB) + Dim webListener As New WebListener(FileSizes.FileSize1GB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=webListener.Address, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + testCode.Should() _ + .Throw(Of Exception)() _ + .Where(Function(ex) TypeOf ex Is OperationCanceledException OrElse TypeOf ex Is WebException) + End Using + End Sub + + + + Public Sub UploadFile_UrlWithAllOptions_ExceptOnUserCancelWhereTrue_Success(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=webListener.Address, + userName:=String.Empty, + password:=String.Empty, + showUI:=True, + connectionTimeout:=TestingConnectionTimeout) + End Sub + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + Public Sub UploadFile_UrlWithAllOptions_ExceptOnUserCancelWhereUrlInvalid_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=InvalidUrlAddress, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + Dim value As String = SR.Network_InvalidUriString.Replace("{0}", "invalidURL") + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(Function(e) e.Message.StartsWith(value)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UrlWithAllOptions_ExceptOnUserCancelWhereUsernameIsNothing_Success(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=webListener.Address, + userName:=Nothing, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + + Public Sub UploadFile_UrlWithAllOptions_ExceptOnUserCancelWhereWhereUploadFailed_Throws(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1Byte) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=webListener.Address, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.StartWith("File size mismatch") + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + Public Sub UploadFile_UrlWithAllOptionsAndNetworkCredentials_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=New Uri(webListener.Address), + GetNetworkCredentials(webListener.ServerUserName, webListener.ServerPassword), + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.ThrowException) + End Sub + + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UrlWithAllOptionsDoNotShowUI_ExceptOnUserCancelWhereInvalidUrl_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=InvalidUrlAddress, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout) + End Sub + + Dim value As String = SR.Network_InvalidUriString.Replace("{0}", "invalidURL") + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(Function(e) e.Message.StartsWith(value)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UrlWithAllOptionsWhereAddressIsNothingOrEmpty_Throws(address As String) + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=Nothing, + address, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + End Sub + + + + + Public Sub UploadFile_UrlWithAllOptionsWhereDestinationIsRootDirectory_Throw(root As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=root, ' This is a Root Directory! + address:=webListener.Address, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(sourceFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UrlWithAllOptionsWhereFilePathTrailingSeparatorsAreInvalid_Throw(separator As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=$"{sourceFileName}{separator}", + address:=webListener.Address, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(sourceFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UrlWithAllOptionsWhereOnUserCancelIsDoNothing_Success(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=webListener.Address, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + + + Public Sub UploadFile_UrlWithAllOptionsWhereRootDirectoryTrailingSeparatorInvalid_Throw(root As String) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=root, ' This is a Root Directory! + address:=New Uri(webListener.Address), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + Dim exceptionExpression As Expressions.Expression(Of Func(Of ArgumentException, Boolean)) = + Function(e) e.Message.StartsWith(SR.IO_FilePathException) _ + AndAlso e.Message.Contains(NameOf(sourceFileName)) + testCode.Should() _ + .Throw(Of ArgumentException)() _ + .Where(exceptionExpression) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UrlWithAllOptionsWhereSourceFileNameInvalid_Throws(sourceFileName As String) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName:=Nothing, + address:=webListener.Address, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + Public Sub UploadFile_UrlWithAllOptionsWhereUriIsNothing_Throws() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=CType(Nothing, Uri), + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + testCode.Should() _ + .Throw(Of ArgumentNullException)() _ + .Where(Function(e) e.Message.StartsWith(SR.General_ArgumentNullException)) + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + + + Public Sub UploadFile_UrlWithAllOptionsWithAllOptions_Success(supportAnonymousLogin As Boolean) + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener(FileSizes.FileSize1MB, supportAnonymousLogin) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=webListener.Address, + userName:=String.Empty, + password:=String.Empty, + showUI:=False, + connectionTimeout:=TestingConnectionTimeout, + onUserCancel:=UICancelOption.DoNothing) + End Sub + + If webListener.ServerAcceptsAnonymousLogin Then + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + Else + testCode.Should() _ + .Throw(Of WebException)() _ + .WithMessage(SR.net_webstatus_Unauthorized) + End If + End Using + End Sub + + + Public Sub UploadFile_UrlWithUserNamePassword_Success() + Dim testDirectory As String = CreateTempDirectory() + Dim sourceFileName As String = CreateTempFile(testDirectory, size:=FileSizes.FileSize1MB) + Dim webListener As New WebListener( + fileSize:=FileSizes.FileSize1MB, + serverUserName:=DefaultUserName, + serverPassword:=DefaultPassword) + Using listener As HttpListener = webListener.ProcessRequests() + Dim testCode As Action = + Sub() + My.Computer.Network.UploadFile( + sourceFileName, + address:=webListener.Address, + userName:=webListener.ServerUserName, + password:=webListener.ServerPassword) + End Sub + + testCode.Should.NotThrow() + webListener.FaultMessage.Should.BeNull() + End Using + End Sub + + End Class +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/DownloadFileTestConstants.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/DownloadFileTestConstants.vb new file mode 100644 index 00000000000..0399b51d3a6 --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/DownloadFileTestConstants.vb @@ -0,0 +1,12 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Namespace Microsoft.VisualBasic.Forms.Tests + Public Module DownloadFileTestConstants + Friend Const DefaultPassword As String = NameOf(DefaultPassword) + Friend Const DefaultUserName As String = NameOf(DefaultUserName) + Friend Const InvalidUrlAddress As String = "invalidURL" + Friend Const TestingConnectionLargeTimeout As Integer = 100_000_000 + Friend Const TestingConnectionTimeout As Integer = 100_000 + End Module +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/DownloadFileVerifiers.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/DownloadFileVerifiers.vb new file mode 100644 index 00000000000..14f7044d9f2 --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/DownloadFileVerifiers.vb @@ -0,0 +1,59 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.IO +Imports System.Net +Imports FluentAssertions + +Namespace Microsoft.VisualBasic.Forms.Tests + + Public Module DownloadFileVerifiers + ''' + ''' Verify that testDirectory exists, that destinationFileName exist and what its length is. + ''' + ''' A Unique directory under the systems Temp directory. + ''' The full path and filename of the new file. + ''' + Friend Sub VerifyFailedDownload( + testDirectory As String, + destinationFileName As String, + listener As HttpListener) + + If Not String.IsNullOrWhiteSpace(testDirectory) Then + Directory.Exists(testDirectory).Should.BeTrue() + End If + If Not String.IsNullOrWhiteSpace(destinationFileName) Then + File.Exists(destinationFileName).Should.BeFalse() + End If + listener.Stop() + listener.Close() + End Sub + + ''' + ''' Verify that testDirectory exists, that destinationFileName exist and what its length is. + ''' + ''' A Unique directory under the systems Temp directory. + ''' + ''' The size in bytes of the destination file, this saves the caller from having to + ''' do another FileInfo call. + ''' + ''' The full path and filename of the new file. + ''' + Friend Function VerifySuccessfulDownload( + testDirectory As String, + destinationFileName As String, + listener As HttpListener) As Long + + Directory.Exists(testDirectory).Should.BeTrue() + Dim fileInfo As New FileInfo(destinationFileName) + fileInfo.Exists.Should.BeTrue() + Directory.Exists(fileInfo.DirectoryName).Should.BeTrue() + ' This directory should not be systems Temp Directory because it must be created + Path.GetTempPath.Should.NotBe(fileInfo.DirectoryName) + listener.Stop() + listener.Close() + Return fileInfo.Length + End Function + + End Module +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/EnumFileSizes.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/EnumFileSizes.vb new file mode 100644 index 00000000000..d0d615d0185 --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/EnumFileSizes.vb @@ -0,0 +1,15 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Namespace Microsoft.VisualBasic.Forms.Tests + Friend Module EnumFileSizes + Friend Enum FileSizes As Integer + Unknown = -1 + FileSize0Bytes = 0 ' The file does not exist + FileSize1Byte = 1 + FileSize1MB = 1_048_576 + FileSize100MB = 104_857_600 + FileSize1GB = 1_048_576_000 + End Enum + End Module +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/PrivateSetterContractResolver.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/PrivateSetterContractResolver.vb new file mode 100644 index 00000000000..f3156fda23c --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/PrivateSetterContractResolver.vb @@ -0,0 +1,33 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.Reflection +Imports System.Text.Json +Imports System.Text.Json.Serialization.Metadata + +Namespace Microsoft.VisualBasic.Forms.Tests + Public Class PrivateSetterContractResolver + Inherits DefaultJsonTypeInfoResolver + + Public Overrides Function GetTypeInfo(type As Type, options As JsonSerializerOptions) As JsonTypeInfo + Dim jsonTypeInfo As JsonTypeInfo = MyBase.GetTypeInfo(type, options) + + If jsonTypeInfo.Kind = JsonTypeInfoKind.Object Then + For Each [property] As JsonPropertyInfo In jsonTypeInfo.Properties + [property].Set = Function(obj, value) + Dim prop As PropertyInfo = type.GetProperty( + [property].Name, + BindingFlags.Public _ + Or BindingFlags.NonPublic _ + Or BindingFlags.Instance _ + Or BindingFlags.IgnoreCase) + prop.SetValue(obj, value, Nothing) + Return True + End Function + Next + End If + + Return jsonTypeInfo + End Function + End Class +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/ServerConfiguration.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/ServerConfiguration.vb new file mode 100644 index 00000000000..a7464bba11e --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/ServerConfiguration.vb @@ -0,0 +1,233 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.IO +Imports System.Text.Json +Imports System.Text.Json.Serialization + +Namespace Microsoft.VisualBasic.Forms.Tests + + Public Class ServerConfiguration + Private Const JsonDefaultFileName As String = "ServerConfiguration.JSON" + + Private Shared ReadOnly s_deserializerOptions As New JsonSerializerOptions() With { + .TypeInfoResolver = New PrivateSetterContractResolver()} + + Private Shared ReadOnly s_jsonFilePathBase As String = Path.Join( + My.Application.Info.DirectoryPath, + "System\Windows\TestUtilities\TestData") + + Private ReadOnly _serializerOptions As New JsonSerializerOptions With { + .WriteIndented = True} + + Private _fileDownloadUrlPrefix As String = "http://127.0.0.1:8080/" + Private _fileUploadUrlPrefix As String = "http://127.0.0.1:8080/" + Private _serverDownloadAllowsAnonymousUser As Boolean = True + Private _serverDownloadIgnoresPasswordErrors As Boolean + Private _serverDownloadPassword As String = "" + Private _serverDownloadUserName As String = "" + Private _serverUploadAllowsAnonymousUser As Boolean = True + Private _serverUploadIgnoresPasswordErrors As Boolean + Private _serverUploadPassword As String = "" + Private _serverUploadUserName As String = "" + + Public Sub New() + + End Sub + + + Public Sub New( + fileDownloadUrlPrefix As String, + fileUploadUrlPrefix As String, + serverDownloadAllowsAnonymousUser As Boolean, + serverDownloadIgnoresPasswordErrors As Boolean, + serverDownloadPassword As String, + serverDownloadUserName As String, + serverUploadAllowsAnonymousUser As Boolean, + serverUploadIgnoresPasswordErrors As Boolean, + serverUploadPassword As String, + serverUploadUserName As String) + + Me.FileDownloadUrlPrefix = fileDownloadUrlPrefix + Me.FileUploadUrlPrefix = fileUploadUrlPrefix + Me.ServerDownloadAllowsAnonymousUser = serverDownloadAllowsAnonymousUser + Me.ServerDownloadIgnoresPasswordErrors = serverDownloadIgnoresPasswordErrors + Me.ServerDownloadPassword = serverDownloadPassword + Me.ServerDownloadUserName = serverDownloadUserName + Me.ServerUploadAllowsAnonymousUser = serverUploadAllowsAnonymousUser + Me.ServerUploadIgnoresPasswordErrors = serverUploadIgnoresPasswordErrors + Me.ServerUploadPassword = serverUploadPassword + Me.ServerUploadUserName = serverUploadUserName + End Sub + + + Public Property FileDownloadUrlPrefix As String + Private Get + Return _fileDownloadUrlPrefix + End Get + Set + _fileDownloadUrlPrefix = Value + End Set + End Property + + + Public Property FileUploadUrlPrefix As String + Private Get + Return _fileUploadUrlPrefix + End Get + Set + _fileUploadUrlPrefix = Value + End Set + End Property + + + Public Property ServerDownloadAllowsAnonymousUser As Boolean + Private Get + Return _serverDownloadAllowsAnonymousUser + End Get + Set + _serverDownloadAllowsAnonymousUser = Value + End Set + End Property + + + Public Property ServerDownloadIgnoresPasswordErrors As Boolean + Private Get + Return _serverDownloadIgnoresPasswordErrors + End Get + Set + _serverDownloadIgnoresPasswordErrors = Value + End Set + End Property + + + Public Property ServerDownloadPassword As String + Private Get + Return _serverDownloadPassword + End Get + Set + _serverDownloadPassword = Value + End Set + End Property + + + Public Property ServerDownloadUserName As String + Private Get + Return _serverDownloadUserName + End Get + Set + _serverDownloadUserName = Value + End Set + End Property + + + Public Property ServerUploadAllowsAnonymousUser As Boolean + Private Get + Return _serverUploadAllowsAnonymousUser + End Get + Set + _serverUploadAllowsAnonymousUser = Value + End Set + End Property + + + Public Property ServerUploadIgnoresPasswordErrors As Boolean + Private Get + Return _serverUploadIgnoresPasswordErrors + End Get + Set + _serverUploadIgnoresPasswordErrors = Value + End Set + End Property + + + Public Property ServerUploadPassword As String + Private Get + Return _serverUploadPassword + End Get + Set + _serverUploadPassword = Value + End Set + End Property + + + Public Property ServerUploadUserName As String + Private Get + Return _serverUploadUserName + End Get + Set + _serverUploadUserName = Value + End Set + End Property + + Private Shared Function GetJsonFilePath(jsonFilePathBase As String, jsonFileName As String) As String + If String.IsNullOrWhiteSpace(jsonFilePathBase) Then + jsonFilePathBase = s_jsonFilePathBase + End If + Return Path.Join(jsonFilePathBase, jsonFileName) + End Function + + Friend Function GetAcceptsAnonymousLogin(uploading As Boolean) As Boolean + If uploading Then + Return ServerUploadAllowsAnonymousUser + Else + Return ServerDownloadAllowsAnonymousUser + End If + End Function + + Friend Function GetDefaultPassword(uploading As Boolean) As String + If uploading Then + Return ServerUploadPassword + Else + Return ServerDownloadPassword + End If + End Function + + Friend Function GetDefaultUserName(uploading As Boolean) As String + If uploading Then + Return ServerUploadUserName + Else + Return ServerDownloadUserName + End If + End Function + + Friend Function GetFileUrlPrefix(uploading As Boolean) As String + If uploading Then + Return FileUploadUrlPrefix + Else + Return FileDownloadUrlPrefix + End If + End Function + + Friend Function GetThrowsPasswordErrors(uploading As Boolean) As Boolean + If uploading Then + Return Not ServerUploadIgnoresPasswordErrors + Else + Return Not ServerDownloadIgnoresPasswordErrors + End If + End Function + + Public Shared Function ServerConfigurationLoad( + Optional jsonFilePathBase As String = "", + Optional jsonFileName As String = JsonDefaultFileName) As ServerConfiguration + + Dim jsonFileNameWithPath As String = GetJsonFilePath(jsonFilePathBase, jsonFileName) + If File.Exists(jsonFileNameWithPath) Then + Dim jsonString As String = File.ReadAllText(jsonFileNameWithPath) + Return JsonSerializer.Deserialize(Of ServerConfiguration)(jsonString, s_deserializerOptions) + End If + Return New ServerConfiguration + End Function + + Public Function ServerConfigurationSave( + Optional jsonFilePathBase As String = "", + Optional jsonFileName As String = JsonDefaultFileName) As String + + Dim jsonFileNameWithPath As String = GetJsonFilePath(jsonFilePathBase, jsonFileName) + Dim jsonString As String = JsonSerializer.Serialize(Me, _serializerOptions) + File.WriteAllText(jsonFileNameWithPath, jsonString) + Return jsonFileNameWithPath + End Function + + End Class +End Namespace diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/TestData/ServerConfiguration.json b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/TestData/ServerConfiguration.json new file mode 100644 index 00000000000..03191e63526 --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/TestData/ServerConfiguration.json @@ -0,0 +1,12 @@ +{ + "FileDownloadUrlPrefix": "http://127.0.0.1:8080/", + "FileUploadUrlPrefix": "http://127.0.0.1:8080/", + "ServerDownloadAllowsAnonymousUser": true, + "ServerDownloadIgnoresPasswordErrors": false, + "ServerDownloadPassword": "", + "ServerDownloadUserName": "", + "ServerUploadAllowsAnonymousUser": true, + "ServerUploadIgnoresPasswordErrors": false, + "ServerUploadPassword": "", + "ServerUploadUserName": "" +} \ No newline at end of file diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/TestData/ServerConfigurationSample.JSON b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/TestData/ServerConfigurationSample.JSON new file mode 100644 index 00000000000..3e36d5eef58 --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/TestData/ServerConfigurationSample.JSON @@ -0,0 +1,12 @@ +{ + "FileDownloadUrlPrefix": "http://someServer.net/", + "FileUploadUrlPrefix": "ftp://ftp.someServer.com/", + "ServerDownloadAllowsAnonymousUser": false, + "ServerDownloadIgnoresPasswordErrors": true, + "ServerDownloadPassword": "Anything", + "ServerDownloadUserName": "Anonymous", + "ServerUploadAllowsAnonymousUser": false, + "ServerUploadIgnoresPasswordErrors": true, + "ServerUploadPassword": "rNrKYTX9g7z3RgJRmxWuGHbeu", + "ServerUploadUserName": "defaultuser" +} diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/VbFileCleanupTestBase.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/VbFileCleanupTestBase.vb index e086373d263..31ca591ddb7 100644 --- a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/VbFileCleanupTestBase.vb +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/VbFileCleanupTestBase.vb @@ -17,7 +17,9 @@ Namespace Microsoft.VisualBasic.Forms.Tests Dispose(disposing:=False) End Sub - ' The base path is system temp directory / a guaranteed unique directory based on a GUID / a temp directory based on TestName + ' The base path is the system temp directory / + ' a guaranteed unique directory based on a GUID / + ' a temp directory based on TestName Friend Shared ReadOnly Property BaseTempPath As String Get Return s_baseTempPath @@ -36,16 +38,23 @@ Namespace Microsoft.VisualBasic.Forms.Tests End Sub ''' - ''' If size >= 0 then create the file with size length. + ''' If size is not FileSize.Unknown then create the file with size length. ''' ''' Full path to working directory. ''' - ''' Size in bytes of the file to be created. + ''' FileSize of the file to be created. ''' ''' The full path and file name of the created file. - ''' If size = -1 no file is create but the full path is returned. + ''' If size = FileSize.Unknown no file is create but the full path is returned. ''' - Friend Shared Function CreateTempFile(sourceDirectoryName As String, Optional filename As String = DefaultFileName, Optional size As Integer = -1) As String + Friend Shared Function CreateTempFile( + sourceDirectoryName As String, + Optional filename As String = DefaultFileName, + Optional size As FileSizes = FileSizes.Unknown) As String + + If filename = DefaultFileName AndAlso size <> FileSizes.Unknown Then + filename = $"{[Enum].GetName(size).Replace("FileSize", "")}.zip" + End If Dim filenameWithPath As String = Path.Join(sourceDirectoryName, filename) If size >= 0 Then @@ -93,7 +102,10 @@ Namespace Microsoft.VisualBasic.Forms.Tests ''' ''' If >0 use line number as part of name. ''' The name of a directory that is safe to write to and is verified to exist. - Friend Function CreateTempDirectory( Optional memberName As String = Nothing, Optional lineNumber As Integer = -1) As String + Friend Function CreateTempDirectory( + Optional memberName As String = Nothing, + Optional lineNumber As Integer = -1) As String + Dim folder As String If lineNumber > 0 Then folder = Path.Join(BaseTempPath, $"{memberName}{lineNumber}") diff --git a/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/WebListener.vb b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/WebListener.vb new file mode 100644 index 00000000000..9d6da3e410a --- /dev/null +++ b/src/Microsoft.VisualBasic.Forms/tests/UnitTests/System/Windows/TestUtilities/WebListener.vb @@ -0,0 +1,309 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. + +Imports System.IO +Imports System.Net +Imports System.Runtime.CompilerServices +Imports System.Threading + +Namespace Microsoft.VisualBasic.Forms.Tests + + Public Class WebListener + Inherits ServerConfiguration + Private Const BufferSize As Integer = 4096 + Private ReadOnly _address As String + Private ReadOnly _fileName As String + Private ReadOnly _fileSize As Integer + Private ReadOnly _fileUrlPrefix As String + Private ReadOnly _localServer As Boolean + Private ReadOnly _serverConfigurationInstance As ServerConfiguration + Private ReadOnly _serverPassword As String + Private ReadOnly _serverUserName As String + Private ReadOnly _upload As Boolean + + ''' + ''' The name of the function that creates the server is used to establish the file to be downloaded. + ''' + ''' Is used to create the file name and the size of download. + ''' Used to establish the file path to be downloaded. + Public Sub New(fileSize As Integer, Optional supportAnonymousLogin As Boolean = True, Optional memberName As String = Nothing) + _fileName = $"{[Enum].GetName(GetType(FileSizes), fileSize)}.zip".Replace("FileSize", "") + _fileSize = fileSize + _serverConfigurationInstance = ServerConfigurationLoad() + _fileUrlPrefix = _serverConfigurationInstance.GetFileUrlPrefix(_upload) + _localServer = _fileUrlPrefix.Contains("8080") + _upload = memberName.Contains("Upload", StringComparison.InvariantCultureIgnoreCase) + If _localServer Then + ServerAcceptsAnonymousLogin = supportAnonymousLogin + Else + ServerAcceptsAnonymousLogin = _serverConfigurationInstance.GetAcceptsAnonymousLogin(_upload) + End If + ServerThrowsPasswordErrors = _serverConfigurationInstance.GetThrowsPasswordErrors(_upload) + _address = $"{_serverConfigurationInstance.GetFileUrlPrefix(_upload)}{_fileName}" + End Sub + + ''' + ''' Used for authenticated download. + ''' + ''' Passed to Me.New. + ''' Name to match for authorization. + ''' Password to match for authorization. + ''' Passed to Me.New. + Public Sub New( + fileSize As Integer, + serverUserName As String, + serverPassword As String, + Optional supportAnonymousLogin As Boolean = True, + Optional memberName As String = Nothing) + + Me.New(fileSize, supportAnonymousLogin, memberName) + + If _localServer Then + _serverPassword = serverPassword + _serverUserName = serverUserName + Else + If serverPassword = DefaultPassword Then + _serverPassword = _serverConfigurationInstance.GetDefaultPassword(_upload) + Else + _serverPassword = serverPassword + End If + If serverUserName = DefaultUserName Then + _serverUserName = _serverConfigurationInstance.GetDefaultUserName(_upload) + Else + _serverUserName = serverUserName + End If + End If + End Sub + + Public ReadOnly Property Address As String + Get + Return _address + End Get + End Property + + ''' + ''' This server will save a when something in the stream doesn't + ''' match what is expected. These will never be visible to the user. + ''' + ''' A with a description of the issue or + Public Property FaultMessage As String + + Public ReadOnly Property FileSize As Long + Get + Return _fileSize + End Get + End Property + + Public Property ServerAcceptsAnonymousLogin As Boolean = True + + Public ReadOnly Property ServerPassword As String + Get + Return _serverPassword + End Get + End Property + + ''' + ''' Some File servers do not return errors on mismatched passwords so we need to + ''' ignore tests that expect errors. + ''' + ''' + Public Property ServerThrowsPasswordErrors As Boolean = True + + Public ReadOnly Property ServerUserName As String + Get + Return _serverUserName + End Get + End Property + + Private Shared Function GetBoundary(contentType As String) As String + Dim elements As String() = contentType.Split(New Char() {";"c}, StringSplitOptions.RemoveEmptyEntries) + Dim element As String = elements.FirstOrDefault(Function(e) e.Trim().StartsWith("boundary=", StringComparison.OrdinalIgnoreCase)) + Return If(element IsNot Nothing, element.Substring(startIndex:=element.IndexOf("="c) + 1).Trim().Trim(""""c), String.Empty) + End Function + + Private Shared Function GetContentDispositionHeader( + lines As List(Of String), + ByRef headerParts() As String) As Integer + For dispositionIndex As Integer = 0 To lines.Count - 1 + Dim line As String = lines(dispositionIndex) + If line.Contains("Content-Disposition", StringComparison.InvariantCultureIgnoreCase) Then + headerParts = line.Split({":"c}, count:=2) + Dim result As Boolean = headerParts.Length = 2 _ + AndAlso headerParts(0).Trim().Equals(value:="Content-Disposition", + comparisonType:=StringComparison.OrdinalIgnoreCase) + Return dispositionIndex + End If + Next + Return -1 + End Function + + Private Shared Function GetDataLength(lines As List(Of String), dispositionIndex As Integer) As Integer + For Each line As String In lines + If line.Substring(0, 1) = vbNullChar Then + Return line.Length + End If + Next + Return 0 + End Function + + Private Shared Function GetFilename(headerParts() As String) As String + Dim value As String = "" + Dim line As String = headerParts(1) + Dim startIndex As Integer = line.IndexOf("filename=""", StringComparison.InvariantCultureIgnoreCase) + If startIndex > -1 Then + line = line.Substring(startIndex + 10) + Dim length As Integer = line.IndexOf(""""c) + value = line.Substring(0, length) + End If + + Return value + End Function + + Friend Function ProcessRequests() As HttpListener + ' Create a listener and add the prefixes. + Dim listener As New HttpListener() + + If _fileUrlPrefix.Contains("8080") Then + + listener.Prefixes.Add(_fileUrlPrefix) + If Not ServerAcceptsAnonymousLogin _ + OrElse _serverUserName IsNot Nothing _ + OrElse _serverPassword IsNot Nothing Then + listener.AuthenticationSchemes = AuthenticationSchemes.Basic + End If + listener.Start() + Dim action As Action = + Sub() + ' Start the listener to begin listening for requests. + Dim response As HttpListenerResponse = Nothing + Try + ' Note: GetContext blocks while waiting for a request. + Dim context As HttpListenerContext = listener.GetContext() + ' Create the response. + response = context.Response + + If context.User?.Identity.IsAuthenticated Then + Dim identity As HttpListenerBasicIdentity = + CType(context.User?.Identity, HttpListenerBasicIdentity) + + If String.IsNullOrWhiteSpace(identity.Name) _ + OrElse identity.Name <> _serverUserName _ + OrElse String.IsNullOrWhiteSpace(identity.Password) _ + OrElse identity.Password <> _serverPassword Then + + response.StatusCode = HttpStatusCode.Unauthorized + Exit Try + End If + End If + + ' Simulate network traffic + Thread.Sleep(millisecondsTimeout:=20) + If _upload Then + Dim request As HttpListenerRequest = context.Request + If request.HttpMethod.Equals("Post", StringComparison.OrdinalIgnoreCase) _ + AndAlso request.HasEntityBody Then + + Dim formData As Dictionary(Of String, String) = GetMultipartFormData(request) + + Using bodyStream As Stream = request.InputStream + Using reader As New StreamReader( + stream:=bodyStream, + encoding:=request.ContentEncoding, + detectEncodingFromByteOrderMarks:=True, + BufferSize) + End Using + End Using + Try + Dim dataLength As String = formData(NameOf(dataLength)) + If _fileSize.ToString <> dataLength Then + FaultMessage = $"File size mismatch, expected {_fileSize} actual {dataLength}" + Else + Dim fileName As String = formData("filename") + If Not fileName.Equals(_fileName, StringComparison.OrdinalIgnoreCase) Then + FaultMessage = $"Filename incorrect, expected '{_fileName}', actual {fileName}" + End If + End If + Catch ex As Exception + ' Ignore is case upload is cancelled + End Try + End If + response.StatusCode = 200 + Else + If _fileSize = 0 Then + response.StatusCode = HttpStatusCode.NotFound + Exit Try + End If + + Dim responseString As String = Strings.StrDup(_fileSize, "A") + Dim buffer() As Byte = Text.Encoding.UTF8.GetBytes(responseString) + response.ContentLength64 = buffer.Length + Using output As Stream = response.OutputStream + Try + output.Write(buffer, offset:=0, count:=buffer.Length) + Catch ex As Exception + ' ignore it will be handled elsewhere + End Try + End Using + End If + Finally + Try + response?.Close() + Catch ex As Exception + + End Try + response = Nothing + End Try + End Sub + + Task.Run(action) + End If + Return listener + End Function + + ''' + ''' Parses a and gets the fileName of the uploaded file + ''' and the lenght of the data file in bytes + ''' + ''' + ''' + ''' A that contains the filename and lenght of the data file. + ''' + Public Function GetMultipartFormData(request As HttpListenerRequest) As Dictionary(Of String, String) + Dim result As New Dictionary(Of String, String) + + If request.ContentType.StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase) Then + Dim boundary As String = GetBoundary(request.ContentType) + Using reader As New StreamReader(request.InputStream, request.ContentEncoding) + Try + Dim content As String = reader.ReadToEnd() + Dim parts As String() = content.Split(boundary, StringSplitOptions.RemoveEmptyEntries) + + For Each part As String In parts + If part.Trim() <> "--" Then + Dim separator As String() = New String() {Environment.NewLine} + Dim lines As List(Of String) = part.Split(separator, StringSplitOptions.RemoveEmptyEntries).ToList + If lines.Count > 2 Then + Dim headerParts As String() = Nothing + Dim dispositionIndex As Integer = GetContentDispositionHeader(lines, headerParts) + + If dispositionIndex > -1 Then + result.Add("filename", GetFilename(headerParts)) + If lines.Count > dispositionIndex + 1 Then + result.Add("dataLength", GetDataLength(lines, dispositionIndex).ToString) + End If + Exit For + End If + End If + End If + Next + Catch ex As Exception + FaultMessage = "MultipartFormData format Error" + End Try + End Using + End If + + Return result + End Function + + End Class +End Namespace diff --git a/src/System.Windows.Forms.Analyzers.VisualBasic/src/Analyzers/ImplementITypedDataObject/ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer.vb b/src/System.Windows.Forms.Analyzers.VisualBasic/src/Analyzers/ImplementITypedDataObject/ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer.vb index 2206c25609b..8dd36d405ce 100644 --- a/src/System.Windows.Forms.Analyzers.VisualBasic/src/Analyzers/ImplementITypedDataObject/ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer.vb +++ b/src/System.Windows.Forms.Analyzers.VisualBasic/src/Analyzers/ImplementITypedDataObject/ImplementITypedDataObjectInAdditionToIDataObjectAnalyzer.vb @@ -2,8 +2,6 @@ ' The .NET Foundation licenses this file to you under the MIT license. Imports System.Collections.Immutable -Imports System.Runtime.InteropServices.ComTypes -Imports System.Windows.Forms.Analyzers Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Diagnostics Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/System.Windows.Forms.Analyzers.VisualBasic/src/Resources/SR.resx b/src/System.Windows.Forms.Analyzers.VisualBasic/src/Resources/SR.resx index 2e834488616..ab6186134f4 100644 --- a/src/System.Windows.Forms.Analyzers.VisualBasic/src/Resources/SR.resx +++ b/src/System.Windows.Forms.Analyzers.VisualBasic/src/Resources/SR.resx @@ -1,17 +1,17 @@  -