Call HttpListener from external IP - c#

I have a very simple API in C# for test purposes. The API is created in a Windows Forms project
listener = new HttpListener();
listener.Prefixes.Add(url);
listener.Start();
LogUtils.appendInfo("Listening for connections on: " + url);
//Handle requests
Task listenTask = HandleIncomingConnections();
listenTask.GetAwaiter().GetResult();
If I call http://localhost:8080/ I get response from API.
The problem is that if I call the API from another PC using the external IP address http://ExternalIp:8080/
I get this error:
Bad Request - Invalid Hostname HTTP Error 400. The request hostname is
invalid
What I have tried:
I have put in the firewall a rule for port 8080 in incoming connections.
I have tested with the ISS server that brings Windows Server 2019 off and on.
I have created a 'applicationhost.config 'file in 'C:\Users\myUser\source\repos\myProyect.vs\proyectname\config' for <'binding protocol="http" bindingInformation=":8080:" /> because my project not have applicationhost.config file.

As #PanagiotisKanavos commented I can not use "localhost" in "listener.Prefixes.Add" for external request.
Solved by:
http://*:8080/
And run Visual Studio as administrator.

Related

SignalR app starts, runs on http but not on https: Unexpectedly closed connection

I have a self-hosted SignalR application in a Windows Service built with VS2015 FW 4.6, SignalR 2.3.0. This has been working fine for more than 2 years using ports 6286 (https) and 6287 (http) and "*" for the IP. I wanted to switch these ports to 80 and 443 respectively and apply a wild-card certificate to 443. Since there are web sites using the certificate on IP 192.168.100.7 I added another IP address (192.168.100.3) to my server applied the certificate with:
netsh http add sslcert ipport=192.168.100.3:443 appid={12345678-db90-4b66-8b01-88f7af2e36bf} certhash=xxxxxxxxxxxxxxxxxxxxxxxxx
I can verify the success with:
netsh http show sslcert ipport=192.168.100.3:443
So I start the WebApps with the following:
SignalR = WebApp.Start("http://192.168.100.3:80/");
SignalRSSL = WebApp.Start("https://192.168.100.3:443/");
They seem to start fine, no errors and if I use http://192.168.100.3/signalr/hubs it works fine. However, https://192.168.100.3:443/signalr/hubs gives the "Unexpectedly closed connection" error.
What have I done wrong, is there something else to set for https?
My error... I was using the internal IP's and corresponding external IP's to test this. What I realized is that the wild-card certificate is not tied to an IP, it's tied to a domain! So, I created an A record for the IP with the wild-card's domain and it worked.
However, I now have a different problem in that it's trying to negotiate with the web server's domain and not the signalR domain to send a message!
https://webserverdomain/signalr/negotiate?clientProtocol=1.5....
I don't know where it's picking the web server's name up but it's different enough that it's probably a topic for another post.

C# HttpListener exception: The format of the specified network name is not valid

I am using this sample code to listen for HTTP requests:
// Create a listener.
HttpListener listener = new HttpListener();
// Add the prefixes.
listener.Prefixes.Add("some URI");
listener.Start();
Console.WriteLine("Listening...");
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
listener.Stop();
But I am having very tough time, because I have no clue what prefix supposed to be. I have read the documentation on this, but whatever I try to enter there, whether it's URI of my computer or t's URI of machine that I am expecting to get response from, I always get exception:
The format of the specified network name is not valid
I tried multiple things, one of them was that I specified URI of my own PC and got exception that these location is unreachable. The more I research the more lost I get.
In the MSDN example on HttpListener I see that URI supposed to have also a port, but if it has to be the URI of external machine I am listening to, then how can I know the port?
Also, I opened ports in firewall (using Windows tools, not commander). I even turned Windows firewall off, but didn't change anything.
My knowledge on networks is very limited, thus I don't even know the exact question I should ask.
I tried hints from related posts, such as:
C# HttpListener The format of the specified network name is not valid
but nothing helped me.
for example use:
listener.Prefixes.Add("http://*:9998/");
listener.Prefixes.Add("https://*:9999/");
If you use * listener will bind to all interfaces. You will need to run as administrator for it to register.
Now if you run this program on host which has a configured IP for example 192.168.178.39
You should connect using:
http://192.168.178.39:9998
https://192.168.178.39:9999
for SSL to work you will need to use the following command:
netsh http add sslcert ipport=0.0.0.0:9999 certhash=Thumbprint appid={GUID}
In the MSDN example on HttpListener I see that URI supposed to have
also a port, but if it has to be the URI of external machine I am
listening to, then how can I know the port?
In that case you should use the default port http 80 or https 443. You will need to use a local IP though on the machine for the prefix do NOT specify the external IP.
If the network has NAT then configure the firewall to allow traffic on port 443 and 80 to desired host.
Now you can connect using external ip and default ports.

Azure connection failed because connected host has failed to respond ip:443

So I implemented an interface to communicate with a rest web service using the HttpClient class to make requests.
The code works perfectly locally, but when I deploy to Azure my application can't fire the request, it crashes on this line:
using (var response = await HttpClient.PostAsync(uri, content)) { ... }
// uri = https://api-rest.zenvia360.com.br/services/send-sms
The exact exception message is this:
A connection attempt failed because the connected party did not properly
respond after a period of time, or established connection failed because
connected host has failed to respond 200.203.125.26:443
The web service provider states that "if you use firewall or proxy you must add and exception for our IPs. For HTTPS, use port 443:
200.203.125.24
200.203.125.25
200.203.125.26 (the ip of the exception message)
200.203.125.27
200.203.125.28
200.203.125.29"
I looked everywhere in Azure looking for a firewall or something and I got nothing. Also this exception message is pretty cryptc. I tested the same code with another url (fired a post to www.gooogle.com) and it worked.
Any ideas?
The problem turned out to be on the web service side. The service I'm using blocks international requests by default. I asked them to whitelist the azure outbound IPs and now it works.

HttpListener with SSL support not getting any connections from remote computer

I am trying to create a simple web server with SSL support. I am trying to use HttpListener for this. This is what I have:
I made a root CA certificate and stored it in the Trusted Root Certification Authorities store
I derived a certificate for server authentication from my root certificate and stored that in the Personal store
I bound the certificate to my application and port with the 'netsh http add sslcert ...'-command.
I also stored my root CA certificate in the Trusted Root Certification Authorites store of another computer.
Here is some code that I used:
private void StartServer()
{
HttpListener server = new HttpListener();
server.Prefixes.Add("http://+:8080/");
server.Prefixes.Add("https://+:8081/");
server.Start();
server.BeginContext(HandleRequestCallback, server);
}
private void (HandleRequestCallback(IAsyncResult ar)
{
HttpListener server = ar.AsyncState as HttpListener;
server.BeginGetContext(HandleRequestCallback, server); // Start listening again.
HttpListenerContext context = server.EndGetContext(ar);
HttpListenerRequest request = context.Request;
ProcessRequest(request);
}
This is what works:
An ordinary http request from the local machine
A secure https request from the local machine (I get a green lock symbol in Chrome)
An ordinary http request from the remote machine
What doesn't work is a secure https request from the remote machine. The connection simply times out. Debugging in VS shows that the HandleRequest method doesn't get hit. Also playing around with Fiddler, I can't see any incoming network traffic in this case.
I have also made a similar solution using TcpListener (and SslStream), and with that, I do get a secure connection from the remote computer. So it is not a firewall issue...
Did someone else encounter this issue? Is there someone who can point me to what I'm missing?

net.tcp no longer works in server 2012

I cannot get server 2012 iis to host net.tcp.
In server 2008R2/VS2012 there is no issues
In server2012/VS2012 when hitting the wdsl I am first receiving "The protocol 'net.tcp' does not have an implementation of HostedTransportConfiguration type registered.", then if I hit refresh I get "An item with the same key has already been added."
The error from the TraceViewer if "service is unable to open its IChannelListener"
But I have set the Bindings on the default website( had to use the command line because it throws an exception if you edit net.tcp in the grid, this is a known issue)
I have set the bindings at the application level to http,net.tcp, created a new AppPool with network service identity, and used findPrivateKey to give it permissions.
I created a new virt of Server 2008R2/VS2012 and had no issues with the above steps.
Edit Additional notes for server 2012
Add Roles and Features:
Verified the following are installed:
Web Sever - Application Development: All checked but CGI and ASP(classic)
.NET Framework 3.5 Features: All checked
Windows Process Activation Service: All checked
IIS: Default Web Site: bindings net.tcp 8081:
IIS: Default Web Site->Advanced Settings->enabled protocols: http,net.tcp
IIS: Default Web Site\Service->Advanced Settings->enabled protocols: http,net.tcp
Is there anything special to do for Server2012?
After a day of searching, finally found it. I guess it another known issue with server2012 & IIS8
http://support.microsoft.com/kb/2803161
Here some tips that you could try:
1-Open a Command Prompt (as administrator) and run:
netstat -ona
Check if your service is listening to your server port.
Example: your endpoint is net.tcp://localhost:8015/MyService. So running the command above, you will see an item:
TCP 127.0.0.1:8015 0.0.0.0 LISTENING
2-If your service is not listening, then create a Console app and self-host your service.
Example:
using System.ServiceModel.ServiceHost;
public class Sample
{
ServiceHost host = new ServiceHost(typeof(MyService));
public static void Main()
{
host.Open();
Console.WriteLine("listening...");
Console.Read();
host.Close();
}
}
3-Repeat the first step and check if your service is listening to the port.

Categories