/* Technitium DNS Server Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ using DnsServerCore.Auth; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using System; using System.Net; using System.Text.Json; using TechnitiumLibrary.Net; namespace DnsServerCore { static class Extensions { readonly static string[] HTTP_METHODS = new string[] { "GET", "POST" }; public static IPEndPoint GetRemoteEndPoint(this HttpContext context, string realIpHeaderName) { try { IPAddress remoteIP = context.Connection.RemoteIpAddress; if (remoteIP is null) return new IPEndPoint(IPAddress.Any, 0); if (remoteIP.IsIPv4MappedToIPv6) remoteIP = remoteIP.MapToIPv4(); if (!string.IsNullOrEmpty(realIpHeaderName) && NetUtilities.IsPrivateIP(remoteIP)) { string xRealIp = context.Request.Headers[realIpHeaderName]; if (IPAddress.TryParse(xRealIp, out IPAddress address)) { //get the real IP address of the requesting client from X-Real-IP header set in nginx proxy_pass block return new IPEndPoint(address, 0); } } return new IPEndPoint(remoteIP, context.Connection.RemotePort); } catch { return new IPEndPoint(IPAddress.Any, 0); } } public static IPAddress GetLocalIpAddress(this HttpContext context) { try { IPAddress localIP = context.Connection.LocalIpAddress; if (localIP is null) return IPAddress.Any; if (localIP.IsIPv4MappedToIPv6) localIP = localIP.MapToIPv4(); return localIP; } catch { return IPAddress.Any; } } public static UserSession GetCurrentSession(this HttpContext context) { if (context.Items["session"] is UserSession userSession) return userSession; throw new InvalidOperationException(); } public static Utf8JsonWriter GetCurrentJsonWriter(this HttpContext context) { if (context.Items["jsonWriter"] is Utf8JsonWriter jsonWriter) return jsonWriter; throw new InvalidOperationException(); } public static IEndpointConventionBuilder MapGetAndPost(this IEndpointRouteBuilder endpoints, string pattern, RequestDelegate requestDelegate) { return endpoints.MapMethods(pattern, HTTP_METHODS, requestDelegate); } public static IEndpointConventionBuilder MapGetAndPost(this IEndpointRouteBuilder endpoints, string pattern, Delegate handler) { return endpoints.MapMethods(pattern, HTTP_METHODS, handler); } public static string QueryOrForm(this HttpRequest request, string parameter) { string value = request.Query[parameter]; if ((value is null) && request.HasFormContentType) value = request.Form[parameter]; return value; } public static string GetQueryOrForm(this HttpRequest request, string parameter) { string value = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(value)) throw new DnsWebServiceException("Parameter '" + parameter + "' missing."); return value; } public static string GetQueryOrForm(this HttpRequest request, string parameter, string defaultValue) { string value = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(value)) return defaultValue; return value; } public static T GetQueryOrForm(this HttpRequest request, string parameter, Func parse) { string value = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(value)) throw new DnsWebServiceException("Parameter '" + parameter + "' missing."); return parse(value); } public static T GetQueryOrFormEnum(this HttpRequest request, string parameter) where T : struct { string value = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(value)) throw new DnsWebServiceException("Parameter '" + parameter + "' missing."); return Enum.Parse(value, true); } public static T GetQueryOrForm(this HttpRequest request, string parameter, Func parse, T defaultValue) { string value = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(value)) return defaultValue; return parse(value); } public static T GetQueryOrFormEnum(this HttpRequest request, string parameter, T defaultValue) where T : struct { string value = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(value)) return defaultValue; return Enum.Parse(value, true); } public static bool TryGetQueryOrForm(this HttpRequest request, string parameter, out string value) { value = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(value)) return false; return true; } public static bool TryGetQueryOrForm(this HttpRequest request, string parameter, Func parse, out T value) { string strValue = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(strValue)) { value = default; return false; } value = parse(strValue); return true; } public static bool TryGetQueryOrFormEnum(this HttpRequest request, string parameter, out T value) where T : struct { string strValue = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(strValue)) { value = default; return false; } return Enum.TryParse(strValue, true, out value); } public static string GetQueryOrFormAlt(this HttpRequest request, string parameter, string alternateParameter) { string value = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(value)) { value = request.QueryOrForm(alternateParameter); if (string.IsNullOrEmpty(value)) throw new DnsWebServiceException("Parameter '" + parameter + "' missing."); } return value; } public static string GetQueryOrFormAlt(this HttpRequest request, string parameter, string alternateParameter, string defaultValue) { string value = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(value)) { value = request.QueryOrForm(alternateParameter); if (string.IsNullOrEmpty(value)) return defaultValue; } return value; } public static T GetQueryOrFormAlt(this HttpRequest request, string parameter, string alternateParameter, Func parse) { string value = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(value)) { value = request.QueryOrForm(alternateParameter); if (string.IsNullOrEmpty(value)) throw new DnsWebServiceException("Parameter '" + parameter + "' missing."); } return parse(value); } public static T GetQueryOrFormAlt(this HttpRequest request, string parameter, string alternateParameter, Func parse, T defaultValue) { string value = request.QueryOrForm(parameter); if (string.IsNullOrEmpty(value)) { value = request.QueryOrForm(alternateParameter); if (string.IsNullOrEmpty(value)) return defaultValue; } return parse(value); } } }