"Hostname could not be parsed" From "ftp" URL - c#

I just purchased some online storage from GoDaddy and I an trying to FTP into my storage account. The thing is, I can view and modify my account using FileZilla, but my C Sharp program will not even access it because of the "hostname could not be parsed" error.
I believe it is because the entire ftp address of my account has two "#" signs in the url, and it is the wreaking havoc in the URI creation process.
Is there anyway I can get around this, or am I screwed because of the naming convention of the GoDaddy storage?
The URL is: ftp:[slashslash]lastname.firstname#gmail.com#onlinefilefolder.com/Home/

Do you need to specify the username and password in the URI for some specific reason? You can simply connect to the host and then provide credentials.
// Create a request to the host
var request = (FtpWebRequest)WebRequest.Create("ftp://onlinefilefolder.com");
// Set the username and password to use
request.Credentials = new NetworkCredential ("lastname.firstname#gmail.com","password");
request.Method = WebRequestMethods.Ftp.UploadFile;
var sourceStream = new StreamReader("testfile.txt");
var 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();

The exception is originating from System.Uri, which (despite it being acceptable by the standards definition) will not allow two # symbols.
// This will reproduce the reported exception, I assume it is what your code is
// doing either explicitly, or somewhere internally
new Uri(#"ftp://lastname.firstname#gmail.com#onlinefilefolder.com/Home/")
A potential workaround is to percent-encode the first # symbol, which will allow the Uri instance to be instantiated without exception--but may or may not work depending on the server's behavior (I have only used this approach a couple times, but it has worked for me):
new Uri(#"ftp://lastname.firstname%40gmail.com#onlinefilefolder.com/Home/")

Related

Upload to FTP, not using anonymous C#

I used the following example code to upload to an FTP, it turns out that the server don't want to use anonymous connection, but I can't figure out how to change it to be able to upload with out breaking that rule.
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/" + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential("username", "password");
// Copy the contents of the file to the request stream.
byte[] fileContents;
using (StreamReader sourceStream = new StreamReader(file))
{
fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
}
request.ContentLength = fileContents.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileContents, 0, fileContents.Length);
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
}
Anonymous credentials are still credentials. You can get rid of them by removing the line
request.Credentials = new NetworkCredential("username", "password");
and you won't be sending any credentials to the server at all.
Nevertheless, as mentioned in "Remarks" section of the MSDN docs, FtpWebRequest class is not recommended to be used for new development. Microsoft recommends to use one of third-party libraries listed here.
I also recommend choosing one of those, as they provide more robust way to communicate with FTP servers. You can enable logging and it will be easier for you to see why exactly your communication with the server is failing. You will see all the commands your app is sending to the server and also all the responses from the server. These libraries also implement all the basic operations like listing, downloading, uploading, permission setting, sync/async etc, so you don't have to write them yourself.

Can not Access a URL using Webrequest

I am trying to get access a URL using .Net but when I run my Program I get the Error The remote server returned an error: (403) Forbidden. Now, the issue is if I click the link http://thisIsMyUR, and enter the user name and password as in the below code. It totally works. I am not able to understand why this exception is coming? Please refer the code below.
Side Note: I am using this sample function below to fire Build of my project in Jenkins Server.
string url = "http://thisIsMyURL";
WebRequest webRequest = WebRequest.Create(url);
webRequest.Credentials = new NetworkCredential("admin", "pass");
WebResponse response = webRequest.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseText = reader.ReadToEnd();
Other than what was recommended by Bradley Uffner in the comments, you can try to provide an actual user agent during the request. I have seen certain servers which would not respond to requests without that header for some odd perceived security reason.
EDIT: as requested, i'll update with some more information.
Some servers may choose to ignore requests, giving some error code (or closing connection) when certain conditions are not met. A good way of checking if that is the case, is to actually send all the standard headers sent by your average web browser in the request. The "User agent" is one of those headers, and this example adds it to your request:
string url = "http://thisIsMyURL";
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.UserAgent = "USER AGENT VALUE";
HttpWebRequest.Credentials = new NetworkCredential("admin", "pass");
WebResponse response = webRequest.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseText = reader.ReadToEnd();
The cast to HttpWebRequest is required so you have access to the UserAgent header field. Other standard HTTP fields can be accessed this way.
You can check which headers are sent by your browser of choice by inspecting its requests using the browser developer tools (usually Right click on webpage -> Inspect elements -> Network).
I figured it out with the help of some articles. A basic authentication needs to be added. Below is a sample.
var userName = "admin;"
var password = "password";
var encodedAuthentication = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(userName + ":" + password));
webRequest.Headers.Add("Authorization", "Basic " + encodedAuthentication);

Windows Authentication-enabled IIS Site performs differently with 2 different bindings

I have a site set up in IIS 7, and it is using Windows Authentication as the only enabled Authentication Mode. It utilizes a custom .NET 4 Application Pool - the pool uses the default ApplicationPoolIdentity. This site is a C#/ASP.NET application with its own page authorization rules (generated using Iron Speed Designer 9). I have the two bindings set up below:
servicedirectory.sampledomain.com
booking.sampledomain.com
Both of these bindings are mapped to the site on all available IPs on port 80.
For the most part, browsing through either binding works successfully, except for a certain page where I create a WebRequest that fetches another page as a Stream. (I am taking the other page's contents and embedding them as an attachment in an iCal (.ics) file for inclusion in meeting requests. The file is downloaded and sent out by the user)
String request = Request.Url.GetLeftPart(UriPartial.Path).
Replace("Conference.aspx", "Confirmation.aspx") +
"?Conference=" + conference.ConferenceId;
WebRequest webRequest = WebRequest.Create(request);
webRequest.UseDefaultCredentials = true;
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
Stream newStream = webRequest.GetRequestStream();
// Send the data.
newStream.Close();
WebResponse webResponse = webRequest.GetResponse();
Stream responseStream = webResponse.GetResponseStream();
using (MemoryStream ms = new MemoryStream())
{
responseStream.CopyTo(ms);
attachmentContent = Convert.ToBase64String(ms.ToArray());
}
responseStream.Close();
The problem is the following: this code succeeds and produces the content from the Confirmation.aspx page as String data (attachmentContent variable) when the user is browsing under the first binding (servicedirectory.sampledomain.com). However, I get a 401.1 error at the WebResponse webResponse = webRequest.GetResponse(); line when browsing via the other binding URL. There are no references in the application source code or web.config to either binding - everything was built with the intention of being deployed to any URL.
Why would two different bindings affect this?

Secure HttpWebRequest so I can send credentials possible?

I have the following code which connects to my php server and retrieves data from it. The only thing is, I need to send the username and password securely from this webrequest to the PHP server. Looking at the docs for the webrequest class, there is a credentials property as well as a preauthenticate property. I'm assuming these are for the network credentials (all my users are in AD).
Is it possible to secure this post request with credentials or is this just a bad idea? I've also found SetBasicAuthHeader - I'll read up on this and see if it might help. All traffic will be on SSL from ASPX site to the PHP site
// variables to store parameter values
string url = "https://myphpserver.php";
// creates the post data for the POST request
string postData = "Username=" + username + "&Password=" + "&UID=" + UniqueRecID;
// create the POST request
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = postData.Length;
// POST the data
using (StreamWriter requestWriter2 = new StreamWriter(webRequest.GetRequestStream()))
{
requestWriter2.Write(postData);
}
// This actually does the request and gets the response back
HttpWebResponse resp = (HttpWebResponse)webRequest.GetResponse();
string responseData = string.Empty;
using (StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream()))
{
// dumps the HTML from the response into a string variable
responseData = responseReader.ReadToEnd();
}
SetBasicAuthHeader is for HTTP Basic Access Authentication so won't help here as you're handling authentication at application level. Really, this is no more insecure than just going to the page in a browser. I see you're using SSL so your request will be encrypted anyway and you have nothing to worry about.
If you're concerned for some other reason (although I can't think why), it sounds like you have control over the PHP end so you could just encrypt the password and add an extra POST parameter so the server knows to decrypt it.
When using HTTPS your data is safe in the message and transport scope. It means no one can decode it or sniff the packets. I suggest you read this article HTTPS Wiki

Difficulty with BugzScout.net from behind a proxy

I'm attempting to use Fogbugz's BugzScout in order to automatically submit unhanded application exceptions to my Fogbugz on demand Account. I've written up a wrapper class for it and everything appears to be just groovy - on my box. Testing the same code in the production environment, behind a Proxy that requires authentication, I have had nothing but issues.
I went to work modifying the BugzScout code in order to get it to authenticate with the Proxy, and after trying many different methods suggested via a Google search, found one that works! But now I'm getting an "Connection actively refused" error from Fogbugz itself, and I don't know what to do.
Here is the code where the BugzScout connects via a .net WebClient to submit a new case, with my modifications to deal with our Proxy. What am I doing that would cause Fogbugz to refuse my request? I've removed all non web-client related code from the procedure for ease of reading.
public string Submit(){
WebClient client = new WebClient();
WebProxy proxy = new WebProxy();
proxy.UseDefaultCredentials = true;
client.Proxy = proxy;
Byte[] response = client.DownloadData(fogBugzUrl);
string responseText = System.Text.Encoding.UTF8.GetString(response);
return (responseText == "") ? this.defaultMsg : responseText;
}
The url is correct and the case is filled in properly- this has been verified.
EDIT: Additional info.
Using Fogbugz on Demand.
Using FogBugz.net code in it's entirety, with only these additions
WebProxy proxy = new WebProxy();
proxy.UseDefaultCredentials = true;
client.Proxy = proxy;
Error occurs when attempting to connect to both https://oursite.fogbugz.com/scoutsubmit.asp and http://oursite.fogbugz.com//scoutsubmit.asp (except one says port 443, and the other port 80, obviously)
I don't know anything about web authentication so I can't tell you what kind I'm using- if you tell me where to look I'd be happy to answer that for you.
Got the fix from Fogbugz- this is the appropriate network code to get though the proxy authentication and not mis-authenticate with Bugzscout.
WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultNetworkCredentials;
WebRequest request = WebRequest.Create(fogBugzUrl);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
Is your fogbugzUrl using HTTP Basic Authentication? Is it SSL (hosted on On Demand?)
The connection actively refused message would be coming from the web server itself, not really FogBugz.
Can you post the HTTP Status Code?
One thing to note if you are using FogBugz On Demand is you HAVE to use the https:// url (not the http url).

Categories