http_worker.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // package http_worker -- веб-воркер бота
  2. package http_worker
  3. import (
  4. "context"
  5. "fmt"
  6. "io"
  7. "net/http"
  8. "strings"
  9. "sync"
  10. "time"
  11. "wartank/pkg/components/arena_net/http_worker/net_stat"
  12. "wartank/pkg/components/kernel/logger"
  13. "wartank/pkg/types"
  14. )
  15. var (
  16. блок sync.Mutex
  17. )
  18. // ХттпВоркер -- объект сетевого исполнителя бота
  19. type ХттпВоркер struct {
  20. botNet types.ИБотСеть
  21. conn *http.Client
  22. статистика *net_stat.СетьСтата
  23. лог types.ИЛоггер
  24. }
  25. // НовХттпВоркер -- возвращает веб-воркера бота
  26. func НовХттпВоркер(botNet types.ИБотСеть, conn *http.Client) *ХттпВоркер {
  27. лог := logger.НовЛоггер("ХттпВоркер")
  28. лог.Инфо("НовХттпВоркер()\n")
  29. сам := &ХттпВоркер{
  30. botNet: botNet,
  31. conn: conn,
  32. статистика: net_stat.НовСетьСтата(botNet),
  33. лог: лог,
  34. }
  35. _ = types.ИХттпВоркер(сам)
  36. return сам
  37. }
  38. // Получ -- потокобезопасно возвращает список строк по ссылке
  39. func (сам *ХттпВоркер) Получ(strLink string) ([]string, error) {
  40. блок.Lock()
  41. defer блок.Unlock()
  42. // if strLink == "https://wartank.ru/production/Mine" {
  43. сам.лог.Отладка("Получ(): link=%v\n", strLink)
  44. // }
  45. ctxCancel, fnCancel := context.WithTimeout(сам.botNet.Контекст(), time.Second*10)
  46. defer fnCancel()
  47. запрос, ош := http.NewRequestWithContext(ctxCancel, "GET", strLink, nil)
  48. if ош != nil {
  49. сам.статистика.IncErr()
  50. return nil, fmt.Errorf("ХттпВоркер.Получ(): при создании запроса, err=\n\t%w", ош)
  51. }
  52. запрос.Header.Set("User-Agent", "Mozilla Firefox 106.1")
  53. ответ, ош := сам.conn.Do(запрос)
  54. if ош != nil {
  55. сам.статистика.IncErr()
  56. return nil, fmt.Errorf("ХттпВоркер.Получ(): при выполнении GET-запроса, err=\n\t%w", ош)
  57. }
  58. defer ответ.Body.Close()
  59. if ответ.StatusCode != http.StatusOK {
  60. сам.статистика.IncErr()
  61. return nil, fmt.Errorf("ХттпВоркер.Получ(): code=%v, status=%v", ответ.StatusCode, ответ.Status)
  62. }
  63. binData, ош := io.ReadAll(ответ.Body)
  64. if ош != nil {
  65. сам.статистика.IncErr()
  66. return nil, fmt.Errorf("ХттпВоркер.Получ(): при чтении тела ответа, err=\n\t%w", ош)
  67. }
  68. if len(binData) == 0 {
  69. сам.статистика.IncErr()
  70. return nil, fmt.Errorf("ХттпВоркер.Получ(): пустое тело ответа, err=\n\t%w", ош)
  71. }
  72. lenData := len(binData) + len(strLink)
  73. сам.статистика.AddByte(lenData)
  74. lstString := strings.Split(string(binData), "\n")
  75. if len(lstString) == 0 {
  76. сам.статистика.IncErr()
  77. return nil, fmt.Errorf("ХттпВоркер.Получ(): lstString is empty")
  78. }
  79. return lstString, nil
  80. }