Is it possible to do "Active" mode FTP using FtpWebRequest? - c#

Due to some firewall issues, we need to do FTP using "active" mode (i.e. not by initiating a PASV command).
Currently, we're using code along the lines of:
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
// Copy the contents of the file to the request stream.
StreamReader sourceStream = new StreamReader("testfile.txt");
byte [] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
But this seems to default to using passive mode; Can we influence this to force it to upload using active mode (in the same way that the command line ftp client does)?

Yes, set the UsePassive property to false.
request.UsePassive = false;

Related

How to Transfer the .xls file to other FTP Path using C#

I am new to the C#, I need to transfer .xlx file from specified location to FTP path (\ServerHostName\ExtractedFile). using C# code, Could you please help me
The MSDN page for FtpWebRequest contains a few examples dealing with FTP in C# & .NET. One of the examples is exactly what you would like to do, uploading a file. This example is asynchronous.
https://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest(v=vs.110).aspx
On another page, there is a simpler example:
https://msdn.microsoft.com/en-us/library/ms229715(v=vs.110).aspx
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestGetExample
{
public static void Main ()
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
// Copy the contents of the file to the request stream.
StreamReader sourceStream = new StreamReader("testfile.txt");
byte [] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();
}
}
}
}

Too many automatic redirections were attempted (even CookieContainer fail)

c# code:
ASCIIEncoding encoding = new ASCIIEncoding();
CookieContainer cook = new CookieContainer();
byte[] data = encoding.GetBytes(postData);
HttpWebRequest myRequest =(HttpWebRequest)WebRequest.Create("http://website.com/index.php");
myRequest.Method = "POST";
myRequest.ContentType = "application/x-www-form-urlencoded";
//myRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
myRequest.ContentLength = data.Length;
Stream newStream = myRequest.GetRequestStream();
newStream.Write(data, 0, data.Length);
newStream.Close();
//myRequest.AllowAutoRedirect = false;
myRequest.CookieContainer = new CookieContainer();
WebResponse response = myRequest.GetResponse();
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
newStream = response.GetResponseStream();
StreamReader reader = new StreamReader(newStream);
Console.WriteLine(reader.ReadToEnd());
index.php
$num= $_POST["num"];
echo $num;
the above code work for me before but suddenly it fail. I tried everything
adding CookieContainer(), setting Redirection to false, using other code for httprequest.
If I AllowAutoRedirect set to false the result would be:
302 Found
Found
The document has moved here
But when i tried this to other web-hosting server it works. So i was thinking its on my WHM/cPanel? Also i have already white-listed my Ip. Already check .htaccess and the options in my cpanelb(redirection).
So any ideas what might cause this?
note: i have already disable'd cloud flare protection
Already Found the solution. It was when they updated my WHM and some Rule was added in ModSecurity Tool that I was not aware off. I just disable that and everything was back to normal :)

FTP stream request stream issue

The error I am getting is web exception. The requested URI is invalid for this FTP command.
I am unsure as how to fix it. Anyone got any idea's? Thanks
private void SendFile(FileInfo file)
{
Console.WriteLine("ftp://" + ipAddressTextField.Text);
// Get the object used to communicate with the server.
string ftp = "ftp://" + ipAddressTextField.Text;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftp);
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential(usernameTextField.Text, passwordTextField.Text);
// Copy the contents of the file to the request stream.
byte[] fileContents = File.ReadAllBytes(file.FullName);
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();
}
Seems you're not setting a destination filename for the upload so the server has no file name to use for the uploaded file.
You could just set it the same as the source file name using something like;
string ftp = "ftp://" + ipAddressTextField.Text + "/" + file.Name;
Console.WriteLine(ftp);
To do a slightly more robust creation of the Uri in case that the file names may have special characters, you could use the Uri class to build it, and pass that in to WebRequest.Create instead.

using ftpWebRequest with an error: the remote server returned error 530 not logged in

I am trying to use the ftpWebRequest in c#
my code is
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://192.168.20.10/file.txt");
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential("dev\ftp", "devftp");
// Copy the contents of the file to the request stream.
StreamReader sourceStream = new StreamReader(#"\file.txt");
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
request.UsePassive = true;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();
and I get an Error in request.GetRequestStream();
the error is: the remote server returned error 530 not logged in
if I try to go in to a browser page and in the url I write ftp://192.168.20.10/
the brows page is asking me for a name and password, I put the same name and password and I see all the files and folders in the ftp folder.
Shouldn't the line:
request.Credentials = new NetworkCredential("dev\ftp", "devftp");
be:
request.Credentials = new NetworkCredential("dev\\ftp", "devftp");
or:
request.Credentials = new NetworkCredential(#"dev\ftp", "devftp");
I have to believe this may be causing your issues because the \f is a form feed character.
Faced the same issue, here's my solution:
request.Credentials = new NetworkCredential(
usernameVariable.Normalize(),passwordVariable.Normalize(),domainVariable.Normalize());
Details can be found here
Hope it helps.
I found out that when connecting via .NET/C# to a FTP-server some characters are not "valid". After setting the login credentials to only contain letters and numbers [a-Z0-9] it worked to log in.
Just remove the double quote from username or password because sometimes $ sign in username or password causes problem. Its good to use single quote every time.
If you assume anonymous logon do not set network credentials. this was the root of my problems.

Anyone have sample code for doing a "chunked" HTTP streaming download of one web directly to a upload to a separate web server?

Background - I'm trying to stream an existing webpage to a separate web application, using HttpWebRequest/HttpWebResponse in C#. One issue I'm striking is that I'm trying to set the file upload request content-length using the file download's content-length, HOWEVER the issue seems to be when the source webpage is on a webserver for which the HttpWebResponse doesn't provide a content length.
HttpWebRequest downloadRequest = WebRequest.Create(new Uri("downloaduri")) as HttpWebRequest;
using (HttpWebResponse downloadResponse = downloadRequest.GetResponse() as HttpWebResponse)
{
var uploadRequest = (HttpWebRequest) WebRequest.Create(new Uri("uripath"));
uploadRequest.Method = "POST";
uploadRequest.ContentLength = downloadResponse.ContentLength; // ####
QUESTION : How could I update this approach to cater for this case (when the download response doesn't have a content-length set). Would it be to somehow use a MemoryStream perhaps? Any sample code would be appreciated. In particular is there a code sample someone would have that shows how to do a "chunked" HTTP download & upload to avoid any issues of the source web server not providing content-length?
Thanks
As I already applied in the Microsoft Forums, there are a couple of options that you have.
However, this is how I would do it with a MemoryStream:
HttpWebRequest downloadRequest = WebRequest.Create(new Uri("downloaduri")) as HttpWebRequest;
byte [] buffer = new byte[4096];
using (MemoryStream ms = new MemoryStream())
using (HttpWebResponse downloadResponse = downloadRequest.GetResponse() as HttpWebResponse)
{
Stream respStream = downloadResponse.GetResponseStream();
int read = respStream.Read(buffer, 0, buffer.Length);
while(read > 0)
{
ms.Write(buffer, 0, read);
read = respStream.Read(buffer, 0, buffer.Length);
}
// get the data of the stream
byte [] uploadData = ms.ToArray();
var uploadRequest = (HttpWebRequest) WebRequest.Create(new Uri("uripath"));
uploadRequest.Method = "POST";
uploadRequest.ContentLength = uploadData.Length;
// you know what to do after this....
}
Also, note that you really don't need to worry about knowing the value for ContentLength a priori. As you have guessed, you could have set SendChunked to true on uploadRequest, and then just copied from the download stream into the upload stream. Or, you can just do the copy without setting chunked, and HttpWebRequest (as far as I know) will buffer the data internally (make sure AllowWriteStreamBuffering is set to true on uploadrequest) and figure out the content length and send the request.

Categories