400 Bad Request (Invalid Host) using simple webserver in C# - c#

I've got a small C# console app to work as a webserver. It responds well on the NAT with devices in the same network, but when I try to access it in a browser from the external IP i get a 400.
The router is configured to port forward, otherwise I get a 404.
localhost:8888/test works fine.
also 192.168.0.x:8888/test for any device.
xxx.xxx.xxx.xxx:8888/test fails with HTTP Error 400. The request hostname is invalid.
Any suggestions?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace httpsrv
{
class Program
{
static void Main(string[] args)
{
WebServer ws = new WebServer(SendResponse, "http://localhost:8888/test/");
ws.Run();
Console.WriteLine("Pi server started");
Console.ReadKey();
ws.Stop();
}
public static string SendResponse(HttpListenerRequest request)
{
return string.Format("<HTML><BODY>Hosted from rasp. pi!<br>{0}</BODY></HTML>", DateTime.Now);
}
}
}
Webserver class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace httpsrv
{
public class WebServer
{
private readonly HttpListener _listener = new HttpListener();
private readonly Func<HttpListenerRequest, string> _responderMethod;
public WebServer(string[] prefixes, Func<HttpListenerRequest, string> method)
{
if (!HttpListener.IsSupported)
throw new NotSupportedException(
"Needs Windows XP SP2, Server 2003 or later.");
if (prefixes == null || prefixes.Length == 0)
throw new ArgumentException("prefixes");
if (method == null)
throw new ArgumentException("method");
foreach (string s in prefixes)
_listener.Prefixes.Add(s);
_responderMethod = method;
_listener.Start();
}
public WebServer(Func<HttpListenerRequest, string> method, params string[] prefixes)
: this(prefixes, method) { }
public void Run()
{
ThreadPool.QueueUserWorkItem((o) =>
{
Console.WriteLine("Webserver running...");
try
{
while (_listener.IsListening)
{
ThreadPool.QueueUserWorkItem((c) =>
{
var ctx = c as HttpListenerContext;
try
{
string rstr = _responderMethod(ctx.Request);
byte[] buf = Encoding.UTF8.GetBytes(rstr);
ctx.Response.ContentLength64 = buf.Length;
ctx.Response.OutputStream.Write(buf, 0, buf.Length);
}
catch { }
finally
{
ctx.Response.OutputStream.Close();
}
}, _listener.GetContext());
}
}
catch { }
});
}
public void Stop()
{
_listener.Stop();
_listener.Close();
}
}
}

I had this issue on ubuntu when using self hosted OWIN and c#.
I fixed it by setting the base address set inside my .exe to
http://*:80
instead of
http://192.168.1.1:80

This
WebServer ws = new WebServer(SendResponse, "http://*:80/");
plus starting application (or command prompt / Visual Studio) with 'Run as administrator' mode worked great!

Either your DNS or name resolution is bad.
There are no routes to forward that traffic to your web server
Check your port forwarding you should be forwarding port 8888 to the internal IP
Last but not least check your firewall, it should allow port 8888
Looking at your code, it seems you are hard coding the request, make that a variable so that you can change it on the fly

Had similar issue as #sean-bradley - but on .net.
This worked great:
WebServer ws = new WebServer(SendResponse, "http://+:80/");

Related

Send data to specific client from another client with a server in middle[C#]

I have searched everywhere but couldn't find as they are all answering to send message to all clients. What I want to achieve is multiple clients request to server to request data from another client and other client sends data to server telling it that data is for requesting client and so. I don't know how to achieve this. I'm new to this.
What I want to achieve:
I have tried with Data sending client to listen and requesting client to connect to it and transfer data. I have achieved this on local network but to make it work online it needs port forwarding and my user will be a lot of different people so port forwarding is not possible for every user. So I can rent a server which will act as a center of transfer. I programmed a test server in console which will listen to a server IP:port X and accept new clients and their data on port X and forward it to server IP:port Y but what this does is send data to all clients on port Y. I cannot send it to clients public ip address directly for obvious reasons. I understand that all the requesting clients are connected to port Y but I cannot create and assign new ports to all the clients interacting. So I want a way to determine how to request and receive the data without the need of assigning or creating new ports to different clients on same server.
What I have tried:
Server code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Test___server
{
class server
{
public static string serverIP = "192.168.0.102";
static void Main(string[] args)
{
Thread listenSendingThread = new Thread(listenSending);
listenSendingThread.IsBackground = true;
listenSendingThread.Start();
Thread listenReceivingThread = new Thread(listenReceiving);
listenReceivingThread.IsBackground = true;
listenReceivingThread.Start();
Console.ReadKey();
}
public static List<TcpClient> listSending = new List<TcpClient>();
public static List<TcpClient> listReceiving = new List<TcpClient>();
public static TcpClient clientSending = null;
private static void listenSending()
{
TcpListener listenerSending = new TcpListener(IPAddress.Parse(serverIP), 5319);
listenerSending.Start();
Console.WriteLine("Server listening to " + serverIP + ":5319");
while(true)
{
clientSending = listenerSending.AcceptTcpClient();
listSending.Add(clientSending);
Console.WriteLine("Sender connection received from " + clientSending.Client.RemoteEndPoint);
}
}
private static void send()
{
StreamWriter sw = new StreamWriter(clientSending.GetStream());
sw.WriteLine(message);
sw.Flush();
Console.WriteLine("Message sent!");
}
public static string message = string.Empty;
private static void listenReceiving()
{
TcpListener listener = new TcpListener(IPAddress.Parse(serverIP), 0045);
listener.Start();
Console.WriteLine("Server listening to " + serverIP + ":0045");
while (true)
{
TcpClient client = listener.AcceptTcpClient();
listReceiving.Add(client);
Console.WriteLine("Receiver connection received from " + client.Client.RemoteEndPoint);
StreamReader sr = new StreamReader(client.GetStream());
message = sr.ReadLine();
send();
}
}
}
}
Requesting client code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test____admin
{
class admin
{
static void Main(string[] args)
{
Console.WriteLine("Begin");
string serverIP = "192.168.0.102";
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
clientSocket.Connect(serverIP, );
Console.WriteLine("Connected");
while (true)
{
Console.WriteLine("Reading");
StreamReader sr = new StreamReader(clientSocket.GetStream());
Console.WriteLine("Message: " + sr.ReadLine());
}
}
}
}
Request satisfying client code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Test___client
{
class client
{
public static string serverIP = "192.168.0.102";
static void Main(string[] args)
{
clientConnect();
}
private static void clientConnect()
{
try
{
TcpClient client = new TcpClient(serverIP, 0045);
StreamWriter sw = new StreamWriter(client.GetStream());
sw.WriteLine("Karan!");
sw.Flush();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
You are using a very low-level API, and doing it the right way is challenging. Instead, try YARP as a reverse proxy. The requesting client should notify the reverse proxy about the desired destination client. One option is sending the destination client name in the request header. You will also need to split a single server request into multiple client requests, then merge their responses into a single one. You can achieve it by implementing Transphorms.
I'm not sure this approach applies to your situation because clients should implement server API using REST, Grpc or any other supported technology.

Trying titanium web proxy solution

We installed nuget titanium web proxy, created a window service and initiated titanium web proxy. The windows service works, runs, and start and stop times are written to a log file. But the web proxy is supposed to catch internet request and afford them, though no such events happens and nothing is logged, when i open some page with different browsers.
Here is our code:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using Titanium.Web.Proxy;
using Titanium.Web.Proxy.EventArguments;
namespace WebProxy1 {
public partial class MyNewService : ServiceBase {
public ProxyServer proxyServer;
public MyNewService() {
InitializeComponent();
}
protected override void OnStart(string[] args) {
proxyServer = new ProxyServer(true, true, true);
proxyServer.BeforeRequest += OnRequest;
proxyServer.Start();
WriteToFile("Service is started at " + DateTime.Now);
}
protected override void OnStop() {
proxyServer.Stop();
WriteToFile("Service is stopped at " + DateTime.Now);
}
public void WriteToFile(string Message) {
string path = "E:\\Downloads\\Logs";
if (!Directory.Exists(path)) {
Directory.CreateDirectory(path);
}
string filepath = "E:\\Downloads\\Logs\\ServiceLog_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
if (!File.Exists(filepath)) {
// Create a file to write to.
using (StreamWriter sw = File.CreateText(filepath)) {
sw.WriteLine(Message);
}
} else {
using (StreamWriter sw = File.AppendText(filepath)) {
sw.WriteLine(Message);
}
}
}
public async Task OnRequest(object sender, SessionEventArgs e) {
WriteToFile(e.HttpClient.Request.Url);
// To cancel a request with a custom HTML content
// Filter URL
if (e.HttpClient.Request.Method.ToUpper() == "GET" && e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("google.com")) {
e.Ok("<!DOCTYPE html>" +
"<html><body><h1>" +
"Website Blocked" +
"</h1>" +
"<p>Blocked by titanium web proxy.</p>" +
"</body>" +
"</html>");
}
// Redirect example
if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("wikipedia.org")) {
e.Redirect("https://www.paypal.com");
}
}
}
}
I think you did not set the titanium proxy properly.
Before starting the proxy, you have to set endpoint.
There is titanium proxy using example here.
This is my sample source.
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true)
{
// Use self-issued generic certificate on all https requests
// Optimizes performance by not creating a certificate for each https-enabled domain
// Useful when certificate trust is not required by proxy clients
//GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password")
};
// Fired when a CONNECT request is received
explicitEndPoint.BeforeTunnelConnect += OnBeforeTunnelConnect;
// An explicit endpoint is where the client knows about the existence of a proxy
// So client sends request in a proxy friendly manner
proxyServer.AddEndPoint(explicitEndPoint);
proxyServer.Start();

How can i scan and list all connected devices to my network wireless, i'm getting exception?

My pc is connected to the router of the network i want to scan but the not wireless the pc is connected with a cable to the router.
But my android device is connected to the network wireless.
So in logic in this case the results in the list should be my pc and my android device.
This is what i'm using now managed wifi api:
managed wifi api
This is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NativeWifi;
namespace ScanWifi
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
WlanClient client = new WlanClient();
try
{
foreach (WlanClient.WlanInterface wlanIface in client.Interfaces)
{
Wlan.WlanBssEntry[] wlanBssEntries = wlanIface.GetNetworkBssList();
foreach (Wlan.WlanBssEntry network in wlanBssEntries)
{
int rss = network.rssi;
byte[] macAddr = network.dot11Bssid;
string tMac = "";
for (int i = 0; i < macAddr.Length; i++)
{
tMac += macAddr[i].ToString("x2").PadLeft(2, '0').ToUpper();
}
listView1.Items.Add("Found network with SSID {0}." + System.Text.ASCIIEncoding.ASCII.GetString(network.dot11Ssid.SSID).ToString());
listView1.Items.Add("Signal: {0}%."+ network.linkQuality);
listView1.Items.Add("BSS Type: {0}."+ network.dot11BssType);
listView1.Items.Add("MAC: {0}.", tMac);
listView1.Items.Add("RSSID:{0}", rss.ToString());
}
Console.ReadLine();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
When running the program i'm exception on WlanApi.cs on the line:
Wlan.ThrowIfError(
Wlan.WlanOpenHandle(Wlan.WLAN_CLIENT_VERSION_XP_SP2, IntPtr.Zero, out negotiatedVersion, out clientHandle));
System.ComponentModel.Win32Exception' occurred in ManagedWifi.dll
The service has not been started
For Windows 10, the service "WLAN AutoConfig" must be started for WlanClient to work. This service should be started automatically on a computer which has a WiFi adapter present. On a computer such as a desktop which does not have a WiFi adapter, the service startup type is probably Manual and not started; you can start it anyway and WlanClient should no longer throw any exceptions, but without a WiFi adapter, it won't see any interfaces, so you won't be able to get a list of networks.
According to the documentation of the [WlanOpenHandle ][1] function, the problem is that the Wireless Zero Configuration (WZC) service is not started on your machine:
WlanOpenHandle will return an error message if the Wireless Zero Configuration (WZC) service has not been started or if the WZC service is not responsive.
However, depending on your platform, it might also might be the case that you are simply passing the wrong parameters to the WlanOpenHandle function. Have you tried passing Wlan.WLAN_CLIENT_VERSION_LONGHORN as the first parameter?

Cannot authenticate against Apache DS using C# and LdapConnection?

Problem
I installed and configured a ApacheDS server running ldap. This was a huge step forward for me in teaching myself ldap. However, the following C# console code returns the following error:
System.DirectoryServices.Protocols.LdapException {"The supplied credential is invalid"}
My code is to use this sample code to authenticate a sample user.
Code
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SampleLdapAuthentication
{
class Program
{
static void Main(string[] args)
{
RunLdap run = new RunLdap("localhost", "organization", 635, "hderp", "spaceballs1234");
bool result = run.ValidateCredentials();
if(result)
{
Console.WriteLine("Authentication Succeeded");
}
else
{
Console.WriteLine("Authentication Failed");
}
}
}
}
SampleLdapAuthentication.cs
using System;
using System.Collections.Generic;
using System.DirectoryServices.Protocols;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace SampleLdapAuthentication
{
public class RunLdap
{
private static string _domainController;
private static string _domain;
private static int _port;
private static string _userName;
private static string _userPassword;
//Constructor. Takes the domain controller, domain, port, username, and password and then calls Ldap Method to run authentication
public RunLdap(string domainController, string domain, int port, string userName, string userPassword)
{
_domainController = domainController;
_domain = null;
_port = port;
_userName = userName;
_userPassword = userPassword;
}
public bool ValidateCredentials()
{
LdapDirectoryIdentifier ldi = new LdapDirectoryIdentifier(_domainController, _port);
NetworkCredential networkCredential = new NetworkCredential(_userName, _userPassword, _domain);
try
{
//We use using so we dispose the object as soon as it goes out of scope
using (LdapConnection connection = new LdapConnection(ldi))
{
//connection.SessionOptions.SecureSocketLayer = true;
connection.AuthType = AuthType.Kerberos;
connection.Bind(networkCredential);
//Not sure what this is doing
}
return true;
}
catch(LdapException ldapException)
{
return false;
}
return false;
}//End of ValidateCredentials
}
}
LDAP Server Details
Notes
The following are worth noting in what I am doing:
I followed this tutorial in creating the server and DIT.
According to my understanding ApacheDS supports keberos out of the box now, so my authentication type should be fine. That is, AuthType
It fails on connection.Bind() method
I am thinking maybe there is something wrong with how I am entering in the credentials and that my C# code is fine. That is why I included the server AD information. I am new to LDAP and using it to authenticate users, so I appreciate your help.
You're not using the distinguished name of the user. When you create your NetworkCredential object, you should be using the distingushed name of the user, in this case, cn=Herp Derp,ou=users,o=organization instead of hderp. The LDAP doesn't know where to look for hderp without the o and ou values.

How to get Monotorrents DHT to work?

Iam trying to get the dht implementation of monotorrent to work but i just cant seem to find any peers.
ive tried most of the examplecode code availeble on the net like the testclient and dhttest.
I have tried with several diffrent infohashes.
Anyone here got it working? or do you know where i can find the devs?
This is how my code looks atm:
using System;
using System.Collections.Generic;
using System.Text;
using MonoTorrent.Dht;
using MonoTorrent.Dht.Listeners;
using System.Net;
using System.IO;
using MonoTorrent.Common;
using MonoTorrent.Tracker.Listeners;
namespace SampleClient
{
class Program
{
static void Main(string[] args)
{
string basePath = Environment.CurrentDirectory;
string torrentsPath = Path.Combine(basePath, "Torrents");
Torrent torrent = null;
// If the torrentsPath does not exist, we want to create it
if (!Directory.Exists(torrentsPath))
Directory.CreateDirectory(torrentsPath);
// For each file in the torrents path that is a .torrent file, load it into the engine.
foreach (string file in Directory.GetFiles(torrentsPath))
{
if (file.EndsWith(".torrent"))
{
try
{
// Load the .torrent from the file into a Torrent instance
// You can use this to do preprocessing should you need to
torrent = Torrent.Load(file);
Console.WriteLine(torrent.InfoHash.ToString());
}
catch (Exception e)
{
Console.Write("Couldn't decode {0}: ", file);
Console.WriteLine(e.Message);
continue;
}
}
}
DhtListener listener = new DhtListener(new IPEndPoint(IPAddress.Parse("192.168.2.3"), 10000));
DhtEngine engine = new DhtEngine(listener);
//engine.RegisterDht(dht);
byte[] nodes = null;
if (File.Exists("mynodes"))
nodes = File.ReadAllBytes("mynodes");
listener.Start();
int i = 0;
bool running = true;
StringBuilder sb = new StringBuilder(1024);
while (running)
{
engine.Start(nodes);
while (Console.ReadLine() != "q")
{
engine.GetPeers(torrent.InfoHash);
}
File.WriteAllBytes("mynodes", engine.SaveNodes());
}
}
}
}
I know it's very old question, I'm not sure why it's still noone has answer it, anyway. The problem seem to be this line:
DhtListener listener = new DhtListener(new IPEndPoint(IPAddress.Parse("192.168.2.3"), 10000));
This ip is not the real ip, so you actually asl peers to send the respone to unkonw adress.
What to do? register your own adress.

Categories

Resources