Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A Simple HTTP server in C#
// 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();
}
}
}
@nikola354

This comment has been minimized.

Copy link

nikola354 commented Dec 19, 2019

Briliant solution! One question: I want to send a json string to the http server. How can I get the message from the request?

@define-private-public

This comment has been minimized.

Copy link
Owner Author

define-private-public commented Dec 19, 2019

I'm not quite sure myself, but my guess would be to check the HttpListenerRequest object that's received by the server: https://docs.microsoft.com/en-us/dotnet/api/system.net.httplistenerrequest?view=netframework-4.8

@define-private-public

This comment has been minimized.

Copy link
Owner Author

define-private-public commented Dec 19, 2019

Reading the docs further, I think it might be the request's InputStream you need to read: https://docs.microsoft.com/en-us/dotnet/api/system.net.httplistenerrequest.inputstream?view=netframework-4.8#examples

@nikola354

This comment has been minimized.

Copy link

nikola354 commented Dec 21, 2019

Thanks!

@hazelForet

This comment has been minimized.

Copy link

hazelForet commented May 29, 2020

Thanks! I have one issue with redirecting https calls into http. for example if the client requested https://myserver/login will automatically redirected to http://myserver/login

@define-private-public

This comment has been minimized.

Copy link
Owner Author

define-private-public commented May 29, 2020

Thanks! I have one issue with redirecting https calls into http. for example if the client requested https://myserver/login will automatically redirected to http://myserver/login

https requires SSL certs and whatnot, and that's always a pain to setup and use. This is meant for something to run locally on a computer, not an externally facing thing, so I don't think that https is something to worry about for this use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.