funnel_http 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c83aef0664b9cea7f66a26b5ef09fd175a9c3ee84163d778b80dc57caab7ad60
4
- data.tar.gz: 7086e25c3a318ae33b59e6524b05ea03ff32c742e242ddde32b449d5e9668dca
3
+ metadata.gz: ca358cfbd282a397a1e8e4458f00c842deb22b8c3715a57bc26dfa171c0394f5
4
+ data.tar.gz: e730cb4d2cc871a82547b6008db1f919243e8102bdd28bfaa95b9838208c38a1
5
5
  SHA512:
6
- metadata.gz: 81fd96f70a60b533d9dc41a41204544b8aa36e57e3464861a933dfc43632d55402543530f8f78e2ab7be9e600bd7f4d7ff6471816a2a01c6edb442eb1713d8b2
7
- data.tar.gz: 97cfe3cd7a61a84772b1059b1100d4391439ea362bd27c090efb3264d4d63d0b21ea7e37b587a73db3a9363a3709e9d14f78edbb115ab95c814deb6eb3fa3343
6
+ metadata.gz: 5b567c0a370a7cdba78948dcb7ab66b97192c9bc227dc2b5da3fc5234fc955cf6e35b22455322a79235fbda3fbe51822765706229c928c5998709aa1808a6bc8
7
+ data.tar.gz: e3d5993b8445e7385c51ad410aa4d2e703c9f397129ae01551f1cb3d31cf5dcbc94c713009f02bb980c0c8c53702bb3dc31504f9e03736da472a43ea606fde31
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
- [full changelog](http://github.com/sue445/funnel_http/compare/v0.2.0...main)
2
+ [full changelog](http://github.com/sue445/funnel_http/compare/v0.3.0...main)
3
+
4
+ ## [0.3.0](https://github.com/sue445/funnel_http/releases/tag/v0.3.0) - 2025-01-12
5
+ [full changelog](http://github.com/sue445/funnel_http/compare/v0.2.0...v0.3.0)
6
+
7
+ * Support request body
8
+ * https://github.com/sue445/funnel_http/pull/51
3
9
 
4
10
  ## [0.2.0](https://github.com/sue445/funnel_http/releases/tag/v0.2.0) - 2025-01-07
5
11
  [full changelog](http://github.com/sue445/funnel_http/compare/v0.1.0...v0.2.0)
data/README.md CHANGED
@@ -45,12 +45,24 @@ requests = [
45
45
  "X-Multiple-Values" => ["1st value", "2nd value"],
46
46
  },
47
47
  },
48
+
49
+ # with request body
50
+ {
51
+ method: :post,
52
+ uri: "https://example.com/api/user",
53
+ header: {
54
+ "Authorization" => "Bearer xxxxxxxx",
55
+ "Content-Type" => "application/json",
56
+ },
57
+ body: '{"name": "sue445"}',
58
+ },
48
59
  ]
49
60
 
50
61
  responses = client.perform(requests)
51
62
  # => [
52
63
  # { status_code: 200, body: "Response of /api/user/1", header: { "Content-Type" => ["text/plain;charset=utf-8"]} }
53
64
  # { status_code: 200, body: "Response of /api/user/2", header: { "Content-Type" => ["text/plain;charset=utf-8"]} }
65
+ # { status_code: 200, body: "Response of /api/user", header: { "Content-Type" => ["text/plain;charset=utf-8"]} }
54
66
  # ]
55
67
  ```
56
68
 
@@ -26,6 +26,7 @@ func rb_funnel_http_run_requests(self C.VALUE, rbAry C.VALUE) C.VALUE {
26
26
  Method: getRbHashValueAsString(rbHash, "method"),
27
27
  URL: getRbHashValueAsString(rbHash, "url"),
28
28
  Header: getRbHashValueAsMap(rbHash, "header"),
29
+ Body: getRbHashValueAsBytes(rbHash, "body"),
29
30
  }
30
31
  requests = append(requests, req)
31
32
  }
@@ -111,6 +112,22 @@ func getRbHashValueAsString(rbHash ruby.VALUE, key string) string {
111
112
  return ruby.Value2String(value)
112
113
  }
113
114
 
115
+ func getRbHashValueAsBytes(rbHash ruby.VALUE, key string) []byte {
116
+ value := ruby.RbHashAref(rbHash, ruby.RbToSymbol(ruby.String2Value(key)))
117
+
118
+ if value == ruby.Qnil() {
119
+ return []byte{}
120
+ }
121
+
122
+ length := ruby.RSTRING_LENINT(value)
123
+ if length == 0 {
124
+ return []byte{}
125
+ }
126
+
127
+ char := ruby.RSTRING_PTR(value)
128
+ return C.GoBytes(unsafe.Pointer(char), C.int(length))
129
+ }
130
+
114
131
  func getRbHashValueAsMap(rbHash ruby.VALUE, key string) map[string][]string {
115
132
  rbHashValue := ruby.RbHashAref(rbHash, ruby.RbToSymbol(ruby.String2Value(key)))
116
133
  rbKeys := ruby.CallFunction(rbHashValue, "keys")
@@ -13,6 +13,7 @@ type Request struct {
13
13
  Method string
14
14
  URL string
15
15
  Header map[string][]string
16
+ Body []byte
16
17
  }
17
18
 
18
19
  // Response is proxy between CRuby and Go
@@ -33,8 +34,7 @@ func RunRequests(httpClient *http.Client, requests []Request) ([]Response, error
33
34
  request := request
34
35
 
35
36
  g.Go(func() error {
36
- var body []byte
37
- httpReq, err := http.NewRequest(request.Method, request.URL, bytes.NewBuffer(body))
37
+ httpReq, err := http.NewRequest(request.Method, request.URL, bytes.NewBuffer(request.Body))
38
38
  if err != nil {
39
39
  return errors.WithStack(err)
40
40
  }
@@ -1,9 +1,11 @@
1
1
  package main_test
2
2
 
3
3
  import (
4
+ "github.com/cockroachdb/errors"
4
5
  "github.com/jarcoal/httpmock"
5
6
  "github.com/stretchr/testify/assert"
6
7
  "github.com/sue445/funnel_http"
8
+ "io"
7
9
  "net/http"
8
10
  "testing"
9
11
  )
@@ -42,13 +44,33 @@ func TestRunRequests(t *testing.T) {
42
44
  return resp, nil
43
45
  })
44
46
 
47
+ httpmock.RegisterResponder("POST", "http://example.com/1",
48
+ func(req *http.Request) (*http.Response, error) {
49
+ payload, err := io.ReadAll(req.Body)
50
+ if err != nil {
51
+ return nil, errors.WithStack(err)
52
+ }
53
+
54
+ resp := httpmock.NewStringResponse(200, string(payload))
55
+
56
+ resp.Header.Set("Content-Type", "text/plain")
57
+
58
+ for key, values := range req.Header {
59
+ for _, value := range values {
60
+ resp.Header.Add(key, value)
61
+ }
62
+ }
63
+
64
+ return resp, nil
65
+ })
66
+
45
67
  tests := []struct {
46
68
  name string
47
69
  requests []main.Request
48
70
  expected []main.Response
49
71
  }{
50
72
  {
51
- name: "1 request",
73
+ name: "GET 1 request",
52
74
  requests: []main.Request{
53
75
  {
54
76
  Method: "GET",
@@ -70,7 +92,7 @@ func TestRunRequests(t *testing.T) {
70
92
  },
71
93
  },
72
94
  {
73
- name: "multiple requests",
95
+ name: "GET multiple requests",
74
96
  requests: []main.Request{
75
97
  {
76
98
  Method: "GET",
@@ -106,6 +128,68 @@ func TestRunRequests(t *testing.T) {
106
128
  },
107
129
  },
108
130
  },
131
+ {
132
+ name: "POST 1 request",
133
+ requests: []main.Request{
134
+ {
135
+ Method: "POST",
136
+ URL: "http://example.com/1",
137
+ Header: map[string][]string{
138
+ "X-My-Request-Header": {"a", "b"},
139
+ },
140
+ Body: []byte("111"),
141
+ },
142
+ },
143
+ expected: []main.Response{
144
+ {
145
+ StatusCode: 200,
146
+ Body: []byte("111"),
147
+ Header: map[string][]string{
148
+ "Content-Type": {"text/plain"},
149
+ "X-My-Request-Header": {"a", "b"},
150
+ },
151
+ },
152
+ },
153
+ },
154
+ {
155
+ name: "POST multiple requests",
156
+ requests: []main.Request{
157
+ {
158
+ Method: "POST",
159
+ URL: "http://example.com/1",
160
+ Header: map[string][]string{
161
+ "X-My-Request-Header": {"a", "b"},
162
+ },
163
+ Body: []byte("111"),
164
+ },
165
+ {
166
+ Method: "POST",
167
+ URL: "http://example.com/1",
168
+ Header: map[string][]string{
169
+ "X-My-Request-Header": {"c", "d"},
170
+ },
171
+ Body: []byte("222"),
172
+ },
173
+ },
174
+ expected: []main.Response{
175
+ {
176
+ StatusCode: 200,
177
+ Body: []byte("111"),
178
+ Header: map[string][]string{
179
+ "Content-Type": {"text/plain"},
180
+ "X-My-Request-Header": {"a", "b"},
181
+ },
182
+ },
183
+ {
184
+ StatusCode: 200,
185
+ Body: []byte("222"),
186
+ Header: map[string][]string{
187
+ "Content-Type": {"text/plain"},
188
+ "X-My-Request-Header": {"c", "d"},
189
+ },
190
+ },
191
+ },
192
+ },
109
193
  }
110
194
 
111
195
  httpClient := http.Client{}
@@ -27,12 +27,14 @@ module FunnelHttp
27
27
  # @option requests :method [String, Symbol] **[required]** Request method (e.g. `:get`, `"POST"`)
28
28
  # @option requests :url [String] **[required]** Request url
29
29
  # @option requests :header [Hash{String => String, Array<String>}, nil] Request header
30
+ # @option requests :body [String, nil] Request body
30
31
  #
31
32
  # @overload perform(request)
32
33
  # @param request [Hash{Symbol => Object}]
33
34
  # @option request :method [String, Symbol] **[required]** Request method (e.g. `:get`, `"POST"`)
34
35
  # @option request :url [String] **[required]** Request url
35
36
  # @option request :header [Hash{String => String, Array<String>}, nil] Request header
37
+ # @option request :body [String, nil] Request body
36
38
  #
37
39
  # @return [Array<Hash<Symbol => Object>>] `Array` of following `Hash`
38
40
  # @return [Integer] `:status_code`
@@ -78,6 +80,7 @@ module FunnelHttp
78
80
  url: request[:url].to_s,
79
81
  method: request[:method].to_s.upcase,
80
82
  header: normalize_header(request[:header]),
83
+ body: request[:body].freeze,
81
84
  }
82
85
  end
83
86
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FunnelHttp
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/sig/funnel_http.rbs CHANGED
@@ -10,7 +10,8 @@ module FunnelHttp
10
10
  type fuzzy_request = {
11
11
  method: String | Symbol,
12
12
  url: String,
13
- header: fuzzy_header?
13
+ header: fuzzy_header?,
14
+ body: String?,
14
15
  }
15
16
 
16
17
  type strict_header = Hash[String, Array[String]]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: funnel_http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sue445
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-01-07 00:00:00.000000000 Z
10
+ date: 2025-01-12 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: go_gem