http_client.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package fairwind
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "net/http"
  9. "strings"
  10. "time"
  11. )
  12. type HTTPClientRequest struct {
  13. Data string
  14. Object any
  15. Encoding int
  16. }
  17. type HTTPCLientResponse struct {
  18. Raw []byte
  19. Object any
  20. Encoding int
  21. }
  22. type HTTPClient struct {
  23. scheme string
  24. host string
  25. port string
  26. }
  27. func NewHTTPClient(scheme string, host string, port string) *HTTPClient {
  28. return &HTTPClient{
  29. scheme: scheme,
  30. host: host,
  31. port: port,
  32. }
  33. }
  34. func (this *HTTPClient) Request(timeout int, method int, path string, headers HTTPHeaders, request *HTTPClientRequest, response *HTTPCLientResponse) error {
  35. buffer, err := json.Marshal(request.Object)
  36. if err != nil {
  37. return err
  38. }
  39. var requestInternal *http.Request
  40. if method == METHOD_GET {
  41. requestInternal, err = http.NewRequest(
  42. "GET",
  43. fmt.Sprintf("%s://%s:%s%s", this.scheme, this.host, this.port, path),
  44. nil,
  45. )
  46. }
  47. if method == METHOD_POST {
  48. requestInternal, err = http.NewRequest(
  49. "POST",
  50. fmt.Sprintf("%s://%s:%s%s", this.scheme, this.host, this.port, path),
  51. bytes.NewBuffer(buffer),
  52. )
  53. }
  54. if err != nil {
  55. return err
  56. }
  57. for key, value := range headers {
  58. requestInternal.Header.Add(key, value)
  59. }
  60. client := &http.Client{
  61. Timeout: time.Duration(timeout) * time.Millisecond,
  62. }
  63. responseInternal, err := client.Do(requestInternal)
  64. if err != nil {
  65. return err
  66. }
  67. if responseInternal.StatusCode != http.StatusOK {
  68. return fmt.Errorf("invalid status = %d", responseInternal.StatusCode)
  69. }
  70. buffer, err = io.ReadAll(responseInternal.Body)
  71. if err != nil {
  72. return err
  73. }
  74. contentTypeHeader := responseInternal.Header.Get("Content-Type")
  75. if contentTypeHeader == "" {
  76. return errors.New("content-type not specified")
  77. }
  78. var contentType string
  79. if contentTypeHeader == "text/plain" || contentTypeHeader == "application/json" || contentTypeHeader == "application/octet-stream" {
  80. contentType = contentTypeHeader
  81. } else {
  82. parts := strings.Split(contentTypeHeader, ";")
  83. if len(parts) != 2 {
  84. return errors.New("content-type invalid")
  85. }
  86. contentType = parts[0]
  87. }
  88. switch contentType {
  89. case "text/plain":
  90. case "application/octet-stream":
  91. response.Raw = buffer
  92. case "application/json":
  93. err = json.Unmarshal(buffer, response.Object)
  94. if err != nil {
  95. return err
  96. }
  97. }
  98. return nil
  99. }