Home

Awesome

OBSOLETE

HttpServerLite has been merged with the .NET Foundation project WatsonWebserver as a subproject called Watson.Lite.

This repository has been moved to public archive as a result.

We are thankful to the community that has contributed to this work and welcome you to continue efforts on the new repository!

alt tag

HttpServerLite

NuGet Version NuGet

TCP-based user-space HTTP and HTTPS server, written in C#, with no dependency on http.sys.

New in v2.1.x

Special Thanks

I'd like to extend a special thanks to those that have provided motivation or otherwise directly helped make HttpServerLite better.

Performance

HttpServerLite is quite fast, however, it's in user-space and may be slower than other webservers that have the benefit of a kernel-mode driver (such as http.sys and IIS or Watson).

Getting Started

Refer to the Test project for a working example.

It is important to under that that HttpServerLite is minimalistic and leaves control to you on which headers are set. Thus it is important to understand the following:

Simple Server

using System;
using System.Threading.Tasks;
using HttpServerLite;

namespace Test
{
  class Program
  {
    static Webserver _Server;

    static void Main(string[] args)
    {
      Webserver server = new Webserver("localhost", 9000, false, null, null, DefaultRoute); 
      server.Settings.Headers.Host = "https://localhost:9000";
      server.Start();
      Console.WriteLine("HttpServerLite listening on http://localhost:9000");
      Console.WriteLine("ENTER to exit");
      Console.ReadLine();
    }
         
    static async Task DefaultRoute(HttpContext ctx)
    {
      string resp = "Hello from HttpServerLite!";
      ctx.Response.StatusCode = 200; 
      ctx.Response.ContentLength = resp.Length;
      ctx.Response.ContentType = "text/plain";
      await ctx.Response.SendAsync(resp);
    }
  }
} 

Routing

HttpServerLite includes the following routing capabilities. These are listed in the other in which they are processed within HttpServerLite:

Additionally, you can annotate your own methods using the StaticRoute, ParameterRoute, or DynamicRoute attributes. Methods decorated with these attributes must be marked as public.

Webserver server = new Webserver("localhost", 9000, false, null, null, DefaultRoute);
server.Start();

[StaticRoute(HttpMethod.GET, "/static")]
public static async Task MyStaticRoute(HttpContext ctx)
{
  string resp = "Hello from the static route";
  ctx.Response.StatusCode = 200;
  ctx.Response.ContentType = "text/plain";
  ctx.Response.ContentLength = resp.Length;
  await ctx.Response.SendAsync(resp);
  return;
}

[ParameterRoute(HttpMethod.GET, "/{version}/api/{id}")]
public static async Task MyParameterRoute(HttpContext ctx)
{
  string resp = "Hello from parameter route version " + ctx.Request.Url.Parameters["version"] + " for ID " + ctx.Request.Url.Parameters["id"];
  ctx.Response.StatusCode = 200;
  ctx.Response.ContentType = "text/plain";
  ctx.Response.ContentLength = resp.Length;
  await ctx.Response.SendAsync(resp);
  return;
}

[DynamicRoute(HttpMethod.GET, "^/dynamic/\\d+$")]
public static async Task MyDynamicRoute(HttpContext ctx)
{
  string resp = "Hello from the dynamic route";
  ctx.Response.StatusCode = 200;
  ctx.Response.ContentType = "text/plain";
  ctx.Response.ContentLength = resp.Length;
  await ctx.Response.SendAsync(resp);
  return;
}

Authorizing or Declining a Connection

server.Callbacks.AuthorizeConnection = AuthorizeConnection;

private static bool AuthorizeConnection(string ipAddress, int port)
{
  // evaluate the IP address and port
  return true;  // permit
  return false; // deny
}

HostBuilder

HostBuilder helps you set up your server much more easily by introducing a chain of settings and routes instead of using the server class directly.

using WatsonWebserver.Extensions.HostBuilderExtension;

Server server = new HostBuilder("127.0.0.1", 8000, false, DefaultRoute)
                .MapStaticRoute(WatsonWebserver.HttpMethod.GET, GetUrlsRoute, "/links")
                .MapStaticRoute(WatsonWebserver.HttpMethod.POST, CheckLoginRoute, "/login")
                .MapStaticRoute(WatsonWebserver.HttpMethod.POST, TestRoute, "/test")
                .Build();

server.Start();

Console.WriteLine("Server started");
Console.ReadKey();

static async Task DefaultRoute(HttpContext ctx) => 
    await ctx.Response.SendAsync("Hello from default route!"); 

static async Task GetUrlsRoute(HttpContext ctx) => 
    await ctx.Response.SendAsync("Here are your links!"); 

static async Task CheckLoginRoute(HttpContext ctx) => 
    await ctx.Response.SendAsync("Checking your login!"); 

static async Task TestRoute(HttpContext ctx) => 
    await ctx.Response.SendAsync("Hello from the test route!"); 

Accessing from Outside Localhost

When you configure HttpServerLite to listen on 127.0.0.1 or localhost, it will only respond to requests received from within the local machine.

To configure access from other nodes outside of localhost, use the following:

Version History

Refer to CHANGELOG.md for version history.