using System; using System.Diagnostics.CodeAnalysis; using System.Net; using System.Text; using Utf8Json; using HttpListenerRequest = SpaceWizards.HttpListener.HttpListenerRequest; using HttpListenerResponse = SpaceWizards.HttpListener.HttpListenerResponse; namespace Webserver { public static class WebUtils { // ReSharper disable once MemberCanBePrivate.Global public const string MimePlain = "text/plain"; public const string MimeHtml = "text/html"; // ReSharper disable once MemberCanBePrivate.Global public const string MimeJson = "application/json"; private static readonly UnityEngine.Profiling.CustomSampler envelopeBuildSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_EnvelopeBuilding"); private static readonly UnityEngine.Profiling.CustomSampler netWriteSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_Write"); public static void WriteText (HttpListenerResponse _resp, string _text, HttpStatusCode _statusCode = HttpStatusCode.OK, string _mimeType = null) { _resp.StatusCode = (int)_statusCode; _resp.ContentType = _mimeType ?? MimePlain; _resp.ContentEncoding = Encoding.UTF8; byte[] buf = Encoding.UTF8.GetBytes (_text); _resp.ContentLength64 = buf.Length; _resp.OutputStream.Write (buf, 0, buf.Length); } public static bool IsSslRedirected (HttpListenerRequest _req) { string proto = _req.Headers ["X-Forwarded-Proto"]; return !string.IsNullOrEmpty (proto) && proto.Equals ("https", StringComparison.OrdinalIgnoreCase); } public static string GenerateGuid () { return Guid.NewGuid ().ToString (); } [SuppressMessage ("ReSharper", "MemberCanBePrivate.Global")] public static void WriteJsonData (HttpListenerResponse _resp, ref JsonWriter _jsonWriter, HttpStatusCode _statusCode = HttpStatusCode.OK) { ArraySegment jsonData = _jsonWriter.GetBuffer (); netWriteSampler.Begin (); _resp.StatusCode = (int)_statusCode; _resp.ContentType = MimeJson; _resp.ContentEncoding = Encoding.UTF8; _resp.ContentLength64 = jsonData.Count; _resp.OutputStream.Write (jsonData.Array!, 0, jsonData.Count); netWriteSampler.End (); } private static readonly byte[] jsonRawDataKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("data"); // {"data": private static readonly byte[] jsonRawMetaKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("meta"); // ,"meta": private static readonly byte[] jsonRawMetaServertimeKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("serverTime"); // {"serverTime": private static readonly byte[] jsonRawMetaRequestMethodKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("requestMethod"); // ,"requestMethod": private static readonly byte[] jsonRawMetaRequestSubpathKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("requestSubpath"); // ,"requestSubpath": private static readonly byte[] jsonRawMetaRequestBodyKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("requestBody"); // ,"requestBody": private static readonly byte[] jsonRawMetaErrorCodeKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("errorCode"); // ,"errorCode": private static readonly byte[] jsonRawMetaExceptionMessageKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("exceptionMessage"); // ,"exceptionMessage": private static readonly byte[] jsonRawMetaExceptionTraceKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("exceptionTrace"); // ,"exceptionTrace": public static void PrepareEnvelopedResult (out JsonWriter _writer) { _writer = new JsonWriter (); _writer.WriteRaw (jsonRawDataKey); } public static void SendEnvelopedResult (RequestContext _context, ref JsonWriter _writer, HttpStatusCode _statusCode = HttpStatusCode.OK, byte[] _jsonInputData = null, string _errorCode = null, Exception _exception = null) { envelopeBuildSampler.Begin (); _writer.WriteRaw (jsonRawMetaKey); _writer.WriteRaw (jsonRawMetaServertimeKey); _writer.WriteString (DateTime.Now.ToString ("o")); if (!string.IsNullOrEmpty (_errorCode)) { _writer.WriteRaw (jsonRawMetaRequestMethodKey); _writer.WriteString (_context.Request.HttpMethod); _writer.WriteRaw (jsonRawMetaRequestSubpathKey); _writer.WriteString (_context.RequestPath); _writer.WriteRaw (jsonRawMetaRequestBodyKey); if (_jsonInputData != null) { _writer.WriteRaw (_jsonInputData); } else { _writer.WriteNull (); } _writer.WriteRaw (jsonRawMetaErrorCodeKey); _writer.WriteString (_errorCode); if (_exception != null) { _writer.WriteRaw (jsonRawMetaExceptionMessageKey); _writer.WriteString (_exception.Message); _writer.WriteRaw (jsonRawMetaExceptionTraceKey); _writer.WriteString (_exception.StackTrace); } } _writer.WriteEndObject (); // End of "meta" object _writer.WriteEndObject (); // End of overall result object envelopeBuildSampler.End (); WriteJsonData (_context.Response, ref _writer, _statusCode); } } }