Всем здравствуйте.
Возникла проблема при попытке считать информацию о содержимом папки на Linux FTP сервере (используется vsftpd на embedded linux для CPU MIPS с ядром 3.2). В моём случае, она возникает только при запросе содержимого папки, в которой расположена лишь одна подпапка.
Ниже расположен код с уже реализованным "костылём", который при получении ошибки (в коде она не конкретизируется, но это ProtocolError -> ActionNotTakenFileUnavailable), заново инициализирует реквест, после чего ошибка магическим образом исчезает и попытка получение response уже не приводит к ошибке и возвращает правильный результат.
Может я идиот и что-то не так делаю, может чего-то не знаю - кто-то может объяснить, что происходит?
C# |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
| /// <summary>
/// Получает список содержимого в указанной папке FTP сервера
/// </summary>
public static List<LinuxContentInfo> GetContentInFTPDirectory(string directoryPath,
string ipAddress,
string ftpPort,
string userName,
string password)
{
try
{
// Создание запроса на получение содержимого папки FTP сервера
FtpWebRequest request = null;
Action<object> FtpWebRequestInitialization = new Action<object>(delegate
{
request = (FtpWebRequest)WebRequest.Create(new Uri("ftp://" + ipAddress + ":" + ftpPort + directoryPath));
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.UseBinary = true;
request.UsePassive = true;
request.Credentials = new NetworkCredential(userName, password);
});
FtpWebRequestInitialization(new object());
//Выполнение запроса
FtpWebResponse response = null;
try
{
response = (FtpWebResponse)request.GetResponse();
}
catch
{
//ПРИМЕЧАНИЕ: Была замечена странная ошибка, когда при запросе содержимого папки с именем "enigma2",
//возникает ошибка 550. В папке "enigma2" при этом находится лишь одна подпапка "python".
//Проблема удивительным образом исчезает, если заново инициализировать FtpWebRequest и повторить запрос.
FtpWebRequestInitialization(new object());
response = (FtpWebResponse)request.GetResponse();
}
//Получения ответа на запрос и его считывание
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string responseData = reader.ReadToEnd();
//Закрытие считывателя и ответа
reader.Close();
response.Close();
string[] contentLines = responseData.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
if (contentLines.Length > 1 && contentLines[0] == responseData)
contentLines = responseData.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
List<LinuxContentInfo> lstLinuxContentInfo = new List<LinuxContentInfo>();
foreach (string contentLine in contentLines)
{
char cType = contentLine[0];
string ownerRights = contentLine.Substring(1, 3);
string rootRights = contentLine.Substring(4, 3);
string userRights = contentLine.Substring(7, 3);
bool yearInsteadTime = false;
Regex regex = new Regex("^(-|d|l)([a-z-]{3})([a-z-]{3})([a-z-]{3})[\\s]+([0-9]+)[\\s]+([A-Za-z0-9]+)[\\s]+([A-Za-z0-9]+)[\\s]+([0-9]+)[\\s]+([A-Z][a-z][a-z])[\\s]+([0-9]+)[\\s]+([0-9]{2}:[0-9]{2})[\\s]+(.+$)");
Match match = regex.Match(contentLine);
if (!match.Success)
{
regex = new Regex("^(-|d|l)([a-z-]{3})([a-z-]{3})([a-z-]{3})[\\s]+([0-9]+)[\\s]+([A-Za-z0-9]+)[\\s]+([A-Za-z0-9]+)[\\s]+([0-9]+)[\\s]+([A-Z][a-z][a-z])[\\s]+([0-9]+)[\\s]+([0-9]{4})[\\s]+(.+$)");
match = regex.Match(contentLine);
yearInsteadTime = true;
}
LinuxContentInfo info = new LinuxContentInfo();
info.Type = match.Groups[1].Value == "-" ? ContentType.FILE : match.Groups[1].Value == "d" ? ContentType.DIRECTORY : match.Groups[1].Value == "l" ? ContentType.LINK : ContentType.UNKNOWN;
info.OwnerRights = new bool[] { match.Groups[2].Value[0] != '-' ? true : false, match.Groups[2].Value[1] != '-' ? true : false, match.Groups[2].Value[2] != '-' ? true : false };
info.RootRights = new bool[] { match.Groups[3].Value[0] != '-' ? true : false, match.Groups[3].Value[1] != '-' ? true : false, match.Groups[3].Value[2] != '-' ? true : false };
info.UserRights = new bool[] { match.Groups[4].Value[0] != '-' ? true : false, match.Groups[4].Value[1] != '-' ? true : false, match.Groups[4].Value[2] != '-' ? true : false };
info.UnknownInt1 = int.Parse(match.Groups[5].Value);
info.UnknownString1 = match.Groups[6].Value;
info.UnknownString2 = match.Groups[7].Value;
info.Size = long.Parse(match.Groups[8].Value);
if (!yearInsteadTime)
info.ModifyDate = DateTime.ParseExact(match.Groups[9].Value + " " + match.Groups[10].Value + " " + match.Groups[11].Value, "MMM dd HH:mm", CultureInfo.InvariantCulture);
else
info.ModifyDate = DateTime.ParseExact(match.Groups[9].Value + " " + match.Groups[10].Value + " " + match.Groups[11].Value, "MMM dd yyyy", CultureInfo.InvariantCulture);
info.Name = match.Groups[12].Value;
lstLinuxContentInfo.Add(info);
}
return lstLinuxContentInfo;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return null;
}
} |
|