package server import ( curl "cfTest/curl" "context" "io" "log" "net" "net/http" "runtime" "time" ) type CurlServer struct { curl.UnimplementedCurlWithResolveServer } func (s *CurlServer) CurlWithResolveParam(ctx context.Context, requestCurlObject *curl.CurlRequest) (*curl.CurlReply, error) { log.Printf("url Received: %v", requestCurlObject.GetUrl()) log.Printf("ip Received: %v", requestCurlObject.GetIp()) log.Printf("UA Received: %v", requestCurlObject.GetUA()) log.Printf("UseHeadMethod Received: %v", requestCurlObject.GetUseHeadMethod()) // UA var UA = "" if len(requestCurlObject.GetUA()) == 0 { UA = generateDefaultUserAgent() } else { UA = requestCurlObject.GetUA() } // Server // 创建一个自定义的 Transport transport := &CustomTransport{ Transport: &http.Transport{ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { dialer := &net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, DualStack: true, } // 修改addr -> 指向IP地址 addr = requestCurlObject.GetIp() + ":443" log.Println("addr = ", addr) conn, err := dialer.DialContext(ctx, network, addr) if err != nil { return nil, err } return conn, nil }, }, // 指定UA UserAgent: UA, UseHeadMethod: requestCurlObject.GetUseHeadMethod(), } // 创建一个使用自定义 Transport 的 HTTP 客户端 client := &http.Client{ Transport: transport, } // 发起 HTTP 请求 resp, err := client.Get(requestCurlObject.GetUrl()) if err != nil { return nil, err } defer resp.Body.Close() // 解析响应结果 log.Println("Code = ", resp.StatusCode) body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } log.Println("Body = ", string(body)) log.Println("header = ", resp.Header) return &curl.CurlReply{ Code: int32(resp.StatusCode), Body: string(body), }, nil } type CustomTransport struct { Transport http.RoundTripper UserAgent string UseHeadMethod bool } func (t *CustomTransport) RoundTrip(req *http.Request) (*http.Response, error) { req.Header.Set("User-Agent", t.UserAgent) if t.UseHeadMethod { req.Method = http.MethodHead } return t.Transport.RoundTrip(req) } func generateDefaultUserAgent() string { // 获取操作系统名称和版本号 osInfo := runtime.GOOS // 获取编程语言和版本号 langInfo := "Go/" + runtime.Version() // 获取应用程序运行时的信息 appInfo := "Executor/1.0" return appInfo + " (" + osInfo + "; " + langInfo + ")" }