http.rb 1.1.0 → 1.2.1

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: a5f552ac83d2afe5184c79455af215f58e18cc7e0f01e1a8bf684a877f8b9d9a
4
- data.tar.gz: 274244f8126d9dbb09b17c1a46be7a7c037ecab83ca8ae5af5bc4d7f3463c07b
3
+ metadata.gz: 8e8141a5ebd470216fbd373f5a21fa5b96981be7dc2d6ddb7d8131b220b91ef7
4
+ data.tar.gz: 20a7507d9c92457c23f38970f9d04877c527115d298a07a5c3fe0015c88ff627
5
5
  SHA512:
6
- metadata.gz: e0fdfcf607047e62db109a3ec414cebf308b270e2757d510f8f337628f0b235a947f4769a5e78a32abd137ce764f63822ca9ff26ccfc5fbc01db39ead0ef1152
7
- data.tar.gz: fb725d77aa4f4312803dadd481b62a705dd3286568469a1ae055a609a86d9991583dd69a7110864375b5835eecbba9ab06ad39ffbc4f61e428686787690908c2
6
+ metadata.gz: 97514595af94da5845f2189b81751838c1c753ee69afaf31cd43d08ab80cfbd623b7da8214e61375a011210ef9dbe330f318e3981b0b5c350f63b12f4526c2a7
7
+ data.tar.gz: a8828932d5d72ab5348f44b2f0bff95f14a13653682161963fdb3d518f3734805798abf518bd7fe849f70e838225a9229b989147c94a3808e533e1f5d50836cd
data/CHANGELOG CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  ## 20260609
4
4
 
5
+ 1.2.1: Split the request builders into their own files.
6
+
7
+ request_with_body and request_without_body, added in 1.2.0, each move into their own file, matching the one-method-per-file layout used throughout lib/. Purely internal reorganisation — the methods, their signatures, and their behaviour are unchanged — so it is a patch, not a minor.
8
+
9
+ 1. + lib/HTTP/request_without_body.rb: HTTP.request_without_body, extracted from verbs.rb; requires net/http and the Hash#x_www_form_urlencode extension.
10
+ 2. + lib/HTTP/request_with_body.rb: HTTP.request_with_body, extracted from verbs.rb; requires net/http and json.
11
+ 3. ~ HTTP/verbs.rb: the request builders are extracted; the file now requires the two new files and keeps the VERBS constant and the named-method generation.
12
+ 4. ~ HTTP::VERSION: /1.2.0/1.2.1/
13
+ 5. ~ CHANGELOG: + 1.2.1 entry
14
+
15
+ ## 20260609
16
+
17
+ 1.2.0: Extract request_without_body and request_with_body.
18
+
19
+ The logic for building request objects — constructing the Net::HTTP request class, encoding bodies, and assembling query strings — lived inside the define_method loops and was unreachable except through the eight named methods. Downstream gems needing a method without a named helper (notably webdav's PROPFIND) had to build raw Net::HTTP request objects and bypass that logic entirely. Those two loop bodies are now module functions, callable directly as HTTP.request_without_body(method, ...) and HTTP.request_with_body(method, ...); the named methods delegate to them and behave identically.
20
+
21
+ 1. ~ HTTP/verbs.rb: + request_without_body() and request_with_body() module functions; the WITHOUT_BODY and WITH_BODY define_method loops now delegate to them.
22
+ 2. + test/HTTP/request_without_body_test.rb
23
+ 3. + test/HTTP/request_with_body_test.rb
24
+ 4. ~ README.md: + Constructing requests for other methods section.
25
+ 5. ~ HTTP::VERSION: /1.1.0/1.2.0/
26
+ 6. ~ CHANGELOG: + 1.2.0 entry
27
+
28
+ ## 20260609
29
+
5
30
  1.1.0: Basic auth via the options hash.
6
31
 
7
32
  Until now basic authentication was only available through credentials embedded in the URI, which forced callers needing programmatic credentials (notably the webdav gem) to construct their own Net::HTTP request objects and bypass the verb methods entirely. The options hash now accepts username: and password:, extracted the same way no_redirect is, so they never leak through to Net::HTTP. This is additive: URI credentials still work as a fallback, and explicit options take precedence over them.
data/README.md CHANGED
@@ -182,6 +182,20 @@ class A
182
182
  end
183
183
  ```
184
184
 
185
+ ### Constructing requests for other methods
186
+
187
+ The named methods cover the HTTP methods with a request class in Ruby's `Net::HTTP` stdlib. For anything else — a method without a named helper, such as `PROPFIND` — the same body encoding, query string, and request handling is available directly:
188
+
189
+ ```ruby
190
+ # No body — args become a query string:
191
+ HTTP.request_without_body(:propfind, 'http://example.com/path', {depth: 1})
192
+
193
+ # With a body — string passthrough, JSON when the content type says so, form data otherwise:
194
+ HTTP.request_with_body(:propfind, 'http://example.com/path', xml, {'Content-Type' => 'application/xml'})
195
+ ```
196
+
197
+ Both take the same `(method, uri, args_or_data, headers, options, &block)` arguments as the named methods, with the method as the first argument, and the named methods delegate to them. For full control over the request object, drop down to `HTTP.request(uri, request_object, headers, options, &block)`.
198
+
185
199
  ## Allowed values for the options hash
186
200
  #### (These pass through to Net::HTTP, except for `no_redirect`, `username`, and `password`.)
187
201
 
data/lib/HTTP/VERSION.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # HTTP::VERSION
3
3
 
4
4
  module HTTP
5
- VERSION = '1.1.0'
5
+ VERSION = '1.2.1'
6
6
  end
@@ -0,0 +1,25 @@
1
+ # HTTP/request_with_body.rb
2
+ # HTTP.request_with_body
3
+
4
+ require 'json'
5
+ require 'net/http'
6
+
7
+ require_relative './request'
8
+
9
+ module HTTP
10
+ def request_with_body(method, uri, data = {}, headers = {}, options = {}, &block)
11
+ uri = uri.is_a?(URI) ? uri : URI.parse(uri)
12
+ request_object = Net::HTTP.const_get(method.to_s.capitalize).new(uri.request_uri)
13
+ content_type = headers.find{|k, v| k.downcase == 'content-type'}&.last.to_s
14
+ if data.is_a?(String)
15
+ request_object.body = data
16
+ elsif content_type.start_with?('application/json')
17
+ request_object.body = JSON.dump(data)
18
+ else
19
+ request_object.form_data = data
20
+ end
21
+ request(uri, request_object, headers, options, &block)
22
+ end
23
+
24
+ module_function :request_with_body
25
+ end
@@ -0,0 +1,21 @@
1
+ # HTTP/request_without_body.rb
2
+ # HTTP.request_without_body
3
+
4
+ require 'net/http'
5
+
6
+ require_relative '../Hash/x_www_form_urlencode'
7
+ require_relative './request'
8
+
9
+ module HTTP
10
+ def request_without_body(method, uri, args = {}, headers = {}, options = {}, &block)
11
+ uri = uri.is_a?(URI) ? uri : URI.parse(uri)
12
+ request_uri = uri.request_uri
13
+ unless args.empty?
14
+ request_uri += '?' + args.x_www_form_urlencode
15
+ end
16
+ request_object = Net::HTTP.const_get(method.to_s.capitalize).new(request_uri)
17
+ request(uri, request_object, headers, options, &block)
18
+ end
19
+
20
+ module_function :request_without_body
21
+ end
data/lib/HTTP/verbs.rb CHANGED
@@ -1,11 +1,8 @@
1
1
  # HTTP/verbs.rb
2
2
  # HTTP.verb
3
3
 
4
- require 'json'
5
- require 'net/http'
6
-
7
- require_relative '../Hash/x_www_form_urlencode'
8
- require_relative './request'
4
+ require_relative './request_without_body'
5
+ require_relative './request_with_body'
9
6
 
10
7
  module HTTP
11
8
  module VERBS
@@ -15,33 +12,15 @@ module HTTP
15
12
 
16
13
  VERBS::WITHOUT_BODY.each do |verb|
17
14
  define_method(verb) do |uri, args = {}, headers = {}, options = {}, &block|
18
- uri = uri.is_a?(URI) ? uri : URI.parse(uri)
19
- request_uri = uri.request_uri
20
- unless args.empty?
21
- request_uri += '?' + args.x_www_form_urlencode
22
- end
23
- request_object = Net::HTTP.const_get(verb.to_s.capitalize).new(request_uri)
24
- request(uri, request_object, headers, options, &block)
15
+ request_without_body(verb, uri, args, headers, options, &block)
25
16
  end
26
-
27
17
  module_function verb
28
18
  end
29
19
 
30
20
  VERBS::WITH_BODY.each do |verb|
31
21
  define_method(verb) do |uri, data = {}, headers = {}, options = {}, &block|
32
- uri = uri.is_a?(URI) ? uri : URI.parse(uri)
33
- request_object = Net::HTTP.const_get(verb.to_s.capitalize).new(uri.request_uri)
34
- content_type = headers.find{|k, v| k.downcase == 'content-type'}&.last.to_s
35
- if data.is_a?(String)
36
- request_object.body = data
37
- elsif content_type.start_with?('application/json')
38
- request_object.body = JSON.dump(data)
39
- else
40
- request_object.form_data = data
41
- end
42
- request(uri, request_object, headers, options, &block)
22
+ request_with_body(verb, uri, data, headers, options, &block)
43
23
  end
44
-
45
24
  module_function verb
46
25
  end
47
26
  end
@@ -0,0 +1,76 @@
1
+ # test/HTTP/request_with_body_test.rb
2
+
3
+ require_relative '../helper'
4
+
5
+ describe ".request_with_body" do
6
+ let(:uri){'http://example.com/path'}
7
+ let(:parsed_uri){URI.parse(uri)}
8
+
9
+ describe "with a string body" do
10
+ let(:body){'raw body'}
11
+
12
+ before do
13
+ stub_request(:post, 'http://example.com/path').
14
+ with(body: body).
15
+ to_return(status: 200, body: '', headers: {})
16
+ end
17
+
18
+ it "passes the string through unchanged" do
19
+ request_object = Net::HTTP::Post.new(parsed_uri.request_uri)
20
+ Net::HTTP::Post.stub(:new, request_object) do
21
+ response = HTTP.request_with_body(:post, uri, body)
22
+ _(request_object.body).must_equal(body)
23
+ _(response.success?).must_equal(true)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "with a JSON content type" do
29
+ let(:data){{a: 1, b: 2}}
30
+ let(:headers){{'Content-Type' => 'application/json'}}
31
+
32
+ before do
33
+ stub_request(:post, 'http://example.com/path').
34
+ with(body: JSON.dump(data)).
35
+ to_return(status: 200, body: '', headers: {})
36
+ end
37
+
38
+ it "JSON-encodes the data" do
39
+ request_object = Net::HTTP::Post.new(parsed_uri.request_uri)
40
+ Net::HTTP::Post.stub(:new, request_object) do
41
+ response = HTTP.request_with_body(:post, uri, data, headers)
42
+ _(request_object.body).must_equal(JSON.dump(data))
43
+ _(response.success?).must_equal(true)
44
+ end
45
+ end
46
+ end
47
+
48
+ describe "with no content type" do
49
+ let(:data){{a: 1, b: 2}}
50
+
51
+ before do
52
+ stub_request(:post, 'http://example.com/path').
53
+ with(body: data.x_www_form_urlencode).
54
+ to_return(status: 200, body: '', headers: {})
55
+ end
56
+
57
+ it "form-encodes the data" do
58
+ request_object = Net::HTTP::Post.new(parsed_uri.request_uri)
59
+ Net::HTTP::Post.stub(:new, request_object) do
60
+ response = HTTP.request_with_body(:post, uri, data)
61
+ _(request_object.body).must_equal(data.x_www_form_urlencode)
62
+ _(response.success?).must_equal(true)
63
+ end
64
+ end
65
+ end
66
+
67
+ describe "delegation from the named method" do
68
+ it "is reached by HTTP.post with the verb prepended" do
69
+ received_args = nil
70
+ HTTP.stub(:request_with_body, ->(*args, &block){received_args = args; nil}) do
71
+ HTTP.post(uri, {a: 1}, {'User-Agent' => 'Minitest'}, {use_ssl: false})
72
+ end
73
+ _(received_args).must_equal([:post, uri, {a: 1}, {'User-Agent' => 'Minitest'}, {use_ssl: false}])
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,53 @@
1
+ # test/HTTP/request_without_body_test.rb
2
+
3
+ require_relative '../helper'
4
+
5
+ describe ".request_without_body" do
6
+ let(:uri){'http://example.com/path'}
7
+ let(:parsed_uri){URI.parse(uri)}
8
+
9
+ describe "without args" do
10
+ before do
11
+ stub_request(:get, 'http://example.com/path').
12
+ to_return(status: 200, body: '', headers: {})
13
+ end
14
+
15
+ it "builds the request object for the given method" do
16
+ received_arg = nil
17
+ request_object = Net::HTTP::Get.new(parsed_uri.request_uri)
18
+ Net::HTTP::Get.stub(:new, ->(arg){received_arg = arg; request_object}) do
19
+ response = HTTP.request_without_body(:get, uri)
20
+ _(received_arg).must_equal(parsed_uri.request_uri)
21
+ _(response.success?).must_equal(true)
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "with args" do
27
+ before do
28
+ stub_request(:get, 'http://example.com/path?a=1&b=2').
29
+ to_return(status: 200, body: '', headers: {})
30
+ end
31
+
32
+ it "appends the encoded query string to the request uri" do
33
+ received_arg = nil
34
+ request_uri = parsed_uri.request_uri + '?a=1&b=2'
35
+ request_object = Net::HTTP::Get.new(request_uri)
36
+ Net::HTTP::Get.stub(:new, ->(arg){received_arg = arg; request_object}) do
37
+ response = HTTP.request_without_body(:get, uri, {a: 1, b: 2})
38
+ _(received_arg).must_equal(request_uri)
39
+ _(response.success?).must_equal(true)
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "delegation from the named method" do
45
+ it "is reached by HTTP.get with the verb prepended" do
46
+ received_args = nil
47
+ HTTP.stub(:request_without_body, ->(*args, &block){received_args = args; nil}) do
48
+ HTTP.get(uri, {a: 1}, {'User-Agent' => 'Minitest'}, {use_ssl: false})
49
+ end
50
+ _(received_args).must_equal([:get, uri, {a: 1}, {'User-Agent' => 'Minitest'}, {use_ssl: false}])
51
+ end
52
+ end
53
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - thoran
@@ -97,6 +97,8 @@ files:
97
97
  - lib/HTTP/RETRY.rb
98
98
  - lib/HTTP/VERSION.rb
99
99
  - lib/HTTP/request.rb
100
+ - lib/HTTP/request_with_body.rb
101
+ - lib/HTTP/request_without_body.rb
100
102
  - lib/HTTP/verbs.rb
101
103
  - lib/Hash/x_www_form_urlencode.rb
102
104
  - lib/Net/HTTP/set_options.rb
@@ -113,6 +115,8 @@ files:
113
115
  - test/HTTP/patch_test.rb
114
116
  - test/HTTP/post_test.rb
115
117
  - test/HTTP/put_test.rb
118
+ - test/HTTP/request_with_body_test.rb
119
+ - test/HTTP/request_without_body_test.rb
116
120
  - test/HTTP/trace_test.rb
117
121
  - test/Net/HTTPResponse/StatusPredicates_test.rb
118
122
  - test/helper.rb