CurlServer.go 4.7 KB

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