System.Net.WebClient具名登入FTP的傳檔路徑問題
3 |
之前介紹過使用System.Net.WebClient類別進行FTP傳檔的精簡寫法,今天發現一個問題。
某個Windows IIS FTP網站開放使用特定帳號user1登入後上傳或下載檔案,使用IE以 ftp:// ftp_ip_address/user1/test.txt的方式可以順利下檔案,但執行以下程式:
using System;
using System.IO;
using System.Threading;
using System.Net;
public class CSharpLab
{
public static void Test()
{
WebClient wc = new WebClient();
wc.Credentials = new NetworkCredential("user1", "****");
string s = wc.DownloadString("ftp://172.28.1.1/user1/test.txt");
Console.WriteLine(s + "\nDone!");
}
}
卻會傳回錯誤:
The remote server returned an error: (550) File unavailable (e.g., file not found, no access).
同事發現,若將URL改成ftp:// 172.28.1.1/test.txt,反而可以成功下載。推測應是WebClient在處理FTP位址的邏輯中,會預設加上帳號名稱(例: user1)成為路徑的一部分。
配合IIS FTP的Log,印證此點:
#Software: Microsoft Internet Information Services 6.0 #Version: 1.0 #Date: 2011-03-25 02:56:53 #Fields: time c-ip cs-method cs-uri-stem sc-status sc-win32-status 02:56:53 172.28.1.1 [1]USER user1 331 0 02:56:54 172.28.1.1 [1]PASS - 230 0 02:57:26 172.28.1.1 [1]QUIT - 257 0 02:58:09 172.28.1.1 [2]USER user1 331 0 02:58:09 172.28.1.1 [2]PASS - 230 0 /* 下載ftp:// 172.28.1.1/user1/test.txt */ 02:58:09 172.28.1.1 [2]CWD /user1/user1 550 2 02:59:05 172.28.1.1 [4]USER user1 331 0 02:59:05 172.28.1.1 [4]PASS - 230 0 /* 下載ftp:// 172.28.1.1/fodler1/foler2/test.txt */ 02:59:05 172.28.1.1 [4]CWD /user1/folder1/folder2 550 3 02:59:17 172.28.1.1 [3]USER user1 331 0 02:59:17 172.28.1.1 [3]PASS - 230 0 /* 下載ftp:// 172.28.1.1/test.txt */ 02:59:17 172.28.1.1 [3]CWD /user1 250 0 02:59:17 172.28.1.1 [3]sent /user1/test.txt 226 0 02:59:35 172.28.1.1 [3]closed - 426 1341 03:45:39 172.28.1.1 [6]USER user1 331 0 03:45:39 172.28.1.1 [6]PASS - 230 0 /* 下載ftp:// 172.28.1.1/../test.txt */ 03:45:39 172.28.1.1 [6]CWD /user1 250 0 03:45:39 172.28.1.1 [6]sent /user1/a.txt 550 2
由Log來看,WebClient會在以非匿名方式連線FTP傳檔時,先使用CWD切換路徑,切換時一律強制加上使用者帳號,造成了我們所觀察到的現象。最後一個測試用".."則變成CWD /user1,".."被無視,無法切至上層目錄。
【結論】
當System.Net.WebClient以特定身分認證(例如: user1)連線ftp:// ftpserver/file.ext方式傳檔時,會在file.ext路徑前方冠上"/user1/"(且無法用".."切到user1目錄的上層),若檔案在/user1/test.txt,URL應改為ftp:// ftpserver/test.txt方可正確對映。
[2012-08-22更新]FTP URL其實可以指定絕對路徑
Comments
# by jerryH
".."會被無視,無法切至上層目錄。 若有user2 是不是就無法用 /* 下載ftp:// 172.28.1.1/../user2/test2.txt */ 就不能用WebClient嗎?
# by Jeffrey
to jerryH, 依我的理解,WebClient假設你會用userX帳號登入來存取/userX/目錄下的檔案,如果硬要用user1登入,存取不在/user1/下的檔案(指非/user1/*, /user1/subFolder/*等隸屬關係,例如: /user2/blah.txt),就會因目錄無法切換而失敗。
# by nicole
謝謝helpful