using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Text; using Kayak.Http; using Kayak; namespace IW4MAdmin { class Scheduler : ISchedulerDelegate { public void OnException(IScheduler scheduler, Exception e) { // it looks like there's a library error in // Kayak.Http.HttpServerTransactionDelegate.OnError if (e.GetType() == typeof(NullReferenceException)) return; ApplicationManager.GetInstance().Logger.WriteWarning("Web service has encountered an error - " + e.Message); ApplicationManager.GetInstance().Logger.WriteDebug($"Stack Trace: {e.StackTrace}"); if (e.InnerException != null) { ApplicationManager.GetInstance().Logger.WriteDebug($"Inner Exception: {e.InnerException.Message}"); ApplicationManager.GetInstance().Logger.WriteDebug($"Inner Stack Trace: {e.InnerException.StackTrace}"); } } public void OnStop(IScheduler scheduler) { ApplicationManager.GetInstance().Logger.WriteInfo("Web service has been stopped..."); } } class Request : IHttpRequestDelegate { public void OnRequest(HttpRequestHead request, IDataProducer requestBody, IHttpResponseDelegate response, string IP) { NameValueCollection querySet = new NameValueCollection(); if (request.QueryString != null) querySet = System.Web.HttpUtility.ParseQueryString(SharedLibrary.Utilities.StripIllegalCharacters(request.QueryString)); querySet.Set("IP", IP); try { SharedLibrary.HttpResponse requestedPage = WebService.GetPage(request.Path, querySet, request.Headers); var headers = new HttpResponseHead() { Status = "200 OK", Headers = new Dictionary() { { "Content-Type", requestedPage.contentType }, { "Content-Length", requestedPage.content.Length.ToString() }, { "Access-Control-Allow-Origin", "*" }, } }; foreach (var key in requestedPage.additionalHeaders.Keys) headers.Headers.Add(key, requestedPage.additionalHeaders[key]); response.OnResponse(headers, new BufferedProducer(requestedPage.content)); } catch (Exception e) { ApplicationManager.GetInstance().Logger.WriteError($"Webfront error during request: {e.Message}"); response.OnResponse(new HttpResponseHead() { Status = "500 Internal Server Error", Headers = new Dictionary() { { "Content-Type", "text/html" }, { "Content-Length", "0"}, } }, new BufferedProducer("")); } } } class BufferedProducer : IDataProducer { ArraySegment data; public BufferedProducer(string data) : this(data, Encoding.UTF8) { } public BufferedProducer(string data, Encoding encoding) : this(encoding.GetBytes(data)) { } public BufferedProducer(byte[] data) : this(new ArraySegment(data)) { } public BufferedProducer(ArraySegment data) { this.data = data; } public IDisposable Connect(IDataConsumer channel) { channel?.OnData(data, null); channel?.OnEnd(); return null; } } class BufferedConsumer : IDataConsumer { List> buffer = new List>(); Action resultCallback; Action errorCallback; public BufferedConsumer(Action resultCallback, Action errorCallback) { this.resultCallback = resultCallback; this.errorCallback = errorCallback; } public bool OnData(ArraySegment data, Action continuation) { buffer?.Add(data); return false; } public void OnError(Exception error) { errorCallback?.Invoke(error); } public void OnEnd() { var str = buffer .Select(b => Encoding.UTF8.GetString(b.Array, b.Offset, b.Count)) .Aggregate((result, next) => result + next); resultCallback(str); } } }