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 +4 -4
- data/CHANGELOG.md +7 -1
- data/README.md +12 -0
- data/ext/funnel_http/funnel_http.go +17 -0
- data/ext/funnel_http/run_requests.go +2 -2
- data/ext/funnel_http/run_requests_test.go +86 -2
- data/lib/funnel_http/client.rb +3 -0
- data/lib/funnel_http/version.rb +1 -1
- data/sig/funnel_http.rbs +2 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca358cfbd282a397a1e8e4458f00c842deb22b8c3715a57bc26dfa171c0394f5
|
4
|
+
data.tar.gz: e730cb4d2cc871a82547b6008db1f919243e8102bdd28bfaa95b9838208c38a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
+
[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
|
-
|
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{}
|
data/lib/funnel_http/client.rb
CHANGED
@@ -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
|
data/lib/funnel_http/version.rb
CHANGED
data/sig/funnel_http.rbs
CHANGED
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.
|
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-
|
10
|
+
date: 2025-01-12 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: go_gem
|