При загрузки файлов c ftp-сервера через http-прокси периодически возникает следующая проблема:
в начале потока добавляется некоторое количество нулей (62-63), конец обрезается на такое же количество байт.
Баг не стабилен. Загрузка файлов без прокси проходит успешно.
В чем может быть проблема?
Вот класс осуществляющий загрузку:
class Downloader
{
//constants
public const int ChunkSize = 1024;
public const string DOWNLOAD_SUCCESS = "OK";
//fields & properties
string _SourceURL="";
public string SourceURL
{
get { return _SourceURL; }
set
{
_SourceURL = value;
proxy = WebProxy.GetDefaultProxy();
proxy.Credentials = CredentialCache.DefaultCredentials;
if (proxy.IsBypassed(new Uri(SourceURL)))
proxy = null;
}
}
WebProxy proxy = null;
FtpWebRequest WebReq=null;
bool AbortDownload = false;
string DestFolder = "";
//delegates & events
public delegate void UpdateDownloadHandler(string nm, int percent);
public delegate void DownloadComplitHandler(string status);
public event UpdateDownloadHandler OnUpdateDownloadStatus;
public event DownloadComplitHandler OnDownloadComplit;
//constructor
public Downloader()
{
proxy = WebProxy.GetDefaultProxy();
proxy.Credentials = CredentialCache.DefaultCredentials;
OnUpdateDownloadStatus += new UpdateDownloadHandler(Downloader_OnUpdateDownloadStatus);
OnDownloadComplit += new DownloadComplitHandler(Downloader_OnDownloadComplit);
}
//default handlers
void Downloader_OnDownloadComplit(string status)
{
}
void Downloader_OnUpdateDownloadStatus(string nm, int percent)
{
}
//methods
public void Download(string dest)
{
try
{
DestFolder = dest;
WebReq = InitFtpRequest();
ReadResponse((FtpWebResponse)(WebReq.GetResponse()));
}
catch (Exception exc)
{
OnDownloadComplit(exc.Message);
}
}
private FtpWebRequest InitFtpRequest()
{
Uri srcURI = new Uri(SourceURL);
if (srcURI.Scheme != Uri.UriSchemeFtp)
throw new Exception("URL сервера обновлений имеет не верный формат (требуется ftp://)");
FtpWebRequest webReq = (FtpWebRequest)(WebRequest.Create(srcURI));
webReq.Method = WebRequestMethods.Ftp.DownloadFile;
webReq.Timeout = 5000;
webReq.ReadWriteTimeout = 10000;
webReq.UseBinary = true;
webReq.UsePassive = true;
webReq.KeepAlive = false;
webReq.Proxy = proxy;
webReq.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
AbortDownload = false;
return webReq;
}
//async download
public void DownloadAsync(string dest)
{
try
{
DestFolder = dest;
WebReq = InitFtpRequest();
WebReq.BeginGetResponse(GetResponseCallback, this);
}
catch (Exception exc)
{
OnDownloadComplit(exc.Message);
}
}
private static void GetResponseCallback(IAsyncResult asyncResult)
{
Downloader dwn=(Downloader)(asyncResult.AsyncState);
dwn.ReadResponse((FtpWebResponse)(dwn.WebReq.EndGetResponse(asyncResult)));
}
private void ReadResponse(FtpWebResponse webResp)
{
string StatusMessage = DOWNLOAD_SUCCESS;
try
{
if (webResp.ContentLength == -1)
throw new Exception(string.Format("Не удалось загрузить файл: {0}",
WebReq.RequestUri.Segments[WebReq.RequestUri.Segments.Length - 1]));
string fname = WebReq.RequestUri.Segments[WebReq.RequestUri.Segments.Length - 1];
OnUpdateDownloadStatus(string.Format("Загрузка файла {0}", fname), -2);
string path = string.Format(@"{0}\{1}", DestFolder,
fname);
Stream fs = File.Open(path, FileMode.Create);
int cnt = 0;
using (BinaryWriter bw = new BinaryWriter(fs))
{
byte[] buf = new byte[ChunkSize];
using (Stream s = webResp.GetResponseStream())
{
do
{
if (AbortDownload)
throw new Exception("Загрузка прервана");
cnt = s.Read(buf, 0, ChunkSize);
bw.Write(buf, 0, cnt);
int percent = (int)(bw.BaseStream.Length * 100 / webResp.ContentLength);
OnUpdateDownloadStatus(
string.Format("Загрузка файла {0} : {1} %", fname, percent), percent);
}
while (cnt > 0);
}
}
}
catch (Exception exc)
{
StatusMessage=exc.Message;
}
finally
{
if (webResp != null)
webResp.Close();
OnDownloadComplit(StatusMessage);
}
}
public void Abort()
{
try
{
AbortDownload = true;
if (WebReq != null)
WebReq.Abort();
}
catch { }
}
}