surf.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package surfer
  2. import (
  3. "crypto/tls"
  4. "math/rand"
  5. "net"
  6. "net/http"
  7. "net/http/cookiejar"
  8. "strings"
  9. "time"
  10. "github.com/surfer/agent"
  11. )
  12. // Default is the default Download implementation.
  13. type Surf struct {
  14. cookieJar *cookiejar.Jar
  15. }
  16. func New() Surfer {
  17. s := new(Surf)
  18. s.cookieJar, _ = cookiejar.New(nil)
  19. return s
  20. }
  21. func (self *Surf) Download(req Request) (resp *http.Response, err error) {
  22. param, err := NewParam(req)
  23. if err != nil {
  24. return nil, err
  25. }
  26. param.client = self.buildClient(param)
  27. resp, err = self.httpRequest(param)
  28. resp = param.writeback(resp)
  29. // if err != nil {
  30. // resp.Status = "200 OK"
  31. // resp.StatusCode = 200
  32. // }
  33. return
  34. }
  35. // buildClient creates, configures, and returns a *http.Client type.
  36. func (self *Surf) buildClient(param *Param) *http.Client {
  37. client := &http.Client{
  38. CheckRedirect: param.checkRedirect,
  39. }
  40. if param.enableCookie {
  41. client.Jar = self.cookieJar
  42. }
  43. transport := &http.Transport{
  44. DisableKeepAlives: true,
  45. Dial: func(network, addr string) (net.Conn, error) {
  46. c, err := net.DialTimeout(network, addr, param.dialTimeout)
  47. if err != nil {
  48. return nil, err
  49. }
  50. if param.connTimeout > 0 {
  51. c.SetDeadline(time.Now().Add(param.connTimeout))
  52. }
  53. return c, nil
  54. },
  55. }
  56. if param.proxy != nil {
  57. transport.Proxy = http.ProxyURL(param.proxy)
  58. }
  59. if strings.ToLower(param.url.Scheme) == "https" {
  60. transport.TLSClientConfig = &tls.Config{RootCAs: nil, InsecureSkipVerify: true}
  61. transport.DisableCompression = true
  62. }
  63. client.Transport = transport
  64. return client
  65. }
  66. // send uses the given *http.Request to make an HTTP request.
  67. func (self *Surf) httpRequest(param *Param) (resp *http.Response, err error) {
  68. req, err := http.NewRequest(param.method, param.url.String(), param.body)
  69. if err != nil {
  70. return nil, err
  71. }
  72. req.Header = param.header
  73. if param.tryTimes <= 0 {
  74. for {
  75. resp, err = param.client.Do(req)
  76. if err != nil {
  77. if !param.enableCookie {
  78. l := len(agent.UserAgents["common"])
  79. r := rand.New(rand.NewSource(time.Now().UnixNano()))
  80. req.Header.Set("User-Agent", agent.UserAgents["common"][r.Intn(l)])
  81. }
  82. time.Sleep(param.retryPause)
  83. continue
  84. }
  85. break
  86. }
  87. } else {
  88. for i := 0; i < param.tryTimes; i++ {
  89. resp, err = param.client.Do(req)
  90. if err != nil {
  91. if !param.enableCookie {
  92. l := len(agent.UserAgents["common"])
  93. r := rand.New(rand.NewSource(time.Now().UnixNano()))
  94. req.Header.Set("User-Agent", agent.UserAgents["common"][r.Intn(l)])
  95. }
  96. time.Sleep(param.retryPause)
  97. continue
  98. }
  99. break
  100. }
  101. }
  102. return resp, err
  103. }