Загрузка файла с ftp через http-прокси
От: STeAlth-S Россия  
Дата: 26.02.09 08:35
Оценка:
При загрузки файлов 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 { }
        }
    }
не люблю мелкие и мягкие, люблю большие и упругие)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.