rest-man 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/{multi-matrix-test.yml → ci.yml} +10 -1
- data/.github/workflows/single-matrix-test.yml +1 -0
- data/.gitignore +2 -0
- data/.rubocop-disables.yml +4 -29
- data/AUTHORS +5 -1
- data/CHANGELOG.md +14 -0
- data/Gemfile +3 -0
- data/README.md +30 -37
- data/Rakefile +1 -59
- data/_doc/lib/restman/abstract_response/_follow_redirection.rdoc +7 -0
- data/_doc/lib/restman/abstract_response/beautify_headers.rdoc +24 -0
- data/_doc/lib/restman/abstract_response/cookie_jar.rdoc +4 -0
- data/_doc/lib/restman/abstract_response/cookies.rdoc +12 -0
- data/_doc/lib/restman/abstract_response/follow_get_redirection.rdoc +2 -0
- data/_doc/lib/restman/abstract_response/follow_redirection.rdoc +2 -0
- data/_doc/lib/restman/abstract_response/headers.rdoc +2 -0
- data/_doc/lib/restman/abstract_response/response_set_vars.rdoc +5 -0
- data/_doc/lib/restman/abstract_response/return.rdoc +9 -0
- data/_doc/lib/restman/add_before_execution_proc.rdoc +2 -0
- data/_doc/lib/restman/create_log.rdoc +2 -0
- data/_doc/lib/restman/exception.rdoc +6 -0
- data/_doc/lib/restman/exceptions/timeout.rdoc +4 -0
- data/_doc/lib/restman/exceptions.rdoc +4 -0
- data/_doc/lib/restman/log=.rdoc +3 -0
- data/_doc/lib/restman/params_array/new.rdoc +20 -0
- data/_doc/lib/restman/params_array/process_pair.rdoc +4 -0
- data/_doc/lib/restman/params_array.rdoc +11 -0
- data/_doc/lib/restman/platform/jruby?.rdoc +4 -0
- data/_doc/lib/restman/platform/mac_mri?.rdoc +5 -0
- data/_doc/lib/restman/proxy.rdoc +2 -0
- data/_doc/lib/restman/proxy_set?.rdoc +5 -0
- data/_doc/lib/restman/raw_response/new.rdoc +6 -0
- data/_doc/lib/restman/raw_response.rdoc +10 -0
- data/_doc/lib/restman/request/cookie_jar.rdoc +3 -0
- data/_doc/lib/restman/request/cookies.rdoc +11 -0
- data/_doc/lib/restman/request/default_headers.rdoc +5 -0
- data/_doc/lib/restman/request/default_ssl_cert_store.rdoc +8 -0
- data/_doc/lib/restman/request/init/cookie_jar.rdoc +55 -0
- data/_doc/lib/restman/request/init/http_method.rdoc +15 -0
- data/_doc/lib/restman/request/make_cookie_header.rdoc +8 -0
- data/_doc/lib/restman/request/make_headers.rdoc +25 -0
- data/_doc/lib/restman/request/maybe_convert_extension.rdoc +18 -0
- data/_doc/lib/restman/request/process_result.rdoc +4 -0
- data/_doc/lib/restman/request/proxy_uri.rdoc +7 -0
- data/_doc/lib/restman/request/stringify_headers.rdoc +9 -0
- data/_doc/lib/restman/request/use_ssl.rdoc +4 -0
- data/_doc/lib/restman/request.rdoc +46 -0
- data/_doc/lib/restman/reset_before_execution_procs.rdoc +1 -0
- data/_doc/lib/restman/resource/[].rdoc +25 -0
- data/_doc/lib/restman/resource.rdoc +33 -0
- data/_doc/lib/restman/response/body.rdoc +7 -0
- data/_doc/lib/restman/response/create.rdoc +10 -0
- data/_doc/lib/restman/response/fix_encoding.rdoc +2 -0
- data/_doc/lib/restman/statuses.rdoc +11 -0
- data/_doc/lib/restman/utils/cgi_parse_header.rdoc +6 -0
- data/_doc/lib/restman/utils/encode_query_string.rdoc +90 -0
- data/_doc/lib/restman/utils/escape.rdoc +11 -0
- data/_doc/lib/restman/utils/flatten_params.rdoc +16 -0
- data/_doc/lib/restman/utils/get_encoding_from_headers.rdoc +24 -0
- data/_doc/lib/restman.rdoc +43 -0
- data/bin/console +15 -0
- data/lib/restman/abstract_response.rb +13 -60
- data/lib/restman/exception.rb +43 -0
- data/lib/restman/exceptions/exception_with_response.rb +7 -0
- data/lib/restman/exceptions/exceptions_map.rb +26 -0
- data/lib/restman/exceptions/request_failed.rb +15 -0
- data/lib/restman/exceptions/server_broke_connection.rb +13 -0
- data/lib/restman/exceptions/timeout.rb +37 -0
- data/lib/restman/params_array/process_pair.rb +39 -0
- data/lib/restman/params_array.rb +3 -48
- data/lib/restman/payload/base.rb +57 -0
- data/lib/restman/payload/multipart/write_content_disposition.rb +88 -0
- data/lib/restman/payload/multipart.rb +56 -0
- data/lib/restman/payload/streamed.rb +22 -0
- data/lib/restman/payload/url_encoded.rb +14 -0
- data/lib/restman/payload.rb +14 -196
- data/lib/restman/platform.rb +2 -18
- data/lib/restman/raw_response.rb +2 -14
- data/lib/restman/request/default_ssl_cert_store.rb +13 -0
- data/lib/restman/request/fetch_body_to_tempfile.rb +58 -0
- data/lib/restman/request/init/cookie_jar.rb +65 -0
- data/lib/restman/request/init/ssl_opts.rb +70 -0
- data/lib/restman/request/init/url/add_query_from_headers.rb +51 -0
- data/lib/restman/request/init/url/normalize_url.rb +19 -0
- data/lib/restman/request/init/url.rb +40 -0
- data/lib/restman/request/init.rb +106 -0
- data/lib/restman/request/log_request.rb +46 -0
- data/lib/restman/request/make_cookie_header.rb +16 -0
- data/lib/restman/request/make_headers.rb +39 -0
- data/lib/restman/request/maybe_convert_extension.rb +28 -0
- data/lib/restman/request/net_http_object.rb +25 -0
- data/lib/restman/request/process_result.rb +36 -0
- data/lib/restman/request/proxy_uri.rb +31 -0
- data/lib/restman/request/stringify_headers.rb +36 -0
- data/lib/restman/request/transmit.rb +152 -0
- data/lib/restman/request.rb +60 -745
- data/lib/restman/resource.rb +2 -60
- data/lib/restman/response.rb +3 -21
- data/lib/restman/statuses.rb +75 -0
- data/lib/restman/statuses_compatibility.rb +18 -0
- data/lib/restman/utils.rb +10 -206
- data/lib/restman/version.rb +1 -1
- data/lib/restman.rb +24 -62
- data/matrixeval.yml +19 -1
- data/rest-man.gemspec +4 -10
- data/spec/integration/capath_digicert/ce5e74ef.0 +1 -1
- data/spec/integration/request_spec.rb +13 -1
- data/spec/spec_helper.rb +11 -0
- data/spec/unit/abstract_response_spec.rb +14 -0
- data/spec/unit/exception_spec.rb +64 -0
- data/spec/unit/exceptions/backwards_campatibility_spec.rb +29 -0
- data/spec/unit/exceptions/exceptions_map_spec.rb +89 -0
- data/spec/unit/exceptions/request_failed_spec.rb +51 -0
- data/spec/unit/exceptions/server_broke_connection_spec.rb +8 -0
- data/spec/unit/exceptions/timeout_spec.rb +59 -0
- data/spec/unit/params_array/process_pair_spec.rb +59 -0
- data/spec/unit/params_array_spec.rb +15 -10
- data/spec/unit/payload/multipart_spec.rb +116 -0
- data/spec/unit/payload/streamed_spec.rb +48 -0
- data/spec/unit/payload/url_encoded_spec.rb +65 -0
- data/spec/unit/payload_spec.rb +0 -208
- data/spec/unit/request/init/url/add_query_from_headers_spec.rb +40 -0
- data/spec/unit/request/init/url/normalize_url_spec.rb +25 -0
- data/spec/unit/request/init_spec.rb +83 -0
- data/spec/unit/request_spec.rb +143 -151
- data/spec/unit/utils_spec.rb +96 -104
- metadata +132 -16
- data/lib/restman/exceptions.rb +0 -238
- data/lib/restman/windows/root_certs.rb +0 -105
- data/lib/restman/windows.rb +0 -8
- data/spec/unit/exceptions_spec.rb +0 -108
- data/spec/unit/windows/root_certs_spec.rb +0 -22
data/spec/unit/request_spec.rb
CHANGED
@@ -20,6 +20,10 @@ describe RestMan::Request, :include_helpers do
|
|
20
20
|
allow(@net).to receive(:verify_callback=)
|
21
21
|
allow(@net).to receive(:ciphers=)
|
22
22
|
allow(@net).to receive(:cert_store=)
|
23
|
+
allow(@net).to receive(:max_retries=)
|
24
|
+
allow(@net).to receive(:read_timeout=)
|
25
|
+
allow(@net).to receive(:write_timeout=)
|
26
|
+
allow(@net).to receive(:open_timeout=)
|
23
27
|
RestMan.log = nil
|
24
28
|
end
|
25
29
|
|
@@ -46,48 +50,17 @@ describe RestMan::Request, :include_helpers do
|
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
49
|
-
describe '.normalize_url' do
|
50
|
-
it "adds http:// to the front of resources specified in the syntax example.com/resource" do
|
51
|
-
expect(@request.normalize_url('example.com/resource')).to eq 'http://example.com/resource'
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'adds http:// to resources containing a colon' do
|
55
|
-
expect(@request.normalize_url('example.com:1234')).to eq 'http://example.com:1234'
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'does not add http:// to the front of https resources' do
|
59
|
-
expect(@request.normalize_url('https://example.com/resource')).to eq 'https://example.com/resource'
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'does not add http:// to the front of capital HTTP resources' do
|
63
|
-
expect(@request.normalize_url('HTTP://example.com/resource')).to eq 'HTTP://example.com/resource'
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'does not add http:// to the front of capital HTTPS resources' do
|
67
|
-
expect(@request.normalize_url('HTTPS://example.com/resource')).to eq 'HTTPS://example.com/resource'
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'raises with invalid URI' do
|
71
|
-
expect {
|
72
|
-
RestMan::Request.new(method: :get, url: 'http://a@b:c')
|
73
|
-
}.to raise_error(URI::InvalidURIError)
|
74
|
-
expect {
|
75
|
-
RestMan::Request.new(method: :get, url: 'http://::')
|
76
|
-
}.to raise_error(URI::InvalidURIError)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
53
|
describe "user - password" do
|
81
54
|
it "extracts the username and password when parsing http://user:password@example.com/" do
|
82
|
-
|
83
|
-
expect(
|
84
|
-
expect(
|
55
|
+
request = RestMan::Request.new(method: :get, url: 'http://joe:pass1@example.com/resource')
|
56
|
+
expect(request.user).to eq 'joe'
|
57
|
+
expect(request.password).to eq 'pass1'
|
85
58
|
end
|
86
59
|
|
87
60
|
it "extracts with escaping the username and password when parsing http://user:password@example.com/" do
|
88
|
-
|
89
|
-
expect(
|
90
|
-
expect(
|
61
|
+
request = RestMan::Request.new(method: :get, url: 'http://joe%20:pass1@example.com/resource')
|
62
|
+
expect(request.user).to eq 'joe '
|
63
|
+
expect(request.password).to eq 'pass1'
|
91
64
|
end
|
92
65
|
|
93
66
|
it "doesn't overwrite user and password (which may have already been set by the Resource constructor) if there is no user/password in the url" do
|
@@ -236,31 +209,14 @@ describe RestMan::Request, :include_helpers do
|
|
236
209
|
end
|
237
210
|
end
|
238
211
|
|
239
|
-
it
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
}).to match(/warning: Overriding "Content-Type" header/i)
|
248
|
-
|
249
|
-
expect(fake_stderr {
|
250
|
-
RestMan::Request.new(method: :post, url: 'example.com',
|
251
|
-
payload: '123456', headers: {content_length: '20'})
|
252
|
-
}).to match(/warning: Overriding "Content-Length" header/i)
|
253
|
-
expect(fake_stderr {
|
254
|
-
RestMan::Request.new(method: :post, url: 'example.com',
|
255
|
-
payload: '123456', headers: {'Content-Length' => '20'})
|
256
|
-
}).to match(/warning: Overriding "Content-Length" header/i)
|
257
|
-
end
|
258
|
-
|
259
|
-
it "does not warn when overriding user header with header derived from payload if those header values were identical" do
|
260
|
-
expect(fake_stderr {
|
261
|
-
RestMan::Request.new(method: :post, url: 'example.com',
|
262
|
-
payload: {'foo' => '123456'}, headers: { 'Content-Type' => 'application/x-www-form-urlencoded' })
|
263
|
-
}).not_to match(/warning: Overriding "Content-Type" header/i)
|
212
|
+
it "does not override headers" do
|
213
|
+
request = RestMan::Request.new(
|
214
|
+
method: :post,
|
215
|
+
url: 'example.com',
|
216
|
+
payload: {'foo' => '123456'},
|
217
|
+
headers: { 'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8' }
|
218
|
+
)
|
219
|
+
expect(request.processed_headers['Content-Type']).to eq('application/x-www-form-urlencoded; charset=UTF-8')
|
264
220
|
end
|
265
221
|
|
266
222
|
it 'does not warn for a normal looking payload' do
|
@@ -488,6 +444,12 @@ describe RestMan::Request, :include_helpers do
|
|
488
444
|
expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestMan::Exceptions::OpenTimeout)
|
489
445
|
end
|
490
446
|
|
447
|
+
it "catches Net::WriteTimeout and raises RestMan's WriteTimeout",
|
448
|
+
:if => defined?(Net::WriteTimeout) do
|
449
|
+
allow(@http).to receive(:request).and_raise(Net::WriteTimeout)
|
450
|
+
expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestMan::Exceptions::WriteTimeout)
|
451
|
+
end
|
452
|
+
|
491
453
|
it "uses correct error message for ReadTimeout",
|
492
454
|
:if => defined?(Net::ReadTimeout) do
|
493
455
|
allow(@http).to receive(:request).and_raise(Net::ReadTimeout)
|
@@ -500,6 +462,11 @@ describe RestMan::Request, :include_helpers do
|
|
500
462
|
expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestMan::Exceptions::OpenTimeout, 'Timed out connecting to server')
|
501
463
|
end
|
502
464
|
|
465
|
+
it "uses correct error message for WriteTimeout",
|
466
|
+
:if => defined?(Net::WriteTimeout) do
|
467
|
+
allow(@http).to receive(:request).and_raise(Net::WriteTimeout)
|
468
|
+
expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestMan::Exceptions::WriteTimeout, 'Timed out writing data to server')
|
469
|
+
end
|
503
470
|
|
504
471
|
it "class method execute wraps constructor" do
|
505
472
|
req = double("rest request")
|
@@ -690,17 +657,6 @@ describe RestMan::Request, :include_helpers do
|
|
690
657
|
end
|
691
658
|
|
692
659
|
describe "timeout" do
|
693
|
-
it "does not set timeouts if not specified" do
|
694
|
-
@request = RestMan::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
|
695
|
-
allow(@http).to receive(:request)
|
696
|
-
allow(@request).to receive(:process_result)
|
697
|
-
|
698
|
-
expect(@net).not_to receive(:read_timeout=)
|
699
|
-
expect(@net).not_to receive(:open_timeout=)
|
700
|
-
|
701
|
-
@request.send(:transmit, @uri, 'req', nil)
|
702
|
-
end
|
703
|
-
|
704
660
|
it 'sets read_timeout' do
|
705
661
|
@request = RestMan::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => 123)
|
706
662
|
allow(@http).to receive(:request)
|
@@ -721,62 +677,49 @@ describe RestMan::Request, :include_helpers do
|
|
721
677
|
@request.send(:transmit, @uri, 'req', nil)
|
722
678
|
end
|
723
679
|
|
724
|
-
it
|
725
|
-
@request = RestMan::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :
|
680
|
+
it "sets write_timeout" do
|
681
|
+
@request = RestMan::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :write_timeout => 123)
|
726
682
|
allow(@http).to receive(:request)
|
727
683
|
allow(@request).to receive(:process_result)
|
728
684
|
|
729
|
-
expect(@net).to receive(:
|
730
|
-
expect(@net).to receive(:read_timeout=).with(123)
|
685
|
+
expect(@net).to receive(:write_timeout=).with(123)
|
731
686
|
|
732
687
|
@request.send(:transmit, @uri, 'req', nil)
|
733
688
|
end
|
734
689
|
|
735
|
-
it '
|
736
|
-
@request = RestMan::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123
|
690
|
+
it 'sets all timeouts with :timeout' do
|
691
|
+
@request = RestMan::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123)
|
737
692
|
allow(@http).to receive(:request)
|
738
693
|
allow(@request).to receive(:process_result)
|
739
694
|
|
740
|
-
expect(@net).to receive(:open_timeout=).with(
|
741
|
-
expect(@net).to receive(:read_timeout=).with(
|
695
|
+
expect(@net).to receive(:open_timeout=).with(123)
|
696
|
+
expect(@net).to receive(:read_timeout=).with(123)
|
697
|
+
expect(@net).to receive(:write_timeout=).with(123)
|
742
698
|
|
743
699
|
@request.send(:transmit, @uri, 'req', nil)
|
744
700
|
end
|
745
701
|
|
746
|
-
|
747
|
-
|
748
|
-
@request = RestMan::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => nil, :open_timeout => nil)
|
702
|
+
it 'supersedes :timeout with open/read/write_timeout' do
|
703
|
+
@request = RestMan::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123, :open_timeout => 34, :read_timeout => 56, :write_timeout => 78)
|
749
704
|
allow(@http).to receive(:request)
|
750
705
|
allow(@request).to receive(:process_result)
|
751
706
|
|
752
|
-
expect(@net).to receive(:
|
753
|
-
expect(@net).to receive(:
|
707
|
+
expect(@net).to receive(:open_timeout=).with(34)
|
708
|
+
expect(@net).to receive(:read_timeout=).with(56)
|
709
|
+
expect(@net).to receive(:write_timeout=).with(78)
|
754
710
|
|
755
711
|
@request.send(:transmit, @uri, 'req', nil)
|
756
712
|
end
|
757
713
|
|
758
|
-
it 'deprecated: warns when disabling timeout by setting it to -1' do
|
759
|
-
@request = RestMan::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => -1)
|
760
|
-
allow(@http).to receive(:request)
|
761
|
-
allow(@request).to receive(:process_result)
|
762
|
-
|
763
|
-
expect(@net).to receive(:read_timeout=).with(nil)
|
764
|
-
|
765
|
-
expect(fake_stderr {
|
766
|
-
@request.send(:transmit, @uri, 'req', nil)
|
767
|
-
}).to match(/^Deprecated: .*timeout.* nil instead of -1$/)
|
768
|
-
end
|
769
714
|
|
770
|
-
it "
|
771
|
-
@request = RestMan::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout =>
|
715
|
+
it "disable timeout by setting it to nil" do
|
716
|
+
@request = RestMan::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => nil, :open_timeout => nil, :write_timeout => nil)
|
772
717
|
allow(@http).to receive(:request)
|
773
718
|
allow(@request).to receive(:process_result)
|
774
719
|
|
775
|
-
expect(@request).to receive(:warn)
|
776
720
|
expect(@net).to receive(:read_timeout=).with(nil)
|
777
|
-
|
778
|
-
expect(@request).to receive(:warn)
|
779
721
|
expect(@net).to receive(:open_timeout=).with(nil)
|
722
|
+
expect(@net).to receive(:write_timeout=).with(nil)
|
780
723
|
|
781
724
|
@request.send(:transmit, @uri, 'req', nil)
|
782
725
|
end
|
@@ -844,6 +787,58 @@ describe RestMan::Request, :include_helpers do
|
|
844
787
|
@request.send(:transmit, @uri, 'req', 'payload')
|
845
788
|
end
|
846
789
|
|
790
|
+
it "should set the keep_alive_timeout if provided" do
|
791
|
+
@request = RestMan::Request.new(
|
792
|
+
:method => :put,
|
793
|
+
:url => 'https://some/resource',
|
794
|
+
:payload => 'payload',
|
795
|
+
:keep_alive_timeout => 1
|
796
|
+
)
|
797
|
+
expect(@net).to receive(:keep_alive_timeout=).with(1)
|
798
|
+
allow(@http).to receive(:request)
|
799
|
+
allow(@request).to receive(:process_result)
|
800
|
+
@request.send(:transmit, @uri, 'req', 'payload')
|
801
|
+
end
|
802
|
+
|
803
|
+
it "should set the close_on_empty_response if provided" do
|
804
|
+
@request = RestMan::Request.new(
|
805
|
+
:method => :put,
|
806
|
+
:url => 'https://some/resource',
|
807
|
+
:payload => 'payload',
|
808
|
+
:close_on_empty_response => true
|
809
|
+
)
|
810
|
+
expect(@net).to receive(:close_on_empty_response=).with(true)
|
811
|
+
allow(@http).to receive(:request)
|
812
|
+
allow(@request).to receive(:process_result)
|
813
|
+
@request.send(:transmit, @uri, 'req', 'payload')
|
814
|
+
end
|
815
|
+
|
816
|
+
it "should set the local_host if provided" do
|
817
|
+
@request = RestMan::Request.new(
|
818
|
+
:method => :put,
|
819
|
+
:url => 'https://some/resource',
|
820
|
+
:payload => 'payload',
|
821
|
+
:local_host => 'localhost'
|
822
|
+
)
|
823
|
+
expect(@net).to receive(:local_host=).with('localhost')
|
824
|
+
allow(@http).to receive(:request)
|
825
|
+
allow(@request).to receive(:process_result)
|
826
|
+
@request.send(:transmit, @uri, 'req', 'payload')
|
827
|
+
end
|
828
|
+
|
829
|
+
it "should set the local_port if provided" do
|
830
|
+
@request = RestMan::Request.new(
|
831
|
+
:method => :put,
|
832
|
+
:url => 'https://some/resource',
|
833
|
+
:payload => 'payload',
|
834
|
+
:local_port => 3000
|
835
|
+
)
|
836
|
+
expect(@net).to receive(:local_port=).with(3000)
|
837
|
+
allow(@http).to receive(:request)
|
838
|
+
allow(@request).to receive(:process_result)
|
839
|
+
@request.send(:transmit, @uri, 'req', 'payload')
|
840
|
+
end
|
841
|
+
|
847
842
|
it "should default to not having an ssl_client_cert" do
|
848
843
|
expect(@request.ssl_client_cert).to be(nil)
|
849
844
|
end
|
@@ -873,6 +868,45 @@ describe RestMan::Request, :include_helpers do
|
|
873
868
|
@request.send(:transmit, @uri, 'req', 'payload')
|
874
869
|
end
|
875
870
|
|
871
|
+
it "should set the ssl_min_version if provided" do
|
872
|
+
@request = RestMan::Request.new(
|
873
|
+
:method => :put,
|
874
|
+
:url => 'https://some/resource',
|
875
|
+
:payload => 'payload',
|
876
|
+
:ssl_min_version => :TLS1_2
|
877
|
+
)
|
878
|
+
expect(@net).to receive(:min_version=).with(:TLS1_2)
|
879
|
+
allow(@http).to receive(:request)
|
880
|
+
allow(@request).to receive(:process_result)
|
881
|
+
@request.send(:transmit, @uri, 'req', 'payload')
|
882
|
+
end
|
883
|
+
|
884
|
+
it "should set the ssl_max_version if provided" do
|
885
|
+
@request = RestMan::Request.new(
|
886
|
+
:method => :put,
|
887
|
+
:url => 'https://some/resource',
|
888
|
+
:payload => 'payload',
|
889
|
+
:ssl_max_version => :TLS1_2
|
890
|
+
)
|
891
|
+
expect(@net).to receive(:max_version=).with(:TLS1_2)
|
892
|
+
allow(@http).to receive(:request)
|
893
|
+
allow(@request).to receive(:process_result)
|
894
|
+
@request.send(:transmit, @uri, 'req', 'payload')
|
895
|
+
end
|
896
|
+
|
897
|
+
it "should set the ssl_timeout if provided" do
|
898
|
+
@request = RestMan::Request.new(
|
899
|
+
:method => :put,
|
900
|
+
:url => 'https://some/resource',
|
901
|
+
:payload => 'payload',
|
902
|
+
:ssl_timeout => 1
|
903
|
+
)
|
904
|
+
expect(@net).to receive(:ssl_timeout=).with(1)
|
905
|
+
allow(@http).to receive(:request)
|
906
|
+
allow(@request).to receive(:process_result)
|
907
|
+
@request.send(:transmit, @uri, 'req', 'payload')
|
908
|
+
end
|
909
|
+
|
876
910
|
it "should set the ssl_ciphers if provided" do
|
877
911
|
ciphers = 'AESGCM:HIGH:!aNULL:!eNULL:RC4+RSA'
|
878
912
|
@request = RestMan::Request.new(
|
@@ -1150,56 +1184,14 @@ describe RestMan::Request, :include_helpers do
|
|
1150
1184
|
end
|
1151
1185
|
end
|
1152
1186
|
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
expect {
|
1158
|
-
RestMan::Request.new(method: :get, url: 'http:///')
|
1159
|
-
}.to raise_error(URI::InvalidURIError, /\Abad URI/)
|
1160
|
-
end
|
1187
|
+
it 'raises with invalid URI' do
|
1188
|
+
expect {
|
1189
|
+
RestMan::Request.new(method: :get, url: 'http://a@b:c')
|
1190
|
+
}.to raise_error(URI::InvalidURIError)
|
1161
1191
|
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
}.to raise_error(URI::InvalidURIError)
|
1166
|
-
end
|
1192
|
+
expect {
|
1193
|
+
RestMan::Request.new(method: :get, url: 'http://::')
|
1194
|
+
}.to raise_error(URI::InvalidURIError)
|
1167
1195
|
end
|
1168
1196
|
|
1169
|
-
describe 'process_url_params' do
|
1170
|
-
it 'should handle basic URL params' do
|
1171
|
-
expect(@request.process_url_params('https://example.com/foo', params: {key1: 123, key2: 'abc'})).
|
1172
|
-
to eq 'https://example.com/foo?key1=123&key2=abc'
|
1173
|
-
|
1174
|
-
expect(@request.process_url_params('https://example.com/foo', params: {'key1' => 123})).
|
1175
|
-
to eq 'https://example.com/foo?key1=123'
|
1176
|
-
|
1177
|
-
expect(@request.process_url_params('https://example.com/path',
|
1178
|
-
params: {foo: 'one two', bar: 'three + four == seven'})).
|
1179
|
-
to eq 'https://example.com/path?foo=one+two&bar=three+%2B+four+%3D%3D+seven'
|
1180
|
-
end
|
1181
|
-
|
1182
|
-
it 'should combine with & when URL params already exist' do
|
1183
|
-
expect(@request.process_url_params('https://example.com/path?foo=1', params: {bar: 2})).
|
1184
|
-
to eq 'https://example.com/path?foo=1&bar=2'
|
1185
|
-
end
|
1186
|
-
|
1187
|
-
it 'should handle complex nested URL params per Rack / Rails conventions' do
|
1188
|
-
expect(@request.process_url_params('https://example.com/', params: {
|
1189
|
-
foo: [1,2,3],
|
1190
|
-
null: nil,
|
1191
|
-
falsy: false,
|
1192
|
-
math: '2+2=4',
|
1193
|
-
nested: {'key + escaped' => 'value + escaped', other: [], arr: [1,2]},
|
1194
|
-
})).to eq 'https://example.com/?foo[]=1&foo[]=2&foo[]=3&null&falsy=false&math=2%2B2%3D4' \
|
1195
|
-
'&nested[key+%2B+escaped]=value+%2B+escaped&nested[other]' \
|
1196
|
-
'&nested[arr][]=1&nested[arr][]=2'
|
1197
|
-
end
|
1198
|
-
|
1199
|
-
it 'should handle ParamsArray objects' do
|
1200
|
-
expect(@request.process_url_params('https://example.com/',
|
1201
|
-
params: RestMan::ParamsArray.new([[:foo, 1], [:foo, 2]])
|
1202
|
-
)).to eq 'https://example.com/?foo=1&foo=2'
|
1203
|
-
end
|
1204
|
-
end
|
1205
1197
|
end
|
data/spec/unit/utils_spec.rb
CHANGED
@@ -1,147 +1,139 @@
|
|
1
1
|
require_relative '_lib'
|
2
2
|
|
3
3
|
describe RestMan::Utils do
|
4
|
+
|
4
5
|
describe '.get_encoding_from_headers' do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
expect(RestMan::Utils.get_encoding_from_headers(
|
15
|
-
{})).to eq nil
|
16
|
-
expect(RestMan::Utils.get_encoding_from_headers(
|
17
|
-
{:content_type => 'foo; bar=baz'})).to eq nil
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'handles various charsets' do
|
21
|
-
expect(RestMan::Utils.get_encoding_from_headers(
|
22
|
-
{:content_type => 'text/plain; charset=UTF-8'})).to eq 'UTF-8'
|
23
|
-
expect(RestMan::Utils.get_encoding_from_headers(
|
24
|
-
{:content_type => 'application/json; charset=ISO-8859-1'})).
|
25
|
-
to eq 'ISO-8859-1'
|
26
|
-
expect(RestMan::Utils.get_encoding_from_headers(
|
27
|
-
{:content_type => 'text/html; charset=windows-1251'})).
|
28
|
-
to eq 'windows-1251'
|
29
|
-
|
30
|
-
expect(RestMan::Utils.get_encoding_from_headers(
|
31
|
-
{:content_type => 'text/html; charset="UTF-16"'})).
|
32
|
-
to eq 'UTF-16'
|
6
|
+
|
7
|
+
let(:get_encoding_from_headers) { RestMan::Utils.get_encoding_from_headers(headers) }
|
8
|
+
|
9
|
+
context 'with valid content_type' do
|
10
|
+
let(:headers) {{content_type: 'text/plain'}}
|
11
|
+
|
12
|
+
it 'assumes no encoding by default' do
|
13
|
+
expect(get_encoding_from_headers).to eq(nil)
|
14
|
+
end
|
33
15
|
end
|
34
|
-
end
|
35
16
|
|
36
|
-
|
37
|
-
|
38
|
-
expect(RestMan::Utils.cgi_parse_header('text/plain')).
|
39
|
-
to eq ['text/plain', {}]
|
17
|
+
context 'with invalid content_type like "blah"' do
|
18
|
+
let(:headers) {{content_type: 'blah'}}
|
40
19
|
|
41
|
-
|
42
|
-
to eq
|
20
|
+
it 'return nil' do
|
21
|
+
expect(get_encoding_from_headers).to eq(nil)
|
22
|
+
end
|
23
|
+
end
|
43
24
|
|
44
|
-
|
45
|
-
|
25
|
+
context 'with invalid content_type like "foo; bar=baz"' do
|
26
|
+
let(:headers) {{content_type: 'foo; bar=baz'}}
|
46
27
|
|
47
|
-
|
48
|
-
to eq
|
28
|
+
it 'return nil' do
|
29
|
+
expect(get_encoding_from_headers).to eq(nil)
|
30
|
+
end
|
31
|
+
end
|
49
32
|
|
50
|
-
|
51
|
-
|
52
|
-
to eq ['text/plain', {'charset' => 'us-ascii', 'another' => 'opt'}]
|
33
|
+
context 'with invalid content_type like empty headers' do
|
34
|
+
let(:headers) {{}}
|
53
35
|
|
54
|
-
|
55
|
-
|
56
|
-
|
36
|
+
it 'return nil' do
|
37
|
+
expect(get_encoding_from_headers).to eq(nil)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with valid content_type with charset UTF-8' do
|
42
|
+
let(:headers) {{content_type: 'text/plain; charset=UTF-8'}}
|
43
|
+
|
44
|
+
it 'return UTF-8' do
|
45
|
+
expect(get_encoding_from_headers).to eq('UTF-8')
|
46
|
+
end
|
47
|
+
end
|
57
48
|
|
58
|
-
|
59
|
-
|
60
|
-
to eq ['foo/bar', {'filename' => 'strange;name'}]
|
49
|
+
context 'with valid content_type with charset ISO-8859-1' do
|
50
|
+
let(:headers) {{content_type: 'text/plain; charset=ISO-8859-1'}}
|
61
51
|
|
62
|
-
|
63
|
-
|
64
|
-
|
52
|
+
it 'return ISO-8859-1' do
|
53
|
+
expect(get_encoding_from_headers).to eq('ISO-8859-1')
|
54
|
+
end
|
55
|
+
end
|
65
56
|
|
66
|
-
|
67
|
-
|
68
|
-
|
57
|
+
context 'with valid content_type with charset windows-1251' do
|
58
|
+
let(:headers) {{content_type: 'text/plain; charset=windows-1251'}}
|
59
|
+
|
60
|
+
it 'return windows-1251' do
|
61
|
+
expect(get_encoding_from_headers).to eq('windows-1251')
|
62
|
+
end
|
69
63
|
end
|
64
|
+
|
65
|
+
context 'with valid content_type with charset UTF-16' do
|
66
|
+
let(:headers) {{content_type: 'text/plain; charset=UTF-16'}}
|
67
|
+
|
68
|
+
it 'return UTF-16' do
|
69
|
+
expect(get_encoding_from_headers).to eq('UTF-16')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '.cgi_parse_header' do
|
76
|
+
|
77
|
+
let(:parse) { ->(line, to:) {
|
78
|
+
expect(RestMan::Utils.cgi_parse_header(line)).to eq(to)
|
79
|
+
}}
|
80
|
+
|
81
|
+
it { parse.('text/plain', to: ['text/plain', {}]) }
|
82
|
+
it { parse.('text/vnd.just.made.this.up', to: ['text/vnd.just.made.this.up', {}]) }
|
83
|
+
it { parse.('text/plain;charset=us-ascii', to: ['text/plain', {'charset' => 'us-ascii'}]) }
|
84
|
+
it { parse.('text/plain ; charset="us-ascii"', to: ['text/plain', {'charset' => 'us-ascii'}]) }
|
85
|
+
it { parse.('text/plain ; charset="us-ascii"; another=opt', to: ['text/plain', {'charset' => 'us-ascii', 'another' => 'opt'}]) }
|
86
|
+
it { parse.('foo/bar; filename="silly.txt"', to: ['foo/bar', {'filename' => 'silly.txt'}]) }
|
87
|
+
it { parse.('foo/bar; filename="strange;name"', to: ['foo/bar', {'filename' => 'strange;name'}]) }
|
88
|
+
it { parse.('foo/bar; filename="strange;name";size=123', to: ['foo/bar', {'filename' => 'strange;name', 'size' => '123'}]) }
|
89
|
+
it { parse.('foo/bar; name="files"; filename="fo\\"o;bar"', to: ['foo/bar', {'name' => 'files', 'filename' => 'fo"o;bar'}]) }
|
90
|
+
|
70
91
|
end
|
71
92
|
|
72
93
|
describe '.encode_query_string' do
|
94
|
+
let(:encoding) { -> (input, to:) {
|
95
|
+
expect(RestMan::Utils.encode_query_string(input)).to eq to
|
96
|
+
} }
|
97
|
+
|
73
98
|
it 'handles simple hashes' do
|
74
|
-
{
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
{'escaped + key' => 'foo'} => 'escaped+%2B+key=foo',
|
80
|
-
}.each_pair do |input, expected|
|
81
|
-
expect(RestMan::Utils.encode_query_string(input)).to eq expected
|
82
|
-
end
|
99
|
+
encoding.({foo: 123, bar: 456}, to: 'foo=123&bar=456')
|
100
|
+
encoding.({'foo' => 123, 'bar' => 456}, to: 'foo=123&bar=456')
|
101
|
+
encoding.({foo: 'abc', bar: 'one two'}, to: 'foo=abc&bar=one+two')
|
102
|
+
encoding.({escaped: '1+2=3'}, to: 'escaped=1%2B2%3D3')
|
103
|
+
encoding.({'escaped + key' => 'foo'}, to: 'escaped+%2B+key=foo')
|
83
104
|
end
|
84
105
|
|
85
106
|
it 'handles simple arrays' do
|
86
|
-
{
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
{'a+b' => [1,2,3]} => 'a%2Bb[]=1&a%2Bb[]=2&a%2Bb[]=3',
|
91
|
-
}.each_pair do |input, expected|
|
92
|
-
expect(RestMan::Utils.encode_query_string(input)).to eq expected
|
93
|
-
end
|
107
|
+
encoding.({foo: [1, 2, 3]}, to: 'foo[]=1&foo[]=2&foo[]=3')
|
108
|
+
encoding.({foo: %w{a b c}, bar: [1, 2, 3]}, to: 'foo[]=a&foo[]=b&foo[]=c&bar[]=1&bar[]=2&bar[]=3')
|
109
|
+
encoding.({foo: ['one two', 3]}, to: 'foo[]=one+two&foo[]=3')
|
110
|
+
encoding.({'a+b' => [1,2,3]}, to: 'a%2Bb[]=1&a%2Bb[]=2&a%2Bb[]=3')
|
94
111
|
end
|
95
112
|
|
96
113
|
it 'handles nested hashes' do
|
97
|
-
{
|
98
|
-
|
99
|
-
{outer: {foo: [1, 2, 3], bar: 'baz'}} => 'outer[foo][]=1&outer[foo][]=2&outer[foo][]=3&outer[bar]=baz',
|
100
|
-
}.each_pair do |input, expected|
|
101
|
-
expect(RestMan::Utils.encode_query_string(input)).to eq expected
|
102
|
-
end
|
114
|
+
encoding.({outer: {foo: 123, bar: 456}}, to: 'outer[foo]=123&outer[bar]=456')
|
115
|
+
encoding.({outer: {foo: [1, 2, 3], bar: 'baz'}}, to: 'outer[foo][]=1&outer[foo][]=2&outer[foo][]=3&outer[bar]=baz')
|
103
116
|
end
|
104
117
|
|
105
118
|
it 'handles null and empty values' do
|
106
|
-
{
|
107
|
-
{string: '', empty: nil, list: [], hash: {}, falsey: false } =>
|
108
|
-
'string=&empty&list&hash&falsey=false',
|
109
|
-
}.each_pair do |input, expected|
|
110
|
-
expect(RestMan::Utils.encode_query_string(input)).to eq expected
|
111
|
-
end
|
119
|
+
encoding.({string: '', empty: nil, list: [], hash: {}, falsey: false }, to: 'string=&empty&list&hash&falsey=false')
|
112
120
|
end
|
113
121
|
|
114
122
|
it 'handles nested nulls' do
|
115
|
-
{
|
116
|
-
{foo: {string: '', empty: nil}} => 'foo[string]=&foo[empty]',
|
117
|
-
}.each_pair do |input, expected|
|
118
|
-
expect(RestMan::Utils.encode_query_string(input)).to eq expected
|
119
|
-
end
|
123
|
+
encoding.({foo: {string: '', empty: nil}}, to: 'foo[string]=&foo[empty]')
|
120
124
|
end
|
121
125
|
|
122
126
|
it 'handles deep nesting' do
|
123
|
-
{
|
124
|
-
{coords: [{x: 1, y: 0}, {x: 2}, {x: 3}]} => 'coords[][x]=1&coords[][y]=0&coords[][x]=2&coords[][x]=3',
|
125
|
-
}.each_pair do |input, expected|
|
126
|
-
expect(RestMan::Utils.encode_query_string(input)).to eq expected
|
127
|
-
end
|
127
|
+
encoding.({coords: [{x: 1, y: 0}, {x: 2}, {x: 3}]}, to: 'coords[][x]=1&coords[][y]=0&coords[][x]=2&coords[][x]=3')
|
128
128
|
end
|
129
129
|
|
130
130
|
it 'handles multiple fields with the same name using ParamsArray' do
|
131
|
-
|
132
|
-
RestMan::ParamsArray.new([[:foo, 1], [:foo, 2], [:foo, 3]]) => 'foo=1&foo=2&foo=3',
|
133
|
-
}.each_pair do |input, expected|
|
134
|
-
expect(RestMan::Utils.encode_query_string(input)).to eq expected
|
135
|
-
end
|
131
|
+
encoding.(RestMan::ParamsArray.new([[:foo, 1], [:foo, 2], [:foo, 3]]), to: 'foo=1&foo=2&foo=3')
|
136
132
|
end
|
137
133
|
|
138
134
|
it 'handles nested ParamsArrays' do
|
139
|
-
{
|
140
|
-
|
141
|
-
RestMan::ParamsArray.new([[:foo, {a: 1}], [:foo, {a: 2}]]) => 'foo[a]=1&foo[a]=2',
|
142
|
-
}.each_pair do |input, expected|
|
143
|
-
expect(RestMan::Utils.encode_query_string(input)).to eq expected
|
144
|
-
end
|
135
|
+
encoding.({foo: RestMan::ParamsArray.new([[:a, 1], [:a, 2]])}, to: 'foo[a]=1&foo[a]=2')
|
136
|
+
encoding.(RestMan::ParamsArray.new([[:foo, {a: 1}], [:foo, {a: 2}]]), to: 'foo[a]=1&foo[a]=2')
|
145
137
|
end
|
146
138
|
end
|
147
139
|
end
|