C# Uri class - stripping off a port number from Authority - c#

I'm trying tu use System.Uri to strip off various information.
E.g. it gets me Uri.Authority.
When my URI is http://some.domain:52146/something, Uri.Authority.ToString() gives me "some.domain:52146".
I'd rather have "some.domain" and the port with a separate call.
Any ideas whow I could strip off the :port_number stuff most elegantly, either with a Uri-method I don't know of or with some string manipulation?
And getting back the http:// would also be useful (to know for example whether it's http or https).

Use Uri.Host and Uri.Port:
Uri uri = new Uri("http://some.domain:52146/something");
string host = uri.Host; // some.domain
int port = uri.Port; // 52146

Since I learnt about the properties Uri.Host and Uri.Port now I know that Uri.Scheme gives me the protocol.

Related

Parsing URL string into protocol string, server string, and domain string in C#?

I'm still relatively new to C# programming and I'm having trouble parsing a URL string. I would like to take a URL like http://server.example.org and split it into separate strings like protocol, server, and domain name. Here is what my code looks like so far:
string url = "http://server.example.org";
string protocol = url.Substring(0, url.IndexOf(":")); // parse from beginning to colon to get protocol
string server = url.Substring(url.IndexOf("//") + 2, url.IndexOf(".")); // parse from // + 2 to first . for server
string domain = url.Substring(url.IndexOf(".") + 1); // the rest of the string should be the domain
The protocol string correctly shows http and domain correctly shows example.org, but the server string comes out as server.exampl instead of server as expected. What am I doing wrong?
The Uri constructor is capable of parsing a URI. It has a wealth of properties that give you various attributes. However, if you want to split the Host you will need to do it manually
var uri = new Uri("http://server.example.org");
var split = uri.Host.Split('.');
Console.WriteLine(uri.Scheme);
Console.WriteLine(uri.Host);
Console.WriteLine(split[0]);
Console.WriteLine(string.Join(".",split.Skip(1)));
Output
http
server.example.org
server
example.org

How to encode IP for GET request in api in .NET

I'm trying to figure out how to send IP in GET request. I want to call GET request like : /api/endpoint/12.12.12.12. I tried to encode it but HttpUtility.UrlEncode won't encode dots for IP alone. When I try use %2E as dot then IIS throws 404.11 - The request filtering module is configured to deny a request that contains a double escape sequence.. How to I make it the right way?
Try to encode it in base 64. You can find how to do it here
/api/endpoint/MTIuMTIuMTIuMTI=
You could just do a string replace.
"12.12.12.12".Replace(".","%2E");
Add a slash at the end of the URL:
/api/endpoint/12.12.12.12/
this should work

Find URL scheme

I want to check whether the incoming url having http or https in c#? Is there any default method to find the url scheme(http/https)?
You could use Uri.Scheme to check and see if it is https.
You could also just use Request.IsSecureConnection
var currentUrl = System.Web.HttpContext.Current.Request.Url;
if (!currentUrl.Scheme.Equals(Uri.UriSchemeHttps,
StringComparison.CurrentCultureIgnoreCase))
For more information : Uri.UriSchemeHttps Field

Uri Constructor .NET Framework Bug?

Why the thirdRelativeUri fails? Is this a .NET bug? Seems like not fixed in 4.0 either.
var googleU = new Uri("http://www.google.com");
var secondRelativeUri = new Uri(googleU,"//test.htm"); // doesn't fail
var thirdRelativeUri = new Uri(googleU,"///test.htm"); // fails - Invalid URI: The hostname could not be parsed.
UPDATE:
#dariom pointed out that this is because protocol relative URL handling in .NET which make sense however this still seems buggy to me:
var thirdRelativeUri = new Uri("///test.htm",UriKind.Relative); // works as expected
var newUri = new Uri(googleU,thirdRelativeUri); //Fails, same error even though it's a relative URI
It fails even when the second Uri is Relative
The file uri scheme (RFC 1738) file://[host]/path shows that host is optional. ///test.html would mean "Since this usually used for local files the host from RFC 1738 is often empty leading to a starting triple /. (ref)"
Change ///test.htm to file:///test.htm and the URI constructor will parse it properly. It's AbsolutePath will be /test.html.
Hope this helps.
I think that the constructor is interpreting "//test.htm" as a URI with no scheme and a hostname of test.htm. You can see this by examining the value of secondRelativeUri - it's "http://test.htm/".
The third URI you're creating is invalid because you have too many slashes.
new Uri(googleU,"//test.htm") mean Uri = http://test.html/ /* valid, Anyway a root somewhere */
new Uri(googleU,"///test.htm") mean Uri = http:///test.html/ /* invalid, Meaningless */
new Uri("///test.htm",UriKind.Relative); //=> Uri = ///test.htm same mistake, not relative location
var r = new Uri("test.htm",UriKind.Relative);
new Uri(googleU, r); // => Uri = http://www.google.com/test.htm
Even when creating relative URLs, .net treats a string that starts with tow slashes as a host name like in "//example.org/document". Similarly three slahes makes a confusion and an exception is thrown. If you are pretty sure these //test.htm and ///test.htm are paths, then you can try using UriBuilder class.

Why doesn't FTPWebRequest, or WebRequest in general accept a /../ path?

I am trying to automate some upload/download tasks from an ftp web server. When I connect to the server through client, or through Firefox even, in order to get to my directory, I have to specify a path like this:
ftp://ftpserver.com/../AB00000/incoming/files
If I try to access this:
ftp://ftpserver.com/AB00000/incoming/files
The server throws an error that the directory does not exist. So, the problem:
I am trying to create an FTPWebRequest with the first ftp address, but it always parses out the "/../" part and then my server says the path doesn't exist.
I've tried these:
Uri target = new Uri("ftp://ftpserver.com/../AB00000/incoming/files");
FtpWebRequest request = (FtpWebRequest)WebReqeuest.Create(target);
and
string target = "ftp://ftpserver.com/../AB00000/incoming/files";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(target);
In the first bit, the path is already incorrect when the Uri object is instantiated, in the second bit, it's after the WebRequest.Create method. Any ideas what's going on?
EDIT:
Additionally, since I posted this, I have tried creating the URI with the no parse option. I have also tried something like this:
string ftpserver = "ftp://ftpserver.com/../";
string path = "12345/01/01/file.toupload";
Uri = new Uri(ftpserver, path, true);
And it always parses out the root part ("/../").
Try escaping the .. with something like:
Uri target = new Uri("ftp://ftpserver.com/%2E%2E/AB00000/incoming/files");
That works according to this blog which I found in this discussion.
Not really sure about it, but it may be for security reasons, since allowing "/../" URIs would potentially let people navigate freely on any server's file system.
Also, the official URI RFC states that when resolving an URI one of the steps performed is actually the removal of "/../" segments, so it's not a problem in the C# library but it's regular URI behavior.
Have you tried using the # symbol like so?
Uri target = new Uri(#"ftp://ftpserver.com/../AB00000/incoming/files");
FtpWebRequest request = (FtpWebRequest)WebReqeuest.Create(target);

Categories