http_client.go 2.2 KB

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