using System; using System.IO; using System.Net; using System.Net.Http; using System.Threading.Tasks; namespace AsyncHttpServerAndClient { internal static class Program { internal static void Main(string[] args) { MainAsync(args).GetAwaiter().GetResult(); } private static async Task MainAsync(string[] args) { var tcs = new TaskCompletionSource(); Console.CancelKeyPress += (sender, e) => { tcs.SetResult(null); }; var server = new AsyncHttpServer(portNumber: 1234); var task = Task.Run(() => server.Start()); await Console.Out.WriteLineAsync("Listening on port 1234. Open http://localhost:1234 in your browser."); await Console.Out.WriteLineAsync("Trying to connect:"); await Console.Out.WriteLineAsync(); await GetResponseAsync("http://localhost:1234"); await Console.Out.WriteLineAsync("Press Ctrl+C to stop the server..."); await tcs.Task; await server.Stop(); } private static async Task GetResponseAsync(string url) { using (var client = new HttpClient()) { var responseMessage = await client.GetAsync(url); var responseHeaders = responseMessage.Headers.ToString(); var response = await responseMessage.Content.ReadAsStringAsync(); Console.WriteLine("Response headers:"); Console.WriteLine(responseHeaders); Console.WriteLine("Response body:"); Console.WriteLine(response); Console.WriteLine(); } } private class AsyncHttpServer { private const string ResponseTemplate = "" + "" + "Test" + "" + "" + "

Test page

" + "

Today is: {0}

" + "" + ""; private readonly HttpListener _listener; public AsyncHttpServer(int portNumber) { _listener = new HttpListener(); _listener.Prefixes.Add(string.Format("http://+:{0}/", portNumber)); } public async Task Start() { _listener.Start(); while (true) { var ctx = await _listener.GetContextAsync(); Console.Out.WriteLine("Client connected..."); Console.Out.WriteLine("Serving file: '{0}'", ctx.Request.Url); ctx.Response.Headers.Add("content-type: text/html; charset=UTF-8"); ctx.Response.Headers.Add("x-content-type-options: nosniff"); ctx.Response.Headers.Add("x-xss-protection:1; mode=block"); ctx.Response.Headers.Add("x-frame-options:DENY"); ctx.Response.Headers.Add("cache-control:no-store, no-cache, must-revalidate"); ctx.Response.Headers.Add("pragma:no-cache"); ctx.Response.Headers.Add("Server", "jl"); var response = string.Format(ResponseTemplate, DateTime.Now); using (var sw = new StreamWriter(ctx.Response.OutputStream)) { await sw.WriteAsync(response); await sw.FlushAsync(); } } } public async Task Stop() { await Console.Out.WriteLineAsync( "Stopping server..."); if (_listener.IsListening) { _listener.Stop(); _listener.Close(); } } } } }