url_connectedness_helper.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package url_connectedness_helper
  2. import (
  3. "errors"
  4. "net/http"
  5. "net/url"
  6. "regexp"
  7. "time"
  8. )
  9. // UrlConnectednessTest 测试输入 url 的连通性
  10. func UrlConnectednessTest(testUrl, proxyAddr string) (bool, int, error) {
  11. var httpClient http.Client
  12. if proxyAddr == "" {
  13. // 无需代理
  14. // 创建连接客户端
  15. httpClient = http.Client{
  16. Timeout: time.Second * testUrlTimeOut,
  17. }
  18. } else {
  19. // 需要代理
  20. // 检测代理iP访问地址
  21. if proxyAddressValidHttpFormat(proxyAddr) == false {
  22. return false, 0, errors.New("proxy address illegal, only support http://xx:xx")
  23. }
  24. // 解析代理地址
  25. proxy, err := url.Parse(proxyAddr)
  26. if err != nil {
  27. return false, 0, err
  28. }
  29. // 设置网络传输
  30. netTransport := &http.Transport{
  31. Proxy: http.ProxyURL(proxy),
  32. MaxIdleConnsPerHost: 10,
  33. ResponseHeaderTimeout: time.Second * time.Duration(testUrlTimeOut),
  34. }
  35. // 创建连接客户端
  36. httpClient = http.Client{
  37. Timeout: time.Second * testUrlTimeOut,
  38. Transport: netTransport,
  39. }
  40. }
  41. begin := time.Now() //判断代理访问时间
  42. // 使用代理IP访问测试地址
  43. res, err := httpClient.Get(testUrl)
  44. if err != nil {
  45. return false, 0, err
  46. }
  47. defer func() {
  48. _ = res.Body.Close()
  49. }()
  50. speed := int(time.Now().Sub(begin).Nanoseconds() / 1000 / 1000) //ms
  51. // 判断是否成功访问,如果成功访问StatusCode应该为200
  52. if res.StatusCode != http.StatusOK {
  53. return false, 0, nil
  54. }
  55. return true, speed, nil
  56. }
  57. // proxyAddressValidHttpFormat 代理地址是否是有效的格式,必须是 http 的代理
  58. func proxyAddressValidHttpFormat(proxyAddr string) bool {
  59. // 首先检测 proxyAddr 是否合法,必须是 http 的代理,不支持 https 代理
  60. re := regexp.MustCompile(`(http):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?`)
  61. result := re.FindAllStringSubmatch(proxyAddr, -1)
  62. if result == nil || len(result) < 1 {
  63. return false
  64. }
  65. return true
  66. }
  67. const testUrlTimeOut = 5