using System; using System.IO; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Web; using Newtonsoft.Json; namespace Noname.Integration.AzureWebApp { public class NonameAzureWebAppModule : IHttpModule { private const string RequestDataKey = "Noname.RequestData"; private static readonly HttpClient _httpClient; private static string _engineUrl; private static string _sourceKey; private static int _sourceType = 28; private static string _sourceIndex; private static string _sourceVersion; static NonameAzureWebAppModule() { // Always skip SSL certificate verification var handler = new HttpClientHandler { ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true }; _httpClient = new HttpClient(handler); // Set timeout _httpClient.Timeout = TimeSpan.FromSeconds(10); } public void Init(HttpApplication context) { // Read configuration from environment variables _engineUrl = Environment.GetEnvironmentVariable("NONAME_ENGINE_URL"); _sourceKey = Environment.GetEnvironmentVariable("NONAME_SOURCE_KEY"); _sourceIndex = Environment.GetEnvironmentVariable("NONAME_SOURCE_INDEX"); _sourceVersion = Environment.GetEnvironmentVariable("NONAME_SOURCE_VERSION"); // Hook into request events context.BeginRequest += OnBeginRequest; context.PreSendRequestHeaders += OnSendResponse; } private void OnBeginRequest(object sender, EventArgs e) { try { HttpApplication app = (HttpApplication)sender; HttpContext context = app.Context; // Capture request headers var requestHeaders = new System.Collections.Generic.Dictionary(); foreach (string key in context.Request.Headers.AllKeys) { if (key != null) { requestHeaders[key] = context.Request.Headers[key]; } } string requestBody = ""; // Store request data in HttpContext.Items for later use context.Items[RequestDataKey] = new { Method = context.Request.HttpMethod, Url = context.Request.RawUrl, Headers = requestHeaders, Body = requestBody, // Already captured above if appropriate Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), ClientIp = context.Request.ServerVariables["REMOTE_ADDR"] ?? context.Request.UserHostAddress ?? "0.0.0.0", ClientPort = context.Request.ServerVariables["REMOTE_PORT"] ?? "0", ServerIp = context.Request.ServerVariables["LOCAL_ADDR"] ?? "0.0.0.0", ServerPort = context.Request.ServerVariables["SERVER_PORT"] ?? "0", HttpVersion = context.Request.ServerVariables["HTTP_VERSION"] ?? "" }; } catch { // Silently handle errors } } private void OnSendResponse(object sender, EventArgs e) { try { HttpApplication app = (HttpApplication)sender; HttpContext context = app.Context; // Retrieve stored request data from OnBeginRequest dynamic requestData = context.Items[RequestDataKey]; if (requestData == null) { return; } // Request body was already captured in OnBeginRequest string requestBody = requestData.Body; // Build response headers dictionary var responseHeaders = new System.Collections.Generic.Dictionary(); foreach (string key in context.Response.Headers.AllKeys) { if (key != null) { responseHeaders[key] = context.Response.Headers[key]; } } string responseBody = ""; // Get response timestamp long responseTs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); // Build the complete traffic data structure var data = new { source = new { type = _sourceType, index = _sourceIndex, key = _sourceKey, version = _sourceVersion }, ip = new { v = 4, src = requestData.ClientIp, dst = requestData.ServerIp }, tcp = new { src = int.TryParse((string)requestData.ClientPort, out int cp) ? cp : 0, dst = int.TryParse((string)requestData.ServerPort, out int sp) ? sp : 0 }, http = new { v = requestData.HttpVersion, request = new { body = requestBody, headers = requestData.Headers, ts = requestData.Timestamp.ToString(), method = requestData.Method, url = requestData.Url }, response = new { body = responseBody, headers = responseHeaders, ts = responseTs.ToString(), status = context.Response.StatusCode } } }; // Send to engine asynchronously Task.Run(() => SendToEngine(data)); } catch { // Silently handle errors } } private async Task SendToEngine(object data) { try { string json = JsonConvert.SerializeObject(data); var content = new StringContent(json, Encoding.UTF8, "application/json"); await _httpClient.PostAsync(_engineUrl, content); } catch { // Silently handle errors } } public void Dispose() { // Cleanup } } }