using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; namespace twitcher { public class Httpd { public class ResponseSet { public string Text { get; set; } = ":)"; public HttpStatusCode statusCode { get; set; } = HttpStatusCode.OK; } public delegate ResponseSet RequestHandler(HttpListenerRequest request); private Dictionary psuedoResources = new Dictionary(); private HttpListener server; public Httpd(int port) { server = new HttpListener(); server.Prefixes.Add($"http://*:{port}/"); server.Start(); } public void HandleEndpoint(string destination, RequestHandler handler) { lock (psuedoResources) { psuedoResources[destination] = handler; } } public void UnhandleEndpoint(string destination, RequestHandler handler) { lock (psuedoResources) { psuedoResources.Remove(destination); } } public async Task go() { while (true) { HttpListenerContext context = await server.GetContextAsync(); HttpListenerResponse response = context.Response; string page = context.Request.Url.LocalPath.Substring(1); var resp = "no resource"; response.StatusCode = (int)HttpStatusCode.NotFound; lock (psuedoResources) { if (psuedoResources.ContainsKey(page)) { string responseText; int responseCode; try { var responseSet = psuedoResources[page](context.Request); responseText = responseSet.Text; responseCode = (int)responseSet.statusCode; } catch (Exception e) { context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; responseText = ":("; Console.Error.WriteLine(JsonConvert.SerializeObject(e)); } if (response.StatusCode != (int)HttpStatusCode.OK) { Console.WriteLine($"returning status code {response.StatusCode}"); } byte[] buffer = Encoding.UTF8.GetBytes(resp); response.ContentLength64 = buffer.Length; Stream st = response.OutputStream; st.Write(buffer, 0, buffer.Length); response.Close(); } // if (page == "twitcherize") // { // byte[] rawIncomingBytes = new byte[context.Request.ContentLength64]; // var readBytes = context.Request.InputStream.Read(rawIncomingBytes, 0, (int)context.Request.ContentLength64); // if (VerifySignature(context.Request.Headers["Twitch-Eventsub-Message-Signature"], // context.Request.ContentEncoding, // context.Request.Headers["Twitch-Eventsub-Message-Id"], // context.Request.Headers["Twitch-Eventsub-Message-Timestamp"], // rawIncomingBytes)) // { // try // { // if (twitchogrambuffer.Contains(context.Request.Headers["Twitch-Eventsub-Message-Id"])) // { // Console.WriteLine("duplicate message received. Ignoring."); // } // else // { // var incomingText = context.Request.ContentEncoding.GetString(rawIncomingBytes); // //Console.WriteLine($"{context.Request.Headers["Twitch-Eventsub-Message-Id"]} looks new to me."); // lock (twitchogrambuffer) // { // var fromTwitch = SubscribableTypesTranslation.RefineTwitchogram(incomingText); // if (fromTwitch.challenge != null) // { // resp = fromTwitch.challenge; // Console.WriteLine("challenge responded to, should be subscribed"); // } // else if (fromTwitch.subscription.status == "authorization_revoked") // { // resp = "ok... :("; // Console.WriteLine($"auth revoked for {fromTwitch.subscription.type} ({fromTwitch.subscription.id})"); // } // else // { // var foundAHandler = false; // foreach (var kvp in psuedoResources) // { // if (kvp.Key.id == fromTwitch.subscription.id) // { // kvp.Value(fromTwitch); // resp = ":)"; // foundAHandler = true; // break; // } // } // if (!foundAHandler) // { // Console.WriteLine($"I don't have a handler for {fromTwitch.subscription.type} ({fromTwitch.subscription.id})? o_O"); // resp = ":S"; // } // } // } // tasksToNotActuallyAwait.Add(logMessageId(context.Request.Headers["Twitch-Eventsub-Message-Id"])); // response.StatusCode = (int)HttpStatusCode.OK; // } // } // catch (Exception e) // { // Console.Error.WriteLine("something went wrong calling resource."); // Console.Error.WriteLine(JsonConvert.SerializeObject(e)); // response.StatusCode = (int)HttpStatusCode.InternalServerError; // resp = "error :("; // } // } // else // { // Console.WriteLine("couldn't verify signature."); // response.StatusCode = (int)HttpStatusCode.Forbidden; // resp = "VoteNay"; // } // } } } } } }