I have code inside of an httphandler which I am using the serve files on a website. Basically this is used as a dynamic replacement instead of linking directly to a file. It takes an ID as input, checks database & permissions then responds back with the associated file. The file itself is stored off site on a different location. I have been instructed to use ftp to bring the file back to the our server. Our server environment is using .net 3.5.
The code I have is working without error when only a single ftp action is happening at one time.
However when the httphandler is being called multiple times simultaneously (e.g. if 4 people are using it once or one person executes 4 times at once) then some of the executions fail, with error The remote server returned an error: 150 Opening data channel for file download from server of XXX: Authentication failed because the remote party has closed the transport stream.
I was originally using fluentFTP 3rd party libraries when I encountered this problem. I thought perhaps it was 3rd party library causing the problem so in debugging I moved to just use FtpWebRequest in the below code but the same error is occurring.
I have been reading into possible fixes for the past couple of days. A lot of common responses have been tried and not worked: these include:
Setting the ServicePointManager.SecurityProtocol
Setting a high connection limit
Setting a connection group for each execution.
None of those changes have had any effect on how the code executes.
A summary of the code is noted below
try
{
//Hook a callback to verify the remote certificate
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(MyCertValidationCb);
ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol = (SecurityProtocolType)48 | (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
FtpWebRequest reqFTP = (FtpWebRequest)WebRequest.Create(new Uri("ftp://" + hostAddress + downloadByFtpSource));
reqFTP.Credentials = new NetworkCredential(ftpUSername, ftpPassword);
reqFTP.EnableSsl = true;
reqFTP.UsePassive = true;
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.KeepAlive = false;
reqFTP.ServicePoint.ConnectionLimit = 100;
Random r = new Random();
var debugTestingRandomNumber = (-1 * r.Next(1000000));
string debugTestingGroupName = "MyGroupName" + debugTestingRandomNumber.ToString();
reqFTP.ConnectionGroupName = debugTestingGroupName;
using (Stream ftpStream = reqFTP.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(downloadByFtpDestination))
{
CopyTo(ftpStream, fileStream);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
var debuggingTest = response.StatusCode.ToString();
result = true;
}
reqFTP.ServicePoint.CloseConnectionGroup(debugTestingGroupName);
}
catch (Exception ex)
{
result = false;
}
edited: to add in line reqFTP.UseBinary = true;