Extensions.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. Technitium DNS Server
  3. Copyright (C) 2023 Shreyas Zare (shreyas@technitium.com)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. using DnsServerCore.Auth;
  16. using Microsoft.AspNetCore.Builder;
  17. using Microsoft.AspNetCore.Http;
  18. using Microsoft.AspNetCore.Routing;
  19. using System;
  20. using System.Net;
  21. using System.Text.Json;
  22. using TechnitiumLibrary.Net;
  23. namespace DnsServerCore
  24. {
  25. static class Extensions
  26. {
  27. readonly static string[] HTTP_METHODS = new string[] { "GET", "POST" };
  28. public static IPEndPoint GetRemoteEndPoint(this HttpContext context, bool ignoreXRealIpHeader = false)
  29. {
  30. try
  31. {
  32. IPAddress remoteIP = context.Connection.RemoteIpAddress;
  33. if (remoteIP is null)
  34. return new IPEndPoint(IPAddress.Any, 0);
  35. if (remoteIP.IsIPv4MappedToIPv6)
  36. remoteIP = remoteIP.MapToIPv4();
  37. if (!ignoreXRealIpHeader && NetUtilities.IsPrivateIP(remoteIP))
  38. {
  39. string xRealIp = context.Request.Headers["X-Real-IP"];
  40. if (IPAddress.TryParse(xRealIp, out IPAddress address))
  41. {
  42. //get the real IP address of the requesting client from X-Real-IP header set in nginx proxy_pass block
  43. return new IPEndPoint(address, 0);
  44. }
  45. }
  46. return new IPEndPoint(remoteIP, context.Connection.RemotePort);
  47. }
  48. catch
  49. {
  50. return new IPEndPoint(IPAddress.Any, 0);
  51. }
  52. }
  53. public static IPAddress GetLocalIpAddress(this HttpContext context)
  54. {
  55. try
  56. {
  57. IPAddress localIP = context.Connection.LocalIpAddress;
  58. if (localIP is null)
  59. return IPAddress.Any;
  60. if (localIP.IsIPv4MappedToIPv6)
  61. localIP = localIP.MapToIPv4();
  62. return localIP;
  63. }
  64. catch
  65. {
  66. return IPAddress.Any;
  67. }
  68. }
  69. public static UserSession GetCurrentSession(this HttpContext context)
  70. {
  71. if (context.Items["session"] is UserSession userSession)
  72. return userSession;
  73. throw new InvalidOperationException();
  74. }
  75. public static Utf8JsonWriter GetCurrentJsonWriter(this HttpContext context)
  76. {
  77. if (context.Items["jsonWriter"] is Utf8JsonWriter jsonWriter)
  78. return jsonWriter;
  79. throw new InvalidOperationException();
  80. }
  81. public static IEndpointConventionBuilder MapGetAndPost(this IEndpointRouteBuilder endpoints, string pattern, RequestDelegate requestDelegate)
  82. {
  83. return endpoints.MapMethods(pattern, HTTP_METHODS, requestDelegate);
  84. }
  85. public static IEndpointConventionBuilder MapGetAndPost(this IEndpointRouteBuilder endpoints, string pattern, Delegate handler)
  86. {
  87. return endpoints.MapMethods(pattern, HTTP_METHODS, handler);
  88. }
  89. public static string QueryOrForm(this HttpRequest request, string parameter)
  90. {
  91. string value = request.Query[parameter];
  92. if ((value is null) && request.HasFormContentType)
  93. value = request.Form[parameter];
  94. return value;
  95. }
  96. public static string GetQueryOrForm(this HttpRequest request, string parameter)
  97. {
  98. string value = request.QueryOrForm(parameter);
  99. if (string.IsNullOrEmpty(value))
  100. throw new DnsWebServiceException("Parameter '" + parameter + "' missing.");
  101. return value;
  102. }
  103. public static string GetQueryOrForm(this HttpRequest request, string parameter, string defaultValue)
  104. {
  105. string value = request.QueryOrForm(parameter);
  106. if (string.IsNullOrEmpty(value))
  107. return defaultValue;
  108. return value;
  109. }
  110. public static T GetQueryOrForm<T>(this HttpRequest request, string parameter, Func<string, T> parse)
  111. {
  112. string value = request.QueryOrForm(parameter);
  113. if (string.IsNullOrEmpty(value))
  114. throw new DnsWebServiceException("Parameter '" + parameter + "' missing.");
  115. return parse(value);
  116. }
  117. public static T GetQueryOrFormEnum<T>(this HttpRequest request, string parameter) where T : struct
  118. {
  119. string value = request.QueryOrForm(parameter);
  120. if (string.IsNullOrEmpty(value))
  121. throw new DnsWebServiceException("Parameter '" + parameter + "' missing.");
  122. return Enum.Parse<T>(value, true);
  123. }
  124. public static T GetQueryOrForm<T>(this HttpRequest request, string parameter, Func<string, T> parse, T defaultValue)
  125. {
  126. string value = request.QueryOrForm(parameter);
  127. if (string.IsNullOrEmpty(value))
  128. return defaultValue;
  129. return parse(value);
  130. }
  131. public static T GetQueryOrFormEnum<T>(this HttpRequest request, string parameter, T defaultValue) where T : struct
  132. {
  133. string value = request.QueryOrForm(parameter);
  134. if (string.IsNullOrEmpty(value))
  135. return defaultValue;
  136. return Enum.Parse<T>(value, true);
  137. }
  138. public static bool TryGetQueryOrForm(this HttpRequest request, string parameter, out string value)
  139. {
  140. value = request.QueryOrForm(parameter);
  141. if (string.IsNullOrEmpty(value))
  142. return false;
  143. return true;
  144. }
  145. public static bool TryGetQueryOrForm<T>(this HttpRequest request, string parameter, Func<string, T> parse, out T value)
  146. {
  147. string strValue = request.QueryOrForm(parameter);
  148. if (string.IsNullOrEmpty(strValue))
  149. {
  150. value = default;
  151. return false;
  152. }
  153. value = parse(strValue);
  154. return true;
  155. }
  156. public static bool TryGetQueryOrFormEnum<T>(this HttpRequest request, string parameter, out T value) where T : struct
  157. {
  158. string strValue = request.QueryOrForm(parameter);
  159. if (string.IsNullOrEmpty(strValue))
  160. {
  161. value = default;
  162. return false;
  163. }
  164. return Enum.TryParse(strValue, true, out value);
  165. }
  166. public static string GetQueryOrFormAlt(this HttpRequest request, string parameter, string alternateParameter)
  167. {
  168. string value = request.QueryOrForm(parameter);
  169. if (string.IsNullOrEmpty(value))
  170. {
  171. value = request.QueryOrForm(alternateParameter);
  172. if (string.IsNullOrEmpty(value))
  173. throw new DnsWebServiceException("Parameter '" + parameter + "' missing.");
  174. }
  175. return value;
  176. }
  177. public static string GetQueryOrFormAlt(this HttpRequest request, string parameter, string alternateParameter, string defaultValue)
  178. {
  179. string value = request.QueryOrForm(parameter);
  180. if (string.IsNullOrEmpty(value))
  181. {
  182. value = request.QueryOrForm(alternateParameter);
  183. if (string.IsNullOrEmpty(value))
  184. return defaultValue;
  185. }
  186. return value;
  187. }
  188. public static T GetQueryOrFormAlt<T>(this HttpRequest request, string parameter, string alternateParameter, Func<string, T> parse)
  189. {
  190. string value = request.QueryOrForm(parameter);
  191. if (string.IsNullOrEmpty(value))
  192. {
  193. value = request.QueryOrForm(alternateParameter);
  194. if (string.IsNullOrEmpty(value))
  195. throw new DnsWebServiceException("Parameter '" + parameter + "' missing.");
  196. }
  197. return parse(value);
  198. }
  199. public static T GetQueryOrFormAlt<T>(this HttpRequest request, string parameter, string alternateParameter, Func<string, T> parse, T defaultValue)
  200. {
  201. string value = request.QueryOrForm(parameter);
  202. if (string.IsNullOrEmpty(value))
  203. {
  204. value = request.QueryOrForm(alternateParameter);
  205. if (string.IsNullOrEmpty(value))
  206. return defaultValue;
  207. }
  208. return parse(value);
  209. }
  210. }
  211. }