-
Star
(183)
You must be signed in to star a gist -
Fork
(34)
You must be signed in to fork a gist
-
-
Save define-private-public/d05bc52dd0bed1c4699d49e2737e80e7 to your computer and use it in GitHub Desktop.
// Filename: HttpServer.cs | |
// Author: Benjamin N. Summerton <define-private-public> | |
// License: Unlicense (http://unlicense.org/) | |
using System; | |
using System.IO; | |
using System.Text; | |
using System.Net; | |
using System.Threading.Tasks; | |
namespace HttpListenerExample | |
{ | |
class HttpServer | |
{ | |
public static HttpListener listener; | |
public static string url = "http://localhost:8000/"; | |
public static int pageViews = 0; | |
public static int requestCount = 0; | |
public static string pageData = | |
"<!DOCTYPE>" + | |
"<html>" + | |
" <head>" + | |
" <title>HttpListener Example</title>" + | |
" </head>" + | |
" <body>" + | |
" <p>Page Views: {0}</p>" + | |
" <form method=\"post\" action=\"shutdown\">" + | |
" <input type=\"submit\" value=\"Shutdown\" {1}>" + | |
" </form>" + | |
" </body>" + | |
"</html>"; | |
public static async Task HandleIncomingConnections() | |
{ | |
bool runServer = true; | |
// While a user hasn't visited the `shutdown` url, keep on handling requests | |
while (runServer) | |
{ | |
// Will wait here until we hear from a connection | |
HttpListenerContext ctx = await listener.GetContextAsync(); | |
// Peel out the requests and response objects | |
HttpListenerRequest req = ctx.Request; | |
HttpListenerResponse resp = ctx.Response; | |
// Print out some info about the request | |
Console.WriteLine("Request #: {0}", ++requestCount); | |
Console.WriteLine(req.Url.ToString()); | |
Console.WriteLine(req.HttpMethod); | |
Console.WriteLine(req.UserHostName); | |
Console.WriteLine(req.UserAgent); | |
Console.WriteLine(); | |
// If `shutdown` url requested w/ POST, then shutdown the server after serving the page | |
if ((req.HttpMethod == "POST") && (req.Url.AbsolutePath == "/shutdown")) | |
{ | |
Console.WriteLine("Shutdown requested"); | |
runServer = false; | |
} | |
// Make sure we don't increment the page views counter if `favicon.ico` is requested | |
if (req.Url.AbsolutePath != "/favicon.ico") | |
pageViews += 1; | |
// Write the response info | |
string disableSubmit = !runServer ? "disabled" : ""; | |
byte[] data = Encoding.UTF8.GetBytes(String.Format(pageData, pageViews, disableSubmit)); | |
resp.ContentType = "text/html"; | |
resp.ContentEncoding = Encoding.UTF8; | |
resp.ContentLength64 = data.LongLength; | |
// Write out to the response stream (asynchronously), then close it | |
await resp.OutputStream.WriteAsync(data, 0, data.Length); | |
resp.Close(); | |
} | |
} | |
public static void Main(string[] args) | |
{ | |
// Create a Http server and start listening for incoming connections | |
listener = new HttpListener(); | |
listener.Prefixes.Add(url); | |
listener.Start(); | |
Console.WriteLine("Listening for connections on {0}", url); | |
// Handle requests | |
Task listenTask = HandleIncomingConnections(); | |
listenTask.GetAwaiter().GetResult(); | |
// Close the listener | |
listener.Close(); | |
} | |
} | |
} |
@CoderLel
For that, you'd need to add in some AJAX stuff ( https://en.wikipedia.org/wiki/Ajax_(programming) ) stuff.
How enabled cors ? Access-Control-Allow-Origin", "*"
used this for a demo.. thanks man :)
Catch a crutch.
Little piece'o'code to keep things going in local network from other devices.
You need to open a certain port in Windows Firewall.
We don't gonna do it several times, cause it makes duplicate entries, so that's the reason why we will use registry to set the flag on first run.
And yep, you need to create a reference to "c:\windows\system32\FirewallAPI.dll".
` RegistryKey currentUserKey = Registry.CurrentUser;
RegistryKey softwareKey = currentUserKey.OpenSubKey("SOFTWARE", writable: true);
RegistryKey orgKey = softwareKey.OpenSubKey("%YOUR ORG NAME%", writable: true);
if (orgKey == null)
orgKey = softwareKey.CreateSubKey("%YOUR ORG NAME%", writable: true);
RegistryKey appKey = orgKey.OpenSubKey("%YOUR APPNAME%", writable: true);
if (appKey == null)
appKey = orgKey.CreateSubKey("%YOUR APPNAME%", writable: true);
bool? permissionsGranted = null;
try
{
object keyValue = appKey.GetValue("Permissions Granted");
permissionsGranted = keyValue != null ? Convert.ToBoolean(keyValue) : false;
}
catch (Exception e) {
permissionsGranted = false;
}
if (permissionsGranted == false) {
appKey.SetValue("Permissions Granted", true);
Type tNetFwPolicy2 = Type.GetTypeFromProgID("HNetCfg.FwPolicy2");
INetFwPolicy2 fwPolicy2 = (INetFwPolicy2)Activator.CreateInstance(tNetFwPolicy2);
var currentProfiles = fwPolicy2.CurrentProfileTypes;
INetFwRule2 inboundRule = (INetFwRule2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
inboundRule.Enabled = true;
inboundRule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW;
inboundRule.Protocol = 6; // TCP
inboundRule.LocalPorts = "80";
inboundRule.Name = "HTTP Server 80 port";
inboundRule.Profiles = currentProfiles;
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
firewallPolicy.Rules.Add(inboundRule);
}
currentUserKey.Close();
softwareKey.Close();
orgKey.Close();
appKey.Close();`
hello world
thanks a lot !! ;)
That's what I was looking for. Thank you very much. Good job.
Been fooling around with this and noticed some unanswered questions above. Can only tell you what worked for me.
"I want to send a json string to the http server. How can I get the message from the request?"
I went with something like:
string payload = GetRequestPostData(ctx.Request);
Where you define that function like:
string GetRequestPostData(HttpListenerRequest request)
{
if (!request.HasEntityBody)
{
return null;
}
using (System.IO.Stream body = request.InputStream)
{
using (var reader = new System.IO.StreamReader(body, request.ContentEncoding))
{
return reader.ReadToEnd();
}
}
}
doesn't work with other Networks on the same Network for example a Phone.
I tried changing "url" to the local IP Address of the Machine Running the code, but this doesn't work for neither my Phone or my PC.
Does anyone have a Solution to this?
change localhost to something like + or *
e.g.
string url = $"http://+:8000/";
Your OS might complain about permissions though.
If so you can try something like: "netsh http add urlacl url=http://+:8000/ user=your_username_here"
how do i encode an image to bytes?
@Tomloyo thats not the right place to ask xD
but since im already here, let me help you.
First you need to load the image into a bitmap.
When you did that, there is a function called LockBits
this returns a pointer to the start of the array.
Then you can just copy all the image bytes into a seperate byte[]
you created.
How could I make this work with SSL Encryption, essentialy have this function as https server
I tried to take TLS part from Kestrel (its to big, I don't need the whole framework), because I need to perform secure connection with OpenSSL (my os doesn't have the newest ciphers uvailable): https://github.com/tmds/KestrelHttpServer/tree/ab78fb0b8ca4f03eb53795f9a97c8152b045ef6b/src/Kestrel.Tls
Here is what I tried to take out: https://github.com/user-attachments/files/17267580/Kestrel.Tls.zip
and this is how I tried using it
using System;
using System.IO;
using System.Text;
using System.Net;
using System.Threading.Tasks;
using Kestrel.Tls;
namespace HttpListenerExample
{
class HttpServer
{
public static HttpListener listener;
public static string url = "https://192.168.88.12:443/"; // Change to HTTPS and appropriate port
public static int pageViews = 0;
public static int requestCount = 0;
public static string certificatePath = "my-cert.pem";
public static string privateKeyPath = "my-key.pem";
public static string pageData =
"<!DOCTYPE>" +
"<html>" +
" <head>" +
" <title>HttpListener Example</title>" +
" </head>" +
" <body>" +
" <p>Page Views: {0}</p>" +
" <form method=\"post\" action=\"shutdown\">" +
" <input type=\"submit\" value=\"Shutdown\" {1}>" +
" </form>" +
" </body>" +
"</html>";
public static async Task HandleIncomingConnections()
{
bool runServer = true;
while (runServer)
{
// Wait for an incoming connection
HttpListenerContext ctx = await listener.GetContextAsync();
Stream innerStream = ctx.Response.OutputStream;
// Wrap the inner stream with TlsStream
using (var tlsStream = new TlsStream(innerStream, certificatePath, privateKeyPath, new[] { "http/1.1" }))
{
// Perform the TLS handshake
await tlsStream.DoHandshakeAsync();
// Handle request
HttpListenerRequest req = ctx.Request;
HttpListenerResponse resp = ctx.Response;
// Print out request info
Console.WriteLine("Request #: {0}", ++requestCount);
Console.WriteLine(req.Url.ToString());
Console.WriteLine(req.HttpMethod);
Console.WriteLine(req.UserHostName);
Console.WriteLine(req.UserAgent);
Console.WriteLine();
// Handle shutdown request
if ((req.HttpMethod == "POST") && (req.Url.AbsolutePath == "/shutdown"))
{
Console.WriteLine("Shutdown requested");
runServer = false;
}
// Increment page views, ignoring favicon requests
if (req.Url.AbsolutePath != "/favicon.ico")
pageViews += 1;
// Write the response info
string disableSubmit = !runServer ? "disabled" : "";
byte[] data = Encoding.UTF8.GetBytes(String.Format(pageData, pageViews, disableSubmit));
resp.ContentType = "text/html";
resp.ContentEncoding = Encoding.UTF8;
resp.ContentLength64 = data.LongLength;
// Write out to the response stream
await tlsStream.WriteAsync(data, 0, data.Length, default);
}
}
}
public static void Main(string[] args)
{
listener = new HttpListener();
listener.Prefixes.Add(url);
listener.Start();
Console.WriteLine("Listening for connections on {0}", url);
// Handle requests
Task listenTask = HandleIncomingConnections();
listenTask.GetAwaiter().GetResult();
// Close the listener
listener.Close();
}
}
}
But using firefox, I get PR_CONNECT_RESET_ERROR
and when I tried to connect using OpenSSL like this
openssl s_client -connect domain.local:443
I get this as error
Connecting to 192.168.88.12
CONNECTED(00000128)
write:errno=10054
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 327 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
So not sure how to fix my problem
I know my certificates are valid, also I do have libssl-1_1.dll
and libcrypto-1_1.dll
in my bin directory
I am experimenting with this, but can I somehow display the real time visits count? Now I have to manually refresh the page and this can be really frustrating sometimes