http_request.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package http_requests
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/json"
  6. "io"
  7. "mime/multipart"
  8. "net/http"
  9. "strings"
  10. "time"
  11. )
  12. func buildHttpRequest(method string, url string, options ...HttpOptions) (*http.Request, error) {
  13. req, err := http.NewRequest(method, url, nil)
  14. if err != nil {
  15. return nil, err
  16. }
  17. for _, option := range options {
  18. switch option.Type {
  19. case "write_timeout":
  20. timeout := time.Second * time.Duration(option.Value.(int64))
  21. ctx, cancel := context.WithTimeout(context.Background(), timeout)
  22. time.AfterFunc(timeout, cancel) // release resources associated with context asynchronously
  23. req = req.WithContext(ctx)
  24. case "header":
  25. for k, v := range option.Value.(map[string]string) {
  26. req.Header.Set(k, v)
  27. }
  28. case "params":
  29. q := req.URL.Query()
  30. for k, v := range option.Value.(map[string]string) {
  31. q.Add(k, v)
  32. }
  33. req.URL.RawQuery = q.Encode()
  34. case "payload":
  35. q := req.URL.Query()
  36. for k, v := range option.Value.(map[string]string) {
  37. q.Add(k, v)
  38. }
  39. req.Body = io.NopCloser(strings.NewReader(q.Encode()))
  40. case "payloadMultipart":
  41. buffer := new(bytes.Buffer)
  42. writer := multipart.NewWriter(buffer)
  43. files := option.Value.(map[string]any)["files"].(map[string]HttpPayloadMultipartFile)
  44. for filename, file := range files {
  45. part, err := writer.CreateFormFile(filename, file.Filename)
  46. if err != nil {
  47. writer.Close()
  48. return nil, err
  49. }
  50. _, err = io.Copy(part, file.Reader)
  51. if err != nil {
  52. writer.Close()
  53. return nil, err
  54. }
  55. }
  56. payload := option.Value.(map[string]any)["payload"].(map[string]string)
  57. for k, v := range payload {
  58. if err := writer.WriteField(k, v); err != nil {
  59. writer.Close()
  60. return nil, err
  61. }
  62. }
  63. if err := writer.Close(); err != nil {
  64. return nil, err
  65. }
  66. req.Body = io.NopCloser(buffer)
  67. req.Header.Set("Content-Type", writer.FormDataContentType())
  68. case "payloadText":
  69. req.Body = io.NopCloser(strings.NewReader(option.Value.(string)))
  70. req.Header.Set("Content-Type", "text/plain")
  71. case "payloadJson":
  72. jsonStr, err := json.Marshal(option.Value)
  73. if err != nil {
  74. return nil, err
  75. }
  76. req.Body = io.NopCloser(bytes.NewBuffer(jsonStr))
  77. // set application/json content type
  78. req.Header.Set("Content-Type", "application/json")
  79. case "directReferer":
  80. req.Header.Set("Referer", url)
  81. }
  82. }
  83. return req, nil
  84. }
  85. func Request(client *http.Client, url string, method string, options ...HttpOptions) (*http.Response, error) {
  86. req, err := buildHttpRequest(method, url, options...)
  87. if err != nil {
  88. return nil, err
  89. }
  90. resp, err := client.Do(req)
  91. if err != nil {
  92. return nil, err
  93. }
  94. return resp, nil
  95. }