using System; using System.IO; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using System.Net.Sockets; using System.Net; using Uwaa.HTTP.Websockets; using Uwaa.HTTP.Routing; namespace Uwaa.HTTP.Example; static class Program { static void Main(string[] args) { Console.WriteLine("Loading test certificate"); X509Certificate cert = X509Certificate.CreateFromCertFile("certs/localhost.pfx"); Console.WriteLine("Preparing listeners"); Router router = CreateRouter(); HttpServer httpServer = new HttpServer(80, null, router); HttpServer httpsServer = new HttpServer(443, cert, router); httpServer.OnConnectionBegin += LogConnect; httpServer.OnConnectionEnd += LogDisconnect; httpsServer.OnConnectionBegin += LogConnect; httpsServer.OnConnectionEnd += LogDisconnect; httpServer.Start(); httpsServer.Start(); Console.WriteLine($"Ready on ports {httpServer.Port} and {httpsServer.Port}"); TestClient(); Task.Delay(-1).Wait(); } /// /// Generates the URL router for the HTTP server. /// static Router CreateRouter() { //The order here matters Router subpath = new Router(); subpath.Add("foo", new StaticEndpoint(HttpResponse.OK("A \"foo\" example sub page"))); subpath.Add("bar", new StaticEndpoint(HttpResponse.OK("A \"bar\" example sub page"))); Router router = new Router(); router.Add(LogRequest); router.Add(new CORS()); router.Add("custom", new CustomRoute()); router.Add("subpath", subpath); router.Add(new FileEndpoint("www-static") { Index = false }); router.Add(new FileEndpoint("www-dynamic") { Index = false }); router.Add("", Root); router.Add(new StaticEndpoint(HttpResponse.NotFound("File not found"))); return router; } /// /// Example HTTP client request. /// static async void TestClient() { Console.WriteLine("Connecting"); //Make request HttpRequest req = new HttpRequest(HttpMethod.GET, "/test.txt"); req.Fields.UserAgent = "test (Uwaa.HTTP)"; req.Fields.Connection = ConnectionType.Close; //Send, get response HttpResponse res = await HttpClient.Request("localhost", true, req); string resText = res.Content?.AsText ?? "null"; Console.WriteLine("Got response: " + resText); } /// /// Logs a new connection to the console. /// static void LogConnect(TcpClient client) { Console.WriteLine($"{client.Client.RemoteEndPoint} connected"); } /// /// Logs a disconnection to the console. /// static void LogDisconnect(IPEndPoint endpoint) { Console.WriteLine($"{endpoint} disconnected"); } /// /// Logs a request to the console. /// static HttpResponse? LogRequest(HttpRequest req, HttpClientInfo info) { Console.WriteLine($"{info.Endpoint.Address}: {req.Method} {req.Path}"); return null; } /// /// Root endpoint: / /// static async Task Root(HttpRequest req, HttpClientInfo info) { if (req.IsWebsocket) return Websocket(req, info); byte[] indexFile = await File.ReadAllBytesAsync("www-static/index.html"); HttpContent html = new HttpContent(new MIMEType("text", "html"), indexFile); return HttpResponse.OK(html); } /// /// Websocket endpoint /// static HttpResponse? Websocket(HttpRequest req, HttpClientInfo info) { return req.UpgradeToWebsocket(HandleWebsocket, "test"); } static async Task HandleWebsocket(Websocket ws) { TimeSpan timeout = TimeSpan.FromMinutes(1); DataFrame payload = await ws.Read().WaitAsync(timeout); if (payload.Opcode != WSOpcode.Close) { string result = payload.AsString(); await ws.Write($"Echoing message: \"{result}\"").WaitAsync(timeout); } return CloseStatus.NormalClosure; } /// /// Custom route: /custom/{param1}/{param2} /// class CustomRoute : RouterBase { public override HttpMethod Method => HttpMethod.GET; public override int Arguments => 2; protected override Task GetResponseInner(HttpRequest req, HttpClientInfo info, ArraySegment path) { string param1 = path[0]; string param2 = path[1]; return Task.FromResult(HttpResponse.OK($"Variable 1: {param1}\nVariable 2: {param2}")); } } }