KestrelServerOptionsExtensions.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using FastGithub.Configuration;
  2. using FastGithub.ReverseProxy;
  3. using Microsoft.AspNetCore.Hosting;
  4. using Microsoft.AspNetCore.Server.Kestrel.Core;
  5. using Microsoft.Extensions.DependencyInjection;
  6. using Microsoft.Extensions.Logging;
  7. using System;
  8. using System.Linq;
  9. using System.Net;
  10. using System.Net.NetworkInformation;
  11. namespace FastGithub
  12. {
  13. /// <summary>
  14. /// Kestrel扩展
  15. /// </summary>
  16. public static class KestrelServerOptionsExtensions
  17. {
  18. /// <summary>
  19. /// 监听http的反向代理
  20. /// </summary>
  21. /// <param name="kestrel"></param>
  22. public static void ListenHttpReverseProxy(this KestrelServerOptions kestrel)
  23. {
  24. const int HTTP_PORT = 80;
  25. if (OperatingSystem.IsWindows())
  26. {
  27. TcpTable.KillPortOwner(HTTP_PORT);
  28. }
  29. if (CanTcpListen(HTTP_PORT) == false)
  30. {
  31. var loggerFactory = kestrel.ApplicationServices.GetRequiredService<ILoggerFactory>();
  32. var logger = loggerFactory.CreateLogger($"{nameof(FastGithub)}.{nameof(ReverseProxy)}");
  33. logger.LogWarning($"由于tcp端口{HTTP_PORT}已经被其它进程占用,http反向代理功能将受限");
  34. }
  35. else
  36. {
  37. kestrel.Listen(IPAddress.Any, HTTP_PORT);
  38. }
  39. }
  40. /// <summary>
  41. /// 监听https的反向代理
  42. /// </summary>
  43. /// <param name="kestrel"></param>
  44. public static void ListenHttpsReverseProxy(this KestrelServerOptions kestrel)
  45. {
  46. const int HTTPS_PORT = 443;
  47. if (OperatingSystem.IsWindows())
  48. {
  49. TcpTable.KillPortOwner(HTTPS_PORT);
  50. }
  51. if (CanTcpListen(HTTPS_PORT) == false)
  52. {
  53. throw new FastGithubException($"由于tcp端口{HTTPS_PORT}已经被其它进程占用,{nameof(FastGithub)}无法进行必须的https反向代理");
  54. }
  55. var certService = kestrel.ApplicationServices.GetRequiredService<CertService>();
  56. certService.CreateCaCertIfNotExists();
  57. certService.InstallAndTrustCaCert();
  58. kestrel.Listen(IPAddress.Any, HTTPS_PORT, listen =>
  59. listen.UseHttps(https =>
  60. https.ServerCertificateSelector = (ctx, domain) =>
  61. certService.GetOrCreateServerCert(domain)));
  62. }
  63. /// <summary>
  64. /// 是否可以监听指定端口
  65. /// </summary>
  66. /// <param name="port"></param>
  67. /// <returns></returns>
  68. private static bool CanTcpListen(int port)
  69. {
  70. var tcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners();
  71. return tcpListeners.Any(item => item.Port == port) == false;
  72. }
  73. }
  74. }