1using System;
2using System.IO;
3using System.Text;
4using System.Net;
5using System.Threading.Tasks;
6
7namespace Eldfell
8{
9 class HttpServer
10 {
11 public static HttpListener listener;
12 public static string url = "http://localhost:8000/";
13 public static int pageViews = 0;
14 public static int requestCount = 0;
15 public static string pageData =
16 "<!DOCTYPE>" +
17 "<html>" +
18 " <head>" +
19 " <title>HttpListener Example</title>" +
20 " </head>" +
21 " <body>" +
22 " <p>Page Views: {0}</p>" +
23 " <form method=\"post\" action=\"shutdown\">" +
24 " <input type=\"submit\" value=\"Shutdown\" {1}>" +
25 " </form>" +
26 " </body>" +
27 "</html>";
28
29
30 public static async Task HandleIncomingConnections()
31 {
32 bool runServer = true;
33
34 // While a user hasn't visited the `shutdown` url, keep on handling requests
35 while (runServer)
36 {
37 // Will wait here until we hear from a connection
38 HttpListenerContext ctx = await listener.GetContextAsync();
39
40 // Peel out the requests and response objects
41 HttpListenerRequest req = ctx.Request;
42 HttpListenerResponse resp = ctx.Response;
43
44 // Print out some info about the request
45 Console.WriteLine("Request #: {0}", ++requestCount);
46 Console.WriteLine(req.Url.ToString());
47 Console.WriteLine(req.HttpMethod);
48 Console.WriteLine(req.UserHostName);
49 Console.WriteLine(req.UserAgent);
50 Console.WriteLine();
51
52 // If `shutdown` url requested w/ POST, then shutdown the server after serving the page
53 if ((req.HttpMethod == "POST") && (req.Url.AbsolutePath == "/shutdown"))
54 {
55 Console.WriteLine("Shutdown requested");
56 runServer = false;
57 }
58
59 // Make sure we don't increment the page views counter if `favicon.ico` is requested
60 if (req.Url.AbsolutePath != "/favicon.ico")
61 pageViews += 1;
62
63 // Write the response info
64 string disableSubmit = !runServer ? "disabled" : "";
65 byte[] data = Encoding.UTF8.GetBytes(String.Format(pageData, pageViews, disableSubmit));
66 resp.ContentType = "text/html";
67 resp.ContentEncoding = Encoding.UTF8;
68 resp.ContentLength64 = data.LongLength;
69
70 // Write out to the response stream (asynchronously), then close it
71 await resp.OutputStream.WriteAsync(data, 0, data.Length);
72 resp.Close();
73 }
74 }
75
76
77 public static void Run()
78 {
79 // Create a Http server and start listening for incoming connections
80 listener = new HttpListener();
81 listener.Prefixes.Add(url);
82 listener.Start();
83 Console.WriteLine("Listening for connections on {0}", url);
84
85 // Handle requests
86 Task listenTask = HandleIncomingConnections();
87 listenTask.GetAwaiter().GetResult();
88
89 // Close the listener
90 listener.Close();
91 }
92 }
93}