Web client upload will happen, Where? - c#

I've written a simple code. I don't understand, what happens here. Please explain to me, where will I find a given upload file
WebClient client = new WebClient();
string uri = "http://localhost:8080/sample.txt";
client.Credentials = CredentialCache.DefaultCredentials;
string Filename = "F:\sample_test.txt/docx;
byte[] arrReturn = client.UploadFile(uri, "POST", Filename);

Well, to start with this clearly isn't your real code, as this line won't compile:
string Filename = "F:\sample_test.txt/docx/";
\s isn't a valid escape sequence However, assuming you had working code, what will happen is that your application would make an HTTP POST request with the contents of the file, to the given URI - in this case http://localhost:8080/sample.txt. It's entirely up to the server what it does with the request.
It could save the file on disk somewhere
It could save it to a database
It could post it to another web service
It could completely ignore the contents, and not save it anywhere
Nothing is guaranteed by the act of uploading the file - you're just making a request with some data.
Now if your URI really involves localhost, then it's uploading the file to the computer you're on - so you should be in control of what the web server listening on port 8080 is going to do with upload requests. Again, we can't tell you what it will do - it's up to the server.

It might be your filename:
string Filename = "F:\sample_test.txt/docx/";
Change the forward slashes to blackslashes, and give an actual filename as well, not just the path:
string Filename = #"F:\sample_test.txt\docx\";
Or
string Filename = "F:\\sample_test.txt\\docx\\";
Actually, the filename as is doesn't make much sense - I'm not sure how UploadFile would process it, even with the slashes going the correct way, as you appear to have a filename followed by a directory...? Shouldn't it actually be:
string Filename = #"F:\docx\sample_test.txt"?
It could be the URI - you're specifying the filename as well as the URI.
Did you look at the location specified in the URI? http://localhost:8080/?
If it's not there, then try wrapping your code in a try-catch block to see if any exceptions are thrown:
try
{
byte[] arrReturn = client.UploadFile(uri, "POST", Filename);
}
catch (Exception ex)
{
// do something here - in the debugger, you can inspect ex.Message to see the exception
}

Related

Allowing full file path in URI for Web API call

I am currently working on a 'download file' implementation using Web API 2.
However, as the files that can be downloaded are NOT stored in the database, I am passing in the full file path as the parameter for identification.
It seems the problem with this approach is that the filePath contains characters that are invalid for a URI... Has anyone got any suggestions to resolve this or an alternate approach?
Download file method:
[HttpGet]
[Route("Files/{*filePath}")]
public HttpResponseMessage Get([FromUri]string filePath)
{
try
{
var file = new FileInfo(filePath);
byte[] bytes = System.IO.File.ReadAllBytes(filePath);
var result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new ByteArrayContent(bytes);
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = file.Name + file.Extension;
return result;
}
catch(Exception ex)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, ex);
}
}
Requiring the client to put the full path in the URI (even if it were encoded so that it only contains valid characters for the URI) implies that you may be publishing these paths somewhere... this is not a great idea for a few reasons:
Security - full Path Disclosure and associated Relative Path Traversal
i.e. what's to stop someone passing in the path to a sensitive file (e.g. your web.config file) and potentially obtaining information that could assist with attacking your system?
Maintainability
Clients may maintain a copy of a URI for reuse or distribution - what happens if the file paths change? Some related conversation on this topic here: Cool URIs don't change
My suggestion - you don't have to put the files themselves in a database, but put a list of files in a database, and use a unique identifier in the URL (e.g. perhaps a slug or GUID). Look up the identifier in the database to discover the path, then return that file.
This ensures:
Nobody can read a file that you haven't indexed and determined is safe to be downloaded
If you move the files you can update the database and client URIs will not change
And to respond to your original question, you can easily ensure the unique identifier is only made up of URI safe characters
Once you have the database, over time you may also fine it useful to maintain other metadata in the database such as who uploaded the file, when, who downloaded it, and when, etc.

Error when downloading the file C#

My code:
string dir = "/Users/valeria/Desktop/screening/"+cell;
string remoteUri ="http://www.broadinstitute.org%2Fcmap%2FviewScan.jsp%3Ftype%3DCEL%26scan%3D"+p;
string pFileName = dir + "/p";
using (WebClient myWebClient = new WebClient())
{
myWebClient.DownloadFile(remoteUri, pFileName);
}
My program creates a file pFileName, but doesn't download anything because I get the following exception:
Unhandled Exception: System.Net.WebException: Could not find a part of
the path
"/Users/valeria/Projects/screening/screening/bin/Debug/http:/www.broadinstitute.org/cmap/viewScan.jsp?type=CEL&scan=EC2003090503AA".
---> System.IO.DirectoryNotFoundException: Could not find a part of the path
"/Users/valeria/Projects/screening/screening/bin/Debug/http:/www.broadinstitute.org/cmap/viewScan.jsp?type=CEL&scan=EC2003090503AA"
What's wrong?
The escaped URI certainly isn't helping. URL-encoding is generally only used when the item you are encoding is being appended to a URL; encoding the URL itself is unnecessary and can lead to other problems.
I would strongly suggest changing
string remoteUri="http://www.broadinstitute.org%2Fcmap%2FviewScan.jsp%3Ftype%3DCEL%26scan%3D"+p;
to
string remoteUri ="http://www.broadinstitute.org/cmap/viewScan.jsp?type=CEL&scan="+p;
and re-trying.
The variable cell is - as pointed out by Adrian Wragg - wrong.
Your error already indicates your problem (the bold part is what's in your cell-variable)
"/Users/valeria/Projects/screening/screening/bin/Debug/http:/www.broadinstitute.org/cmap/viewScan.jsp?type=CEL&scan=EC2003090503AA"
So make sure you provide a valid path.
If you don't believe me, you can check your filepath like this:
If (!System.IO.Directory.Exists(dir))
{
Stop; //<== if it hits here, we are right. ;-)
}
There are two problems with your code:
1: You are using encoded Uri, so you have to decode your Uri using System.Web.HttpUtility:
string decodedUri = HttpUtility.UrlDecode(remoteUri);
Then, you will get proper Uri:
http://www.broadinstitute.org/cmap/viewScan.jsp?type=CEL&scan=EC2003090503AA
Which you should pass to myWebClient:
myWebClient.DownloadFile(decodedUri, pFileName);
2: Your cell variable points to url, so you have to fix it. You can assign it as string.Empty or remove it temporary to see if that solution works.

downloading file from FTP server: the given path's format is not supported

I have written this code to download file from FTP server but it shows error message that The given path's format is not supported.
WebClient web = new WebClient();
byte[] filedata = web.DownloadData("ftp://localhost/images/"
+ "/" + "aaaasa.txt");
FileStream file = File.Create("ftp://localhost/images/"+"/"+"aaaasa.txt");
file.Write(filedata, 0, filedata.Length);
file.Close();
Double slashes in your urls look suspicious.
e.g.:
"ftp://localhost/images/"+"/"+"aaaasa.txt"
gives
ftp://localhost/images//aaaasa.txt
is that what you meant?
Also File.Create is only meant for local files.
In addition to what the others said about the double slash ("//") in your FTP path, please note that the local file can not contain a protocol:
File.Create("ftp://localhost/images/"+"/"+"aaaasa.txt")
That doesn't work. Please provide a local file name like in the following example:
FileStream file = File.Create(#"C:\Temp\aaaasa.txt");
file.Write(filedata, 0, filedata.Length);
file.Close();
I think, that the problem you have is caused by the fact that the path you given is incorrect due to an "/" too much
what you have written now:
web.DownloadData("ftp://localhost/images/" + "/" + "aaaasa.txt")
it results in "ftp://localhost/images//aaaasa.txt"
if you would remove the + "/" I think you might be fine.
This goes as well for the file.create method.
Get rid of the double slashes. Also, the File class works against local filesystems, which it appears is what you are trying to write the data to. Why do you have the ftp:// in that path?
You have to use FtpWebRequest for this purpose. Follow by link. there are number of useful examples in "Examples" section.

C# Absolute URI removes ".." from URL

I have to upload a file via FTP to ftp://ftp.remoteServer.com
My root directory on remoteServer contains an "upload" and a "download" folder. I need to put my file in the "upload" directory. But on log in, the server automatically puts me in the "download" folder.
I tried doing this:
string serverTarget = "ftp://ftp.remoteServer.com/";
serverTarget += "../upload/myfile.txt";
Uri target = new Uri(serverTarget);
FTPWebRequest ftp = (FTPWebRequest)FtpWebRequest.Create(target);
using(Stream requestStream = ftp.GetRequestStream()) {
// Do upload here
}
This code fails with: (550) File unavailable (e.g., file not found, no access)
I debugged the code, and target.AbsoluteUri returns as ftp://ftp.remoteServer.com/upload instead of ftp://ftp.remoteServer.com/../upload (missing the ..)
If I put ftp://ftp.remoteServer.com/../upload in a browser, I can log in and verify this is the correct place where I want to put my file.
How can I get the FTPWebRequest to go to the correct place?
I believe you can encode the dots as %2E to keep the dots in your URI.
So something like:
string serverTarget = "ftp://ftp.remoteServer.com/%2E%2E/upload/myfile.txt";
Try this:
string serverTarget = "../upload/myfile.txt";
Uri uri = new Uri(serverTarget, UriKind.Relative);
Andy Evans' comment is correct.
Consider the URI: http://ftp.myserver.com/../. The .. means, "take me to the parent of this directory". But there is no parent! So when you derive the absolute URL, you're going to end up with http://ftp.myserver.com/ There is nothing else that the parser can do.
I think the problem is with the configuration of your FTP server. I assume that the directory structure looks something like:
ftproot
upload
download
It looks like the FTP service is automatically logging you to /ftproot/download. That is, the URI ftp.myserver.com gets mapped to /ftproot/download on the local file system. If that's the case, no amount of fiddling with the URI is going to get you anywhere. If the URI root is mapped to the download directory, there is no way you can, using the .. syntax, "go up one level and then down."
Are you able to upload using an FTP client such as Filezilla, or perhaps the Windows FTP command line tool? If so, what are the steps you take to do it? Can you make your code do the same thing?

FTP c# against Solaris 10 server

I am trying this code to download a file from a Windows machine using C# against a Solaris machine and I receive error 550 - File unavailable.
string fileName = FileName();
string remoteUri = "xxxx";
var webClient = new WebClient();
webClient.Proxy = null;
webClient.Credentials = new NetworkCredential(Settings.Default.FtpUser, Settings.Default.FtpPassword);
webClient.BaseAddress = "ftp://"+Settings.Default.FtpHost;
webClient.DownloadFile(remoteUri, fileName);
I have validated that the URI works when using it in the address line of an Internet Explorer.
The URI looks like this
ftp://10.99.137.99/opt/scripts/overnight/test.txt
The actual location after the login on the Unix side is
/opt/scripts/overnight/test.txt
on the Unix side.
I am able to view the file after entering my user and password. What am I doing wrong? What other steps can I take? Is there an easy way to use more manual ftp?
Here's another interesting article with a different answer:
FtpWebRequest Download File
string remoteUri = "xxxx";
Have you posted the actual code? This is the name of the remote file. It needs to be ftp://10.99.137.99/opt/scripts/overnight/test.txt not xxxx
If it isn't the actual code, can you post the code you are really using?

Categories

Resources