CurlServer.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package curlServer
  2. import (
  3. curl2 "cfTest/curlServer/pb"
  4. "context"
  5. "github.com/sirupsen/logrus"
  6. "gopkg.in/natefinch/lumberjack.v2"
  7. "io"
  8. "net"
  9. "net/http"
  10. "runtime"
  11. "strings"
  12. "time"
  13. )
  14. var logger *logrus.Logger
  15. type CurlServer struct {
  16. curl2.UnimplementedCurlWithResolveServer
  17. }
  18. func (s *CurlServer) CurlWithResolveParam(ctx context.Context, requestCurlObject *curl2.CurlRequest) (*curl2.CurlReply, error) {
  19. logger.Println("url Received: ", requestCurlObject.GetUrl())
  20. logger.Println("ip Received: ", requestCurlObject.GetIp())
  21. logger.Println("ua Received: ", requestCurlObject.GetUa())
  22. logger.Println("UseHeadMethod Received: ", requestCurlObject.GetUseHeadMethod())
  23. // ua
  24. var ua = ""
  25. if len(requestCurlObject.GetUa()) == 0 {
  26. ua = generateDefaultUserAgent()
  27. } else {
  28. ua = requestCurlObject.GetUa()
  29. }
  30. // Server
  31. // 创建一个自定义的 Transport
  32. transport := &CustomTransport{
  33. Transport: &http.Transport{
  34. DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
  35. dialer := &net.Dialer{
  36. Timeout: 30 * time.Second,
  37. KeepAlive: 30 * time.Second,
  38. DualStack: true,
  39. }
  40. // 修改addr -> 指向IP地址
  41. addr = requestCurlObject.GetIp() + ":443"
  42. logger.Println("addr = ", addr)
  43. conn, err := dialer.DialContext(ctx, network, addr)
  44. if err != nil {
  45. logger.Error("TCP连接异常: " + err.Error())
  46. return nil, err
  47. }
  48. return conn, nil
  49. },
  50. },
  51. // 指定UA
  52. UserAgent: ua,
  53. UseHeadMethod: requestCurlObject.GetUseHeadMethod(),
  54. }
  55. // 创建一个使用自定义 Transport 的 HTTP 客户端
  56. client := &http.Client{
  57. Transport: transport,
  58. }
  59. // 创建一个GET请求, 将转义字符重新转换
  60. originalUrl := strings.Replace(requestCurlObject.GetUrl(), "%5B", "[", -1)
  61. originalUrl = strings.Replace(originalUrl, "%5D", "]", -1)
  62. originalUrl = strings.Replace(originalUrl, "%20", " ", -1)
  63. originalUrl = strings.Replace(originalUrl, "%7B", "{", -1)
  64. originalUrl = strings.Replace(originalUrl, "%7D", "}", -1)
  65. originalUrl = strings.Replace(originalUrl, "%22", "\"", -1)
  66. originalUrl = strings.Replace(originalUrl, "%26", "&", -1)
  67. logger.Println(originalUrl)
  68. // 发起 HTTP 请求
  69. resp, err := client.Get(originalUrl)
  70. if err != nil {
  71. logger.Error("发送HTTP请求出错, e:" + err.Error() + ", url: " + requestCurlObject.GetUrl())
  72. return nil, err
  73. }
  74. defer resp.Body.Close()
  75. // 解析响应结果
  76. logger.Println("Code = ", resp.StatusCode)
  77. _, err = io.ReadAll(resp.Body)
  78. if err != nil {
  79. logger.Error(err.Error())
  80. return nil, err
  81. }
  82. logger.Println("header = ", resp.Header)
  83. return &curl2.CurlReply{
  84. Code: int32(resp.StatusCode),
  85. ContentLength: resp.ContentLength,
  86. }, nil
  87. }
  88. type CustomTransport struct {
  89. Transport http.RoundTripper
  90. UserAgent string
  91. UseHeadMethod bool
  92. }
  93. func (t *CustomTransport) RoundTrip(req *http.Request) (*http.Response, error) {
  94. req.Header.Set("User-Agent", t.UserAgent)
  95. if t.UseHeadMethod {
  96. req.Method = http.MethodHead
  97. }
  98. return t.Transport.RoundTrip(req)
  99. }
  100. func generateDefaultUserAgent() string {
  101. // 获取操作系统名称和版本号
  102. osInfo := runtime.GOOS
  103. // 获取编程语言和版本号
  104. langInfo := "Go/" + runtime.Version()
  105. // 获取应用程序运行时的信息
  106. appInfo := "Executor/1.0"
  107. return appInfo + " (" + osInfo + "; " + langInfo + ")"
  108. }
  109. func InitLogger() {
  110. setupLogger()
  111. // 在初始化函数中对包级别的变量进行初始化
  112. logger = logrus.StandardLogger()
  113. logger.Println("启动CurlServer, 初始化日志框架...")
  114. }
  115. func setupLogger() {
  116. // 创建一个新的logrus实例
  117. log := logrus.New()
  118. // 设置日志输出为文件,并使用lumberjack库来实现每天生成一个新的日志文件,并保存旧日志文件
  119. log.SetOutput(&lumberjack.Logger{
  120. Filename: "../../logs/curlServer/" + generateLogFileName(), // 日志文件路径,使用日期占位符%Y-%m-%d
  121. MaxSize: 20, // 每个日志文件的最大尺寸,单位:MB
  122. MaxBackups: 3, // 最多保留的旧日志文件数
  123. MaxAge: 30, // 最多保留的旧日志文件天数(这里设置为30天)
  124. LocalTime: true, // 使用本地时间(默认为UTC时间)
  125. Compress: true, // 是否压缩旧日志文件
  126. })
  127. // 设置日志格式为JSON格式
  128. log.SetFormatter(&logrus.JSONFormatter{})
  129. // 设置日志级别为Debug
  130. log.SetLevel(logrus.DebugLevel)
  131. // 将logrus实例设置为全局的默认日志记录器
  132. logrus.StandardLogger().SetOutput(log.Out)
  133. }
  134. func generateLogFileName() string {
  135. currentDate := time.Now().Format("01-02-2006")
  136. return "curl_" + currentDate + ".log"
  137. }
  138. func GetLogger() *logrus.Logger {
  139. return logger
  140. }