KestrelServerOptionsExtensions.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using FastGithub.Configuration;
  2. using FastGithub.HttpServer;
  3. using Microsoft.AspNetCore.Connections;
  4. using Microsoft.AspNetCore.Hosting;
  5. using Microsoft.AspNetCore.Server.Kestrel.Core;
  6. using Microsoft.Extensions.DependencyInjection;
  7. using Microsoft.Extensions.Logging;
  8. using Microsoft.Extensions.Options;
  9. using System;
  10. using System.Linq;
  11. using System.Net.NetworkInformation;
  12. namespace FastGithub
  13. {
  14. /// <summary>
  15. /// Kestrel扩展
  16. /// </summary>
  17. public static class KestrelServerOptionsExtensions
  18. {
  19. /// <summary>
  20. /// 无限制
  21. /// </summary>
  22. /// <param name="kestrel"></param>
  23. public static void NoLimit(this KestrelServerOptions kestrel)
  24. {
  25. kestrel.Limits.MaxRequestBodySize = null;
  26. kestrel.Limits.MinResponseDataRate = null;
  27. kestrel.Limits.MinRequestBodyDataRate = null;
  28. }
  29. /// <summary>
  30. /// 监听http代理
  31. /// </summary>
  32. /// <param name="kestrel"></param>
  33. public static void ListenHttpProxy(this KestrelServerOptions kestrel)
  34. {
  35. var options = kestrel.ApplicationServices.GetRequiredService<IOptions<FastGithubOptions>>().Value;
  36. var httpProxyPort = options.HttpProxyPort;
  37. if (CanListenTcp(httpProxyPort) == false)
  38. {
  39. throw new FastGithubException($"tcp端口{httpProxyPort}已经被其它进程占用,请在配置文件更换{nameof(FastGithubOptions.HttpProxyPort)}为其它端口");
  40. }
  41. var logger = kestrel.GetLogger();
  42. kestrel.ListenLocalhost(httpProxyPort);
  43. logger.LogInformation($"已监听http://localhost:{httpProxyPort},http代理服务启动完成");
  44. }
  45. /// <summary>
  46. /// 尝试监听ssh反向代理
  47. /// </summary>
  48. /// <param name="kestrel"></param>
  49. public static void ListenSshReverseProxy(this KestrelServerOptions kestrel)
  50. {
  51. var sshPort = ReverseProxyPort.Ssh;
  52. kestrel.ListenLocalhost(sshPort, listen =>
  53. {
  54. listen.UseFlowAnalyze();
  55. listen.UseConnectionHandler<SshReverseProxyHandler>();
  56. });
  57. if (OperatingSystem.IsWindows())
  58. {
  59. kestrel.GetLogger().LogInformation($"已监听ssh://localhost:{sshPort},github的ssh反向代理服务启动完成");
  60. }
  61. }
  62. /// <summary>
  63. /// 尝试监听http反向代理
  64. /// </summary>
  65. /// <param name="kestrel"></param>
  66. public static void ListenHttpReverseProxy(this KestrelServerOptions kestrel)
  67. {
  68. var httpPort = ReverseProxyPort.Http;
  69. kestrel.ListenLocalhost(httpPort);
  70. if (OperatingSystem.IsWindows())
  71. {
  72. kestrel.GetLogger().LogInformation($"已监听http://localhost:{httpPort},http反向代理服务启动完成");
  73. }
  74. }
  75. /// <summary>
  76. /// 监听https反向代理
  77. /// </summary>
  78. /// <param name="kestrel"></param>
  79. /// <exception cref="FastGithubException"></exception>
  80. public static void ListenHttpsReverseProxy(this KestrelServerOptions kestrel)
  81. {
  82. var certService = kestrel.ApplicationServices.GetRequiredService<CertService>();
  83. certService.CreateCaCertIfNotExists();
  84. certService.InstallAndTrustCaCert();
  85. var httpsPort = ReverseProxyPort.Https;
  86. kestrel.ListenLocalhost(httpsPort, listen =>
  87. {
  88. if (OperatingSystem.IsWindows())
  89. {
  90. listen.UseFlowAnalyze();
  91. }
  92. listen.UseHttps(https =>
  93. {
  94. https.ServerCertificateSelector = (ctx, domain) => certService.GetOrCreateServerCert(domain);
  95. });
  96. });
  97. if (OperatingSystem.IsWindows())
  98. {
  99. var logger = kestrel.GetLogger();
  100. logger.LogInformation($"已监听https://localhost:{httpsPort},https反向代理服务启动完成");
  101. }
  102. }
  103. /// <summary>
  104. /// 获取日志
  105. /// </summary>
  106. /// <param name="kestrel"></param>
  107. /// <returns></returns>
  108. private static ILogger GetLogger(this KestrelServerOptions kestrel)
  109. {
  110. var loggerFactory = kestrel.ApplicationServices.GetRequiredService<ILoggerFactory>();
  111. return loggerFactory.CreateLogger($"{nameof(FastGithub)}.{nameof(HttpServer)}");
  112. }
  113. /// <summary>
  114. /// 是否可以监听指定tcp端口
  115. /// </summary>
  116. /// <param name="port"></param>
  117. /// <returns></returns>
  118. private static bool CanListenTcp(int port)
  119. {
  120. var tcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners();
  121. return tcpListeners.Any(item => item.Port == port) == false;
  122. }
  123. }
  124. }