c # ftp загрузить в Linux - PullRequest
       18

c # ftp загрузить в Linux

3 голосов
/ 03 ноября 2011

Я пытаюсь проверить, существует ли каталог на FTP-сервере. Прежде чем сказать «использовать ListDirectory» или «использовать PrintWorkingDirectory», они не всегда работают; Например, я проверил, существует ли ftp: // webserver / Logs , и оба сказали мне, что это происходит, когда его нет. Поэтому я пошел по пути загрузки файла в каталог, и в случае успеха каталог существует.

Проблема в том, что приведенный ниже метод не работает с сервером GoDaddy на базе CentOS, на котором запущен vsFTPd 2.0.7.2. Прекрасно работает с FTP-сервером Microsoft на IIS7.5.

Поэтому я следил за трафиком с помощью Wireshark и использовал Filezilla, чтобы увидеть, что он делает, чтобы мое приложение не работало. И единственное отличие заключается в том, что Filezilla меняет рабочий каталог, когда я пытаюсь загрузить файл с путем перед ним.

Я чувствую, что это как-то связано с путём его загрузки на сервер и интерпретацией Linux, потому что это может быть немного смешно с именами ... :-D Любые идеи горячо приветствуются?

Код приложения

private bool DirectoryExists(string d)
{
    bool exists = true;
    try
    {
        string file = "directoryexists.test";
        string path = url + homepath + d + "/" + file;

        //Try to save to the directory
        req = (FtpWebRequest)WebRequest.Create(path);
        req.ConnectionGroupName = "conngroup1";
        req.Method = WebRequestMethods.Ftp.UploadFile;
        if (nc != null) req.Credentials = nc;
        if (cbSSL.Checked) req.EnableSsl = true;
        req.Timeout = 10000;

        byte[] fileContents = System.Text.Encoding.Unicode.GetBytes("SAFE TO DELETE");
        req.ContentLength = fileContents.Length;

        Stream s = req.GetRequestStream();
        s.Write(fileContents, 0, fileContents.Length);
        s.Close();

        //Delete file if successful
        req = (FtpWebRequest)WebRequest.Create(path);
        req.ConnectionGroupName = "conngroup1";
        req.Method = WebRequestMethods.Ftp.DeleteFile;
        if (nc != null) req.Credentials = nc;
        if (cbSSL.Checked) req.EnableSsl = true;
        req.Timeout = 10000;

        res = (FtpWebResponse)req.GetResponse();
        res.Close();
    }
    catch (WebException ex)
    {
        exists = false;
    }
    return exists;
}

Журнал Filezilla через Wireshark

Response: 230 Login successful.
Request: CWD /Home/test1
Response: 250 Directory successfully changed.
Request: TYPE I
Response: 200 Switching to Binary mode.
Request: PASV
Response: 227 Entering Passive Mode (216,69,186,142,71,209)
Request: LIST
Response: 150 Here comes the directory listing.
FTP Data: 78 bytes
Response: 226 Directory send OK.
Request: PASV
Response: 227 Entering Passive Mode (216,69,186,142,177,1)
Request: STOR directoryexists.txt
Response: 150 Ok to send data.
Response: 226 File receive OK.

Журнал приложения через Wireshark

Response: 230 Login successful.
Request: OPTS utf8 on
Response: 501 Option not understood.
Request: PWD
Response: 257 "/Home/"
Request: PWD
Response: 257 "/Home/"
Request: TYPE I
Response: 200 Switching to Binary mode.
Request: PASV
Response: 227 Entering Passive Mode (216,69,186,142,217,87)
Request: STOR test1/directoryexists.txt
Response: 553 Could not create file.

Создает папки, если они не существуют.

Response: 230 Login successful.
Request: PWD
Response: 257 "/Home/"
Request: PWD
Response: 257 "/Home/"
Request: TYPE I
Response: 200 Switching to Binary mode.
Request: PASV
Response: 227 Entering Passive Mode (216,69,186,142,220,60)
Request: STOR Logs/directoryexists.txt
Response: 553 Could not create file.
Request: PWD
Response: 257 "/Home/"
Request: MKD Logs
Response: 257 Create folder operation successful.
Request: TYPE I
Response: 200 Switching to Binary mode.
Request: PASV
Response: 227 Entering Passive Mode (216,69,186,142,255,245)
Request: STOR Logs/LogFiles/directoryexists.txt
Response: 553 Could not create file.
Request: PWD
Response: 257 "/Home/"
Request: MKD Logs/LogFiles
Response: 257 Create folder operation successful.

1 Ответ

3 голосов
/ 03 ноября 2011

Linux снова кусается ...

Решение состоит в том, чтобы установить двойную косую черту в имени пути, чтобы, когда дело доходит до STOR, у нее была начальная косая черта ... вот так:

string url = "ftp://website/";
string homepath = "/Home/";
string d = "test1";
string file = "directoryexists.test";

string path = url + homepath + d + "/" + file;

так что полный путь будет выглядеть как ftp://website//Home/test1/directoryexists.test

req = (FtpWebRequest)WebRequest.Create("ftp://website//Home/test1/directoryexists.test"); 

Таким образом, команда STOR будет выглядеть как

STOR /Home/test1/directoryexists.test

Вы можете получить домашний путь из StatusDescription

req = (FtpWebRequest)WebRequest.Create(url);
req.Method = WebRequestMethods.Ftp.PrintWorkingDirectory;
if (nc != null) req.Credentials = nc;
if (cbSSL.Checked) req.EnableSsl = true;
req.Timeout = 10000;
res = (FtpWebResponse)req.GetResponse();

System.Text.RegularExpressions.Regex regexp = new System.Text.RegularExpressions.Regex("\\s\"([^\"]*)\"\\s");
homepath = regexp.Match(res.StatusDescription).Groups[1].Value;

res.Close();
...