Ftp Connection Failure in VB.NET - vb.net

Using the code below, I continue to get a "Unable to connect to the remote server" error at Using response as... I'm not quite sure whats wrong or where to look for help. FTP in .NET seems to be seldom used.
Ok, second stupid question. EnableSsl != Sftp?
Dim FTPrequest As FtpWebRequest = DirectCast(FtpWebRequest.Create(New Uri("ftp://176.31.212.85/dev/shm/Minecraft/world/players/Drise.dat")), FtpWebRequest)
FTPrequest.EnableSsl = True
FTPrequest.Credentials = New System.Net.NetworkCredential("user", "pass")
FTPrequest.Method = Ftp.DownloadFile
FTPrequest.UseBinary = True
FTPrequest.KeepAlive = False
Dim ftpstream As IO.Stream = Nothing
Using response As System.Net.FtpWebResponse = CType(FTPrequest.GetResponse(), System.Net.FtpWebResponse)
Using responseStream As IO.Stream = response.GetResponseStream
'loop to read & write to stream
Dim buffer(2047) As Byte
Dim read As Integer = 0
Do
read = responseStream.Read(buffer, 0, buffer.Length)
ftpstream.Write(buffer, 0, read)
Loop Until read = 0 'see Note(1)
responseStream.Close()
End Using
response.Close()
End Using

I'd like to provide some clarification I found later in regards to this question that I never got to posting. SFTP is part of the SSH family, not, SSL. VB.Net (since the last time I used it) does not support SFTP connections. There are some external libraries that do, but all of the ones I found required money.

Related

Why would my VB.NET WebRequest suddenly stop working?

A while ago I wrote a programme in VB.NET to use the Betfair Exchange API. It has worked perfectly for months, but overnight on Tuesday it stopped working. I can still log in, but from Wednesday I have been unable to get anything else from the server.
Betfair are investigating, but according to them nobody else seems to be experiencing the same problem - although I'm not sure how many will be using VB.NET.
Below is the function I have been using to obtain data from the API. Like I said it was working on Tuesday night but not from Wednesday morning. Is there anything here which is "not perfect" or "could be better", or perhaps there is some alternative code I could try? Or is there something which might have happened on my pc which has caused the problem?
The programme falls over at the line "dataStream = request.GetRequestStream() ". The error is "Received an unexpected EOF or 0 bytes from the transport stream."
I would be grateful for any advice that anyone could offer. Thank you!
Public Function CreateRequest(ByVal postData As String, Optional ByVal accountsApi As Boolean = False)
Dim Url As String = "https://api.betfair.com/exchange/betting/json-rpc/v1"
If accountsApi Then Url = "https://api.betfair.com/exchange/account/json-rpc/v1"
Dim request As WebRequest = Nothing
Dim dataStream As Stream = Nothing
Dim response As WebResponse = Nothing
Dim strResponseStatus As String = ""
Dim reader As StreamReader = Nothing
Dim responseFromServer As String = ""
Try
request = WebRequest.Create(New Uri(Url))
request.Method = "POST"
request.ContentType = "application/json-rpc"
request.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8")
request.Headers.Add("X-Application", appKey)
request.Headers.Add("X-Authentication", sessToken)
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData) ' Data to post such as ListEvents, ListMarketCatalogue etc
request.ContentLength = byteArray.Length ' Set the ContentLength property of the WebRequest.
dataStream = request.GetRequestStream() ' Get the request stream.
dataStream.Write(byteArray, 0, byteArray.Length) ' Write the data to the request stream.
dataStream.Close() ' Close the Stream object.
response = request.GetResponse() ' Get the response.
strResponseStatus = CType(response, HttpWebResponse).StatusDescription ' Display the status below if required
dataStream = response.GetResponseStream() ' Get the stream containing content returned by the server.
reader = New StreamReader(dataStream) ' Open the stream using a StreamReader for easy access.
responseFromServer = reader.ReadToEnd() ' Read the content.
reader.Close() : dataStream.Close() : response.Close()
Catch ex As Exception
MsgBox("CreateRequest Error" & vbCrLf & ex.Message, MsgBoxStyle.Critical, " Error")
End Try
Return responseFromServer
End Function
I would check that the provider hasn't recently deprecated use of TLS 1.0 (as they should have done before now, in fact).
If so, your code needs to enforce use of TLS 1.1+:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
This only has to be set once, usually in the (static) type initializer or similar.
And I 100% agree with Andrew Mortimer that you should use Using blocks wherever possible. I'd also suggest moving all of your string values into variables or constants to clean things up and keep them maintainable. Eg:
Const ContentType As String = "application/json-rpc"
...
request.ContentType = ContentType
UPDATE
I just found this announcement on their site:
https://forum.developer.betfair.com/forum/developer-program/announcements/33563-tls-1-0-no-longer-supported-from-1st-december-all-betfair-api-endpoints
If you are allowed to use external dependencies within this project I would recommend using RestSharp nuget package it works really well for creating API requests and getting there response without having to use httpclient which gets messy.
Link: https://restsharp.dev/

Uploading file with FtpWebRequest from an azure hosted application to an external ftp site

UPDATE: I found out that it is not an issue with azure rather the
other party who are actually doing white-listing on incoming
connection.
I implemented a service, which open and ftp connection to upload a file to a remote FTP server. The code works perfectly (!) running on my desktop, however if I publish it to the azure hosting cloud and execute with exactly the same parameters I get WebException with the message 'The remote server returned an error: (530) Not logged in.' I haven't found any relevant setting in the azure console. I also tried different setting like on/off keep-alive and passive, but the result are the same. Do you guys have an idea what could be the problem?
The code for reference:
Dim request As FtpWebRequest
request = TryCast(WebRequest.Create($"ftp://{_host}/inventory/{_uploadFilename}"), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.UploadFile
request.Credentials = New NetworkCredential(_username, _password)
request.UsePassive = True
request.UseBinary = True
request.KeepAlive = False
Using fs As FileStream = File.OpenRead(_fileName)
Dim buffer As Byte() = New Byte(fs.Length - 1) {}
fs.Read(buffer, 0, buffer.Length)
fs.Close()
Dim requestStream As Stream = request.GetRequestStream()
requestStream.Write(buffer, 0, buffer.Length)
requestStream.Flush()
requestStream.Close()
Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
Return Ok($"Remote server response: {response.StatusDescription}")
End Using
Where is NetworkCredential getting credentials from?
Windows Authentication (Kerberos/NTLM) won't work in Azure. You need to use FTP login (as in USER and PASS FTP commands).
Always use PASSIVE mode when attempting FTP transfer from Azure.
Imports System.IO
Imports System.Net
Module Module1
Sub Main()
Dim request As FtpWebRequest
Dim _host = "remote.ftpserver.com"
Dim _uploadFilename = "file.txt"
Dim _filename = "file.txt"
Dim _username = "Username"
Dim _password = "PaSsw0rD"
request = TryCast(WebRequest.Create($"ftp://{_host}/path/{_uploadFilename}"),
FtpWebRequest)
request.Method = WebRequestMethods.Ftp.UploadFile
request.Credentials = New NetworkCredential(_username, _password)
request.UsePassive = True
request.UseBinary = True
request.KeepAlive = False
Using fs As FileStream = File.OpenRead(_filename)
Dim buffer As Byte() = New Byte(fs.Length - 1) {}
fs.Read(buffer, 0, buffer.Length)
fs.Close()
Dim requestStream As Stream = request.GetRequestStream()
requestStream.Write(buffer, 0, buffer.Length)
requestStream.Flush()
requestStream.Close()
Dim response As FtpWebResponse = DirectCast(request.GetResponse(),
FtpWebResponse)
Console.WriteLine($"Remote server response: {response.StatusCode},
{response.StatusDescription}")
End Using
End Sub
End Module
Apologies if the formatting is all over the place. This is my first attempt at writing VB.
Running this in Kudu's DebugConsole for clarity - same sandbox as the Web App:
On the remote FTP server:
ftp> ls file.txt
200 PORT command successful.
125 Data connection already open; Transfer starting.
file.txt
226 Transfer complete.
ftp: 13 bytes received in 0.02Seconds 0.81Kbytes/sec.
ftp> bin
200 Type set to I.
ftp> get file.txt
200 PORT command successful.
125 Data connection already open; Transfer starting.
226 Transfer complete.
ftp: 24 bytes received in 0.18Seconds 0.14Kbytes/sec.
ftp> !type file.txt
Upped with FtpWebRequest
I found out that it is not an issue with azure rather the other party who are actually doing white-listing on incoming connection.

Creating a file on my website using VB.net

I have searched but couldn't get any real solution to creating a file on my website by uploading the file from the local system using VB.net
This is my code so far
Dim rdr As New FileStream(ReSaveFile, FileMode.Open)
Dim req As HttpWebRequest = DirectCast(WebRequest.Create("http://www.timemedian.com/display.txt"), HttpWebRequest)
req.Method = "POST"
' you might use "POST"
req.ContentLength = rdr.Length
req.AllowWriteStreamBuffering = True
Dim reqStream As Stream = req.GetRequestStream()
Dim inData As Byte() = New Byte(rdr.Length - 1) {}
' Get data from upload file to inData
Dim bytesRead As Integer = rdr.Read(inData, 0, rdr.Length)
' put data into request stream
reqStream.Write(inData, 0, rdr.Length)
rdr.Close()
req.GetResponse()
' after uploading close stream
reqStream.Close()
but I cant possible see the error. Please help
I uploaded the file using ftp protocol like this
Try
Dim mReq1 As System.Net.FtpWebRequest = DirectCast(System.Net.WebRequest.Create("ftp://ftp.websitename.com//" & SetID & ".pvx"), System.Net.FtpWebRequest)
mReq1.Credentials = New System.Net.NetworkCredential("username", "password")
mReq1.Method = System.Net.WebRequestMethods.Ftp.UploadFile
Dim MFile1() As Byte = System.IO.File.ReadAllBytes(ReSaveFile)
Dim mStream1 As System.IO.Stream = mReq1.GetRequestStream()
mStream1.Write(MFile1, 0, MFile1.Length)
mStream1.Close()
mStream1.Dispose()
Catch ex As Exception
MsgBox("Your file was not fully posted to the remote server. PVX Mail may not function properly")
Exit Sub
End Try

FTP UPLOAD to AS/400 from VB.NET

I am attempting to perform a FTP Put function to an AS/400 IBM Mainframe with VB.NET. I am able to upload a file however, I need to be able to capture each output response from the mainframe for logging purposes. In short capture what prints out on the cmd screen if I were to perform the FTP manually. Any suggestions would be greatly appreciated.
Depending on the library you are using, you should be able to get some kind of response object or string from the FTP server for each command you submit. You can then parse these responses and dump them into a file/destination/source of your choosing.
EDIT: Since you're using the FTPWebRequest/Response library, you'll want to have your FTPWebRequest object dump its results into the FTPWebResponse object and then read the entire stream with code something like this:
Dim request As FtpWebRequest = DirectCast(WebRequest.Create(serverUri), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.ListDirectory
Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
Dim responseStream As Stream = Nothing
Dim readStream As StreamReader = Nothing
Try
responseStream = response.GetResponseStream()
readStream = New StreamReader(responseStream, System.Text.Encoding.UTF8)
If readStream IsNot Nothing Then
Console.WriteLine(readStream.ReadToEnd())
End If
Console.WriteLine("List status: " & response.StatusDescription)
Finally
If readStream IsNot Nothing Then
readStream.Close()
End If
If response IsNot Nothing Then
response.Close()
End If
End Try
Return True
End Function
You should be able to tailor this code to your own in order to retrieve the response details you need.

Download file from ftp if newer or different

I am trying to download a file from an ftp site only if it's newer than my local file. Can anyone help how to incorporate to check for the file properties? right now it downloads the file, but just need if newer. The purpose is to update a .mdb with the contents of the file, so don't want to download file and run an update everytime my app runs, only if the file is different. This is the code I am using:
Const localFile As String = "C:\version.xml"
Const remoteFile As String = "/version.xml"
Const host As String = "ftp://1.1.1.1"
Const username As String = "user"
Const password As String = "pwd"
Dim URI As String = host & remoteFile
Dim ftp As System.Net.FtpWebRequest = _
CType(FtpWebRequest.Create(URI), FtpWebRequest)
ftp.Credentials = New _
System.Net.NetworkCredential(username, password)
ftp.KeepAlive = False
ftp.UseBinary = True
ftp.Method = System.Net.WebRequestMethods.Ftp.DownloadFile
Using response As System.Net.FtpWebResponse = _
CType(ftp.GetResponse, System.Net.FtpWebResponse)
Using responseStream As IO.Stream = response.GetResponseStream
Using fs As New IO.FileStream(localFile, IO.FileMode.Create)
Dim buffer(2047) As Byte
Dim read As Integer = 0
Do
read = responseStream.Read(buffer, 0, buffer.Length)
fs.Write(buffer, 0, read)
Loop Until read = 0
responseStream.Close()
fs.Flush()
fs.Close()
End Using
responseStream.Close()
End Using
response.Close()
End Using
Any help is appreciated
Not sure if this answers your question but I am looking for a similar answer and came across this.
http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx
Look into LastWriteTime and you could save that time and check to see if it is a newer date then what is saved. You would have to also figure out how to download the file as a while(not familiar with the code maybe you are).