Подтвердить что ты не робот

Загрузка файла FTP с помощью HTTP-прокси

Есть ли способ загрузить файл на FTP-сервер за HTTP-прокси?

Кажется, загрузка файла не поддерживается за HTTP-прокси с использованием .Net Webclient. (http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.proxy.aspx).

Если нет обходного пути? Если нет, знаете ли вы хорошую и бесплатную библиотеку FTP, которую я могу использовать?

Изменить. К сожалению, у меня нет FTP-прокси для подключения.

4b9b3361

Ответ 1

В активном режиме FTP сервер инициирует подключение к клиенту данных. Если клиент находится за прокси-сервером HTTP, это явно не сработает. В пассивном режиме FTP клиент инициирует как начальное, так и подключение к данным. Поскольку HTTP-прокси могут туннелировать произвольные исходящие TCP-соединения (используя метод CONNECT), должно быть возможно получить доступ к FTP-серверу в пассивном режиме через HTTP-прокси.

FtpWebRequest, похоже, поддерживает пассивный режим. Однако я не понимаю, почему поддерживаются файлы и списки файлов, а загрузка файлов, которые также используют одно и то же подключение к данным, - это не.

Вы подтвердили, что FtpWebRequest, настроенный для пассивного режима, не работает через прокси-сервер HTTP, через который список каталогов/загрузка файлов работает нормально?

Ответ 2

большинство FTP-прокси-серверов делают свое дело в соединении, поэтому, если у вас нет прокси-сервера, вы делаете это:

  • сервер: myftpserver.com
  • пользователь: me
  • пароль: pwd

используя FTP-прокси, выполните следующие действия:

  • сервер: ftpproxy.mydomain.com
  • пользователь: [email protected]
  • пароль: pwd

и он просто работает оттуда. Я использую это ПРАВОЕ ЭТО ВТОРОЕ (пытается отладить что-то) через прокси-сервер squid.

... но поскольку у вас нет FTP-прокси....

У вас есть прокси-сервер SOCKS? Это может сработать, но я не знаю, сможет ли .NET это сделать. В противном случае, если честно, я думаю, что вы застряли! FTP - это "нечетный" протокол по сравнению с HTTP, поскольку он имеет канал управления (порт 21) и канал данных (или более одного, на случайном порту), поэтому переход через прокси-сервер - это... весело скажем меньше!

Ответ 3

Наш Rebex FTP/SSL может использовать HTTP-прокси. Это не бесплатно, хотя...

// initialize FTP client 
Ftp client = new Ftp();

// setup proxy details  
client.Proxy.ProxyType = FtpProxyType.HttpConnect;
client.Proxy.Host = proxyHostname;
client.Proxy.Port = proxyPort;

// add proxy username and password when needed 
client.Proxy.UserName = proxyUsername;
client.Proxy.Password = proxyPassword;

// connect, login 
client.Connect(hostname, port);
client.Login(username, password);

// do some work 
// ... 

// disconnect 
client.Disconnect();

Ответ 4

Одним из решений является попытка реализации Mono FtpWebRequest. Я посмотрел на его исходный код, и кажется, что его легко будет модифицировать, чтобы все соединения (управление и данные) туннелировались через HTTP-прокси.

Вы устанавливаете TCP-соединение с вашим HTTP-прокси вместо реального FTP-сервера. Затем вы отправляете CONNECT myserver:21 HTTP/1.0, а затем два CRLF (CRLF =\r\n). Если прокси-сервер нуждается в аутентификации, вам необходимо использовать HTTP/1.1, а также отправить прокси-аутентификационный заголовок с учетными данными. Затем вам нужно прочитать первую строку ответа. Если он начинается с "HTTP/1.0 200 " или "HTTP/1.1 200 ", вы (остальная часть кода) можете продолжать использовать соединение, как если бы оно напрямую подключалось к FTP-серверу.

Ответ 5

В .NET Framework 4.6.3 FtpWebRequest все еще не может загружать файлы через HTTP-прокси.

Если указанный прокси-сервер является прокси-сервером HTTP, поддерживаются только команды DownloadFile, ListDirectory и ListDirectoryDetails.

Итак, либо вам нужно реализовать загрузку самостоятельно, либо использовать стороннюю FTP-библиотеку.


Например, сборка WinSCP.NET, вы можете использовать:

// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Ftp,
    HostName = "example.com",
    UserName = "user",
    Password = "mypassword",
};

// Configure proxy
sessionOptions.AddRawSettings("ProxyMethod", "3");
sessionOptions.AddRawSettings("ProxyHost", "proxy");

using (Session session = new Session())
{
    // Connect
    session.Open(sessionOptions);

    // Upload file
    string localFilePath = @"C:\path\file.txt";
    string pathUpload = "/file.txt";
    session.PutFiles(localFilePath, pathUpload).Check();
}

Для параметров tje SessionOptions.AddRawSettings см. raw настройки.

Легче иметь WinSCP GUI генерировать код кода FTP С# для вас.

Обратите внимание, что сборка WinSCP.NET не является родной библиотекой .NET. Это скорее тонкая .NET-оболочка поверх консольного приложения.

(Я автор WinSCP)

Ответ 6

Если у вас есть способ загрузить файл через FTP без С#, то он также должен быть возможен в С#. Работает ли загрузка через браузер или FTP-клиент?

Одна FTP-библиотека, которая мне больше всего нравится, .NET FTP Client library.

Ответ 7

Как говорит Александр, HTTP-прокси могут проксировать произвольный трафик. Вам нужен FTP-клиент, который поддерживает использование HTTP-прокси. Александр также прав, что это будет работать только в пассивном режиме.

Мой работодатель продает такой FTP-клиент, но это инструмент уровня предприятия, который входит только в очень большую систему.

Я уверен, что есть другие, которые будут лучше соответствовать вашим потребностям.

Ответ 8

Стандартный способ загрузки контента в URL-адрес ftp://через HTTP-прокси будет использовать запрос HTTP PUT. Прокси-сервер HTTP действует как HTTP ↔ FTP-шлюз при работе с URL-адресами ftp://, передавая HTTP-запрос запрашивающему клиенту и FTP на запрошенный FTP-сервер.

По крайней мере, HTTP-прокси Squid поддерживает PUT для URL ftp://, не уверен, что делают другие прокси.

Более распространенным способом является злоупотребление методом CONNECT для использования туннелей над прокси-сервером. Но это часто не допускается из-за последствий для безопасности использования двунаправленных туннелей над прокси-сервером.

Ответ 9

Привет, у меня была такая же проблема - разрешение было создать прокси-объект и получить значения по умолчанию - это должно быть хорошо, если ваше приложение запущено с учетной записью сети -

FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));

System.Net.WebProxy proxy = System.Net.WebProxy.GetDefaultProxy();
proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;

// set the ftpWebRequest proxy
reqFTP.Proxy = proxy;

Это разрешило проблему для меня.

Ответ 10

Прокляните эти несвободные приложения и компоненты!!! Вот мой код с открытым кодом С#, который может загружать файл на FTP через HTTP-прокси.

        public bool UploadFile(string localFilePath, string remoteDirectory)
    {
        var fileName = Path.GetFileName(localFilePath);
        string content;
        using (var reader = new StreamReader(localFilePath))
            content = reader.ReadToEnd();

        var proxyAuthB64Str = Convert.ToBase64String(Encoding.ASCII.GetBytes(_proxyUserName + ":" + _proxyPassword));
        var sendStr = "PUT ftp://" + _ftpLogin + ":" + _ftpPassword
            + "@" + _ftpHost + remoteDirectory + fileName + " HTTP/1.1\n"
            + "Host: " + _ftpHost + "\n"
            + "User-Agent: Mozilla/4.0 (compatible; Eradicator; dotNetClient)\n" + "Proxy-Authorization: Basic " + proxyAuthB64Str + "\n"
            + "Content-Type: application/octet-stream\n"
            + "Content-Length: " + content.Length + "\n"
            + "Connection: close\n\n" + content;

        var sendBytes = Encoding.ASCII.GetBytes(sendStr);

        using (var proxySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            proxySocket.Connect(_proxyHost, _proxyPort);
            if (!proxySocket.Connected)
                throw new SocketException();
            proxySocket.Send(sendBytes);

            const int recvSize = 65536;
            var recvBytes = new byte[recvSize];
            proxySocket.Receive(recvBytes, recvSize, SocketFlags.Partial);

            var responseFirstLine = new string(Encoding.ASCII.GetChars(recvBytes)).Split("\n".ToCharArray()).Take(1).ElementAt(0);
            var httpResponseCode = Regex.Replace(responseFirstLine, @"HTTP/1\.\d (\d+) (\w+)", "$1");
            var httpResponseDescription = Regex.Replace(responseFirstLine, @"HTTP/1\.\d (\d+) (\w+)", "$2");
            return httpResponseCode.StartsWith("2");
        }
        return false;
    }

Ответ 11

У меня была такая же проблема.

Моя основная цель - загрузить файл в ftp. И мне было все равно, будет ли мой трафик проходить через прокси-сервер или нет.

Итак, я просто установил свойство FTPWebRequest.Proxy равным null сразу после FTPWebRequest.Create(uri).

И это сработало. Да, я знаю, что это решение не самое большое. И больше того, я не понимаю, почему это сработало. Во всяком случае, цель завершена.

Ответ 12

Я не уверен, что все HTTP-прокси работают одинаково, но мне удалось обмануть наш, просто создав HTTP-запрос для доступа к ресурсу на URI ftp://user:[email protected]/path.

К сожалению, для создания экземпляра HttpWebRequest вы должны использовать WebRequest.Create. И если вы это сделаете, вы не сможете создать HTTP-запрос для схемы ftp://.

Итак, я использовал немного рефлексии для вызова непубличного конструктора, который делает это:

var ctor = typeof(HttpWebRequest).GetConstructor(
    BindingFlags.NonPublic | BindingFlags.Instance, 
    null, 
    new Type[] { typeof(Uri), typeof(ServicePoint) }, 
    null);
var req = (WebRequest)ctor.Invoke(new object[] { new Uri("ftp://user:[email protected]/test.txt"), null });
req.Proxy = new WebProxy("myproxy", 8080);
req.Method = WebRequestMethods.Http.Put;

using (var inStream = req.GetRequestStream())
{
    var buffer = Encoding.ASCII.GetBytes("test upload");
    inStream.Write(buffer, 0, buffer.Length);
}

using (req.GetResponse())
{
}

Вы также можете использовать другие методы, такие как "УДАЛИТЬ" для других задач.

В моем случае это работало как шарм.

Ответ 13

Id действительно не видит связи между прокси-сервером http и загрузкой на ftp-сервер. Если вы используете HTTP-прокси-класс для доступа к http-ресурсам через прокси-сервер http. ftp - другой протокол, а прокси ftp используют другой протокол.