in Eski Blog Yazılarım

FtpWebRequest ile DirectoryExists

MaestroPanel‘de bir kullanıcımız çok kritik olmayan bir bug rapor etti fakat bana enteresan bir durum geldiğinden ve biraz da zaman bulabildiğimden yazayım dedim.

Hata şöyleydi;
Web sitesinin yedeklerini uzak ftp sunucusuna gönderirken bazı FTP sunucularında sorun yaşanıyormuş.

Yani bir FTP sunucusuna sorunsuz upload ederken, farklı bir FTP sunucusuna upload sırasında 530, 500 hataları dönüyormuş loglarda.

Biraz debug yaptıktan sonra  hatanın FtpWebRequest ile dizin listelerken Unix ve Windows farkından kaynaklanan bir hata olduğunu anladım.

Normalde uzak FTP sunucusunda bir dosyanın var olup, olmadığını anlamak için istek, WebRequestMethods.Ftp.ListDirectory methodu ile işaretlenir ve FtpWebRequest’de efendi gibi dizinlerin ve dosyaların listesini döndürür.  Klasör yoksa da (550) File unavailable der.

Fakat FtpWebRequest , Linux FTP sunucularında var olmayan bir dizini kontrol etmek isteseniz sanki varmış gibi davranıyor ve herhangi bir hata döndürmüyor.

Örnek:

FtpWebRequest request = WebRequest.Create(“ftp://10.4.2.1:21/OlmayanDizin”) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.MakeDirectory;

using (FtpWebResponse response = request.GetResponse() as FtpWebResponse)
{
using (StreamReader sr = new  StreamReader(response.GetResponseStream()))
{
sr.Close();
}
response.Close();
}

Peki dizinin var olup olmadığını nasıl anlayacağız?

Öncelikle bazı sunucular UTF8 bazısı ASCII olduğundan StreamReader’da bunun otomatik bulan bir parametrenin olduğunu öğrendim detectEncodingFromByteOrderMarks konu ile ilgisi yok ama True verilmesi öngörülemeyen problemleri elemine edebileceğinden True verdim.

Diğer yandan Linux FTP sunucusundan var olmayan bir dizini (ftp://10.4.2.1:21/OlmayanDizin) istersem herhangi bir Exception’ın fırlatılmadığını fakat klasörün sonuna Forward Slash’ı koduğumda gerektiği gibi (ftp://10.4.2.1:21/OlmayanDizin/) hata fırlatıldığını keşfettim ve en son kod aşağıdaki şekide oldu.

FtpWebRequest request = WebRequest.Create(“ftp://10.4.2.1:21/OlmayanDizin/”) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.MakeDirectory;

using (FtpWebResponse response = request.GetResponse() as FtpWebResponse)
{
using (StreamReader sr = new StreamReader(response.GetResponseStream(), detectEncodingFromByteOrderMarks: true))
{
sr.Close();
}
response.Close();
}

Bu hareketle her iki tipteki FTP sunucusundaki olmayan dizini sorgularken olmadığı için hatamızı alıyoruz. Peh!

Bonus: Bu arada FtpWebRequest sınıfının TimeOut’u default 100.000 milisaniye yeni 1 dakika 40 saniye. Eğer yüksek boyutlu bir dosya gönderiyorsanız sıkıntı olabiliyor o nedenle TimeOut’u -1 olarak yani sonsuz olarak işaretlemekte fayda var.

Yorum Bırak

Comment