httpi 2.4.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/development.yml +48 -0
  3. data/CHANGELOG.md +45 -0
  4. data/Gemfile +10 -5
  5. data/README.md +20 -16
  6. data/Rakefile +5 -3
  7. data/UPDATING.md +7 -0
  8. data/httpi.gemspec +6 -7
  9. data/lib/httpi/adapter/curb.rb +8 -2
  10. data/lib/httpi/adapter/em_http.rb +5 -4
  11. data/lib/httpi/adapter/excon.rb +17 -5
  12. data/lib/httpi/adapter/http.rb +15 -2
  13. data/lib/httpi/adapter/httpclient.rb +16 -4
  14. data/lib/httpi/adapter/net_http.rb +42 -16
  15. data/lib/httpi/adapter/net_http_persistent.rb +6 -2
  16. data/lib/httpi/adapter/rack.rb +13 -6
  17. data/lib/httpi/auth/ssl.rb +68 -3
  18. data/lib/httpi/logger.rb +6 -1
  19. data/lib/httpi/request.rb +12 -5
  20. data/lib/httpi/response.rb +2 -0
  21. data/lib/httpi/version.rb +1 -1
  22. data/lib/httpi.rb +4 -4
  23. data/spec/fixtures/client_cert.pem +18 -14
  24. data/spec/fixtures/client_key.pem +25 -13
  25. data/spec/httpi/adapter/curb_spec.rb +36 -10
  26. data/spec/httpi/adapter/em_http_spec.rb +23 -21
  27. data/spec/httpi/adapter/excon_spec.rb +28 -90
  28. data/spec/httpi/adapter/http_spec.rb +23 -96
  29. data/spec/httpi/adapter/httpclient_spec.rb +46 -4
  30. data/spec/httpi/adapter/net_http_persistent_spec.rb +31 -81
  31. data/spec/httpi/adapter/net_http_spec.rb +39 -99
  32. data/spec/httpi/adapter/rack_spec.rb +6 -8
  33. data/spec/httpi/auth/ssl_spec.rb +49 -1
  34. data/spec/httpi/httpi_spec.rb +16 -4
  35. data/spec/httpi/request_spec.rb +5 -0
  36. data/spec/integration/curb_spec.rb +20 -0
  37. data/spec/integration/em_http_spec.rb +19 -2
  38. data/spec/integration/excon_spec.rb +174 -0
  39. data/spec/integration/fixtures/ca_all.pem +17 -42
  40. data/spec/integration/fixtures/server.cert +17 -17
  41. data/spec/integration/fixtures/server.key +25 -13
  42. data/spec/integration/http_spec.rb +156 -0
  43. data/spec/integration/httpclient_spec.rb +20 -0
  44. data/spec/integration/net_http_persistent_spec.rb +34 -2
  45. data/spec/integration/net_http_spec.rb +144 -1
  46. data/spec/integration/support/application.rb +4 -2
  47. data/spec/integration/support/server.rb +1 -2
  48. data/spec/spec_helper.rb +0 -2
  49. metadata +31 -29
  50. data/.travis.yml +0 -8
@@ -3,8 +3,8 @@ require "integration/support/server"
3
3
 
4
4
  describe HTTPI::Adapter::EmHttpRequest do
5
5
 
6
- # em_http is not supported on ruby 1.8
7
- unless RUBY_VERSION =~ /1\.8/
6
+ # em_http is not supported on java
7
+ unless RUBY_PLATFORM =~ /java/
8
8
  require "em-synchrony"
9
9
 
10
10
  subject(:adapter) { :em_http }
@@ -42,6 +42,23 @@ describe HTTPI::Adapter::EmHttpRequest do
42
42
  expect(response.headers["Set-Cookie"]).to eq(cookies)
43
43
  end
44
44
 
45
+ if RUBY_PLATFORM =~ /java/
46
+ pending <<-MSG
47
+ It seems like JRuby is missing support for inactivity timeout! See related issues on GitHub:
48
+ - https://github.com/eventmachine/eventmachine/issues/155
49
+ - https://github.com/eventmachine/eventmachine/pull/312
50
+ MSG
51
+ else
52
+ it "it supports read timeout" do
53
+ request = HTTPI::Request.new(@server.url + "timeout")
54
+ request.read_timeout = 0.5 # seconds
55
+
56
+ expect do
57
+ HTTPI.get(request, adapter)
58
+ end.to raise_exception(HTTPI::TimeoutError)
59
+ end
60
+ end
61
+
45
62
  it "executes GET requests" do
46
63
  response = HTTPI.get(@server.url, adapter)
47
64
  expect(response.body).to eq("get")
@@ -0,0 +1,174 @@
1
+ require "spec_helper"
2
+ require "integration/support/server"
3
+
4
+ describe HTTPI::Adapter::Excon do
5
+
6
+ subject(:adapter) { :excon }
7
+
8
+ context "http requests" do
9
+ before :all do
10
+ @server = IntegrationServer.run
11
+ end
12
+
13
+ after :all do
14
+ @server.stop
15
+ end
16
+
17
+ it "sends and receives HTTP headers" do
18
+ request = HTTPI::Request.new(@server.url + "x-header")
19
+ request.headers["X-Header"] = "HTTPI"
20
+
21
+ response = HTTPI.get(request, adapter)
22
+ expect(response.body).to include("HTTPI")
23
+ end
24
+
25
+ it "it supports headers with multiple values" do
26
+ request = HTTPI::Request.new(@server.url + "cookies")
27
+
28
+ response = HTTPI.get(request, adapter)
29
+ cookies = ["cookie1=chip1; path=/", "cookie2=chip2; path=/"]
30
+ expect(response.headers["Set-Cookie"]).to eq(cookies)
31
+ end
32
+
33
+ it "it supports read timeout" do
34
+ require "excon"
35
+
36
+ request = HTTPI::Request.new(@server.url + "timeout")
37
+ request.read_timeout = 0.5 # seconds
38
+
39
+ expect do
40
+ HTTPI.get(request, adapter)
41
+ end.to raise_exception(Excon::Error::Timeout)
42
+ end
43
+
44
+ it "executes GET requests" do
45
+ response = HTTPI.get(@server.url, adapter)
46
+ expect(response.body).to eq("get")
47
+ expect(response.headers["Content-Type"]).to eq("text/plain")
48
+ end
49
+
50
+ it "executes POST requests" do
51
+ response = HTTPI.post(@server.url, "<some>xml</some>", adapter)
52
+ expect(response.body).to eq("post")
53
+ expect(response.headers["Content-Type"]).to eq("text/plain")
54
+ end
55
+
56
+ it "executes HEAD requests" do
57
+ response = HTTPI.head(@server.url, adapter)
58
+ expect(response.code).to eq(200)
59
+ expect(response.headers["Content-Type"]).to eq("text/plain")
60
+ end
61
+
62
+ it "executes PUT requests" do
63
+ response = HTTPI.put(@server.url, "<some>xml</some>", adapter)
64
+ expect(response.body).to eq("put")
65
+ expect(response.headers["Content-Type"]).to eq("text/plain")
66
+ end
67
+
68
+ it "executes DELETE requests" do
69
+ response = HTTPI.delete(@server.url, adapter)
70
+ expect(response.body).to eq("delete")
71
+ expect(response.headers["Content-Type"]).to eq("text/plain")
72
+ end
73
+
74
+ it "supports basic authentication" do
75
+ request = HTTPI::Request.new(@server.url + "basic-auth")
76
+ request.auth.basic("admin", "secret")
77
+
78
+ response = HTTPI.get(request, adapter)
79
+ expect(response.body).to eq("basic-auth")
80
+ end
81
+
82
+ it "does not support ntlm authentication" do
83
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
84
+ request.auth.ntlm("tester", "vReqSoafRe5O")
85
+
86
+ expect { HTTPI.get(request, adapter) }.
87
+ to raise_error(HTTPI::NotSupportedError, /does not support NTLM authentication/)
88
+ end
89
+
90
+ it "supports disabling verify mode" do
91
+ request = HTTPI::Request.new(@server.url)
92
+ request.auth.ssl.verify_mode = :none
93
+ adapter_class = HTTPI::Adapter.load(adapter).new(request)
94
+ expect(adapter_class.client.data[:ssl_verify_peer]).to eq(false)
95
+ end
96
+
97
+ it "supports chunked response" do
98
+ request = HTTPI::Request.new(@server.url)
99
+ res = ""
100
+ request.on_body do |body|
101
+ res += body
102
+ end
103
+ response = HTTPI.post(request, adapter)
104
+ expect(res).to eq("post")
105
+ expect(response.body).to eq("")
106
+ end
107
+ end
108
+
109
+ if RUBY_PLATFORM =~ /java/
110
+ pending "Puma Server complains: SSL not supported on JRuby"
111
+ else
112
+ context "https requests" do
113
+ before :all do
114
+ @server = IntegrationServer.run(:ssl => true)
115
+ end
116
+ after :all do
117
+ @server.stop
118
+ end
119
+
120
+ it "raises when no certificate was set up" do
121
+ expect { HTTPI.post(@server.url, "", adapter) }.to raise_error(HTTPI::SSLError)
122
+ end
123
+
124
+ it "works when set up properly" do
125
+ request = HTTPI::Request.new(@server.url)
126
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
127
+
128
+ response = HTTPI.get(request, adapter)
129
+ expect(response.body).to eq("get")
130
+ end
131
+
132
+ it "works with min_version/max_version" do
133
+ request = HTTPI::Request.new(@server.url)
134
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
135
+ request.auth.ssl.min_version = :TLS1_2
136
+ request.auth.ssl.max_version = :TLS1_2
137
+
138
+ response = HTTPI.get(request, adapter)
139
+ expect(response.body).to eq("get")
140
+ end
141
+
142
+ it "works with client cert and key provided as file path" do
143
+ request = HTTPI::Request.new(@server.url)
144
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
145
+ request.auth.ssl.cert_file = "spec/fixtures/client_cert.pem"
146
+ request.auth.ssl.cert_key_file = "spec/fixtures/client_key.pem"
147
+
148
+ response = HTTPI.get(request, adapter)
149
+ expect(response.body).to eq("get")
150
+ end
151
+
152
+ it "works with client cert and key set directly" do
153
+ request = HTTPI::Request.new(@server.url)
154
+
155
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
156
+ request.auth.ssl.cert = OpenSSL::X509::Certificate.new File.open("spec/fixtures/client_cert.pem").read
157
+ request.auth.ssl.cert_key = OpenSSL::PKey.read File.open("spec/fixtures/client_key.pem").read
158
+
159
+ response = HTTPI.get(request, adapter)
160
+ expect(response.body).to eq("get")
161
+ end
162
+
163
+ it "works with ciphers" do
164
+ request = HTTPI::Request.new(@server.url)
165
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
166
+ request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
167
+
168
+ response = HTTPI.get(request, adapter)
169
+ expect(response.body).to eq("get")
170
+ end
171
+ end
172
+ end
173
+
174
+ end
@@ -1,44 +1,19 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- MIID0DCCArigAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
3
- MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
4
- DTA0MDEzMDAwNDIzMloXDTM2MDEyMjAwNDIzMlowPDELMAkGA1UEBgwCSlAxEjAQ
5
- BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQswCQYDVQQDDAJDQTCCASIw
6
- DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANbv0x42BTKFEQOE+KJ2XmiSdZpR
7
- wjzQLAkPLRnLB98tlzs4xo+y4RyY/rd5TT9UzBJTIhP8CJi5GbS1oXEerQXB3P0d
8
- L5oSSMwGGyuIzgZe5+vZ1kgzQxMEKMMKlzA73rbMd4Jx3u5+jdbP0EDrPYfXSvLY
9
- bS04n2aX7zrN3x5KdDrNBfwBio2/qeaaj4+9OxnwRvYP3WOvqdW0h329eMfHw0pi
10
- JI0drIVdsEqClUV4pebT/F+CPUPkEh/weySgo9wANockkYu5ujw2GbLFcO5LXxxm
11
- dEfcVr3r6t6zOA4bJwL0W/e6LBcrwiG/qPDFErhwtgTLYf6Er67SzLyA66UCAwEA
12
- AaOB3DCB2TAPBgNVHRMBAf8EBTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09w
13
- ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRJ7Xd380KzBV7f
14
- USKIQ+O/vKbhDzAOBgNVHQ8BAf8EBAMCAQYwZAYDVR0jBF0wW4AUSe13d/NCswVe
15
- 31EiiEPjv7ym4Q+hQKQ+MDwxCzAJBgNVBAYMAkpQMRIwEAYDVQQKDAlKSU4uR1Iu
16
- SlAxDDAKBgNVBAsMA1JSUjELMAkGA1UEAwwCQ0GCAQAwDQYJKoZIhvcNAQEFBQAD
17
- ggEBAIu/mfiez5XN5tn2jScgShPgHEFJBR0BTJBZF6xCk0jyqNx/g9HMj2ELCuK+
18
- r/Y7KFW5c5M3AQ+xWW0ZSc4kvzyTcV7yTVIwj2jZ9ddYMN3nupZFgBK1GB4Y05GY
19
- MJJFRkSu6d/Ph5ypzBVw2YMT/nsOo5VwMUGLgS7YVjU+u/HNWz80J3oO17mNZllj
20
- PvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U
21
- PbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a
22
- d/xgcK06UVQRL/HbEYGiQL056mc=
23
- -----END CERTIFICATE-----
24
- -----BEGIN CERTIFICATE-----
25
- MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
26
- MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
27
- DTA0MDEzMDAwNDMyN1oXDTM1MDEyMjAwNDMyN1owPzELMAkGA1UEBgwCSlAxEjAQ
28
- BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQ4wDAYDVQQDDAVTdWJDQTCC
29
- ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0Ou7AyRcRXnB/kVHv/6kwe
30
- ANzgg/DyJfsAUqW90m7Lu1nqyug8gK0RBd77yU0w5HOAMHTVSdpjZK0g2sgx4Mb1
31
- d/213eL9TTl5MRVEChTvQr8q5DVG/8fxPPE7fMI8eOAzd98/NOAChk+80r4Sx7fC
32
- kGVEE1bKwY1MrUsUNjOY2d6t3M4HHV3HX1V8ShuKfsHxgCmLzdI8U+5CnQedFgkm
33
- 3e+8tr8IX5RR1wA1Ifw9VadF7OdI/bGMzog/Q8XCLf+WPFjnK7Gcx6JFtzF6Gi4x
34
- 4dp1Xl45JYiVvi9zQ132wu8A1pDHhiNgQviyzbP+UjcB/tsOpzBQF8abYzgEkWEC
35
- AwEAAaNyMHAwDwYDVR0TAQH/BAUwAwEB/zAxBglghkgBhvhCAQ0EJBYiUnVieS9P
36
- cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUlCjXWLsReYzH
37
- LzsxwVnCXmKoB/owCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCJ/OyN
38
- rT8Cq2Y+G2yA/L1EMRvvxwFBqxavqaqHl/6rwsIBFlB3zbqGA/0oec6MAVnYynq4
39
- c4AcHTjx3bQ/S4r2sNTZq0DH4SYbQzIobx/YW8PjQUJt8KQdKMcwwi7arHP7A/Ha
40
- LKu8eIC2nsUBnP4NhkYSGhbmpJK+PFD0FVtD0ZIRlY/wsnaZNjWWcnWF1/FNuQ4H
41
- ySjIblqVQkPuzebv3Ror6ZnVDukn96Mg7kP4u6zgxOeqlJGRe1M949SS9Vudjl8X
42
- SF4aZUUB9pQGhsqQJVqaz2OlhGOp9D0q54xko/rekjAIcuDjl1mdX4F2WRrzpUmZ
43
- uY/bPeOBYiVsOYVe
2
+ MIIDDjCCAfagAwIBAgIBAzANBgkqhkiG9w0BAQsFADA4MRMwEQYKCZImiZPyLGQB
3
+ GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCQ0EwHhcNMjAw
4
+ ODAxMDAwMDAwWhcNMjQwODAxMDAwMDAwWjA4MRMwEQYKCZImiZPyLGQBGRYDbmV0
5
+ MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCQ0EwggEiMA0GCSqGSIb3
6
+ DQEBAQUAA4IBDwAwggEKAoIBAQDIHxrFcS2JkRQbXLFosb32unVkVuwHSPSt6Dpl
7
+ 2jUQHP/bceAx/d9waHYf8rlbCFAIoduZDOc7XCJUidgcG5NfLJyQpkkWOU8CGWH+
8
+ Ipl4AE8auYCcy/0T7BQqaRC41HPmrJG1CC40rqcY47lUO2haI+vj5TZFHNhAbRat
9
+ rR1iD1veis2gBZtrMzd4IlpvEHGv6ghfnSc20za4exmapjp/uAAIOXpeFX8QHumA
10
+ bty4dd+iHpKjDzUrhG9Qa5v28ii2K1AcbczUQ7FzSp2/GoRSjF+WY6i86N9Z1M97
11
+ 2PEgy0IG5l6JHu1P0/rd00hN0h0Owzv3V5ldMLZap7+pVFQTAgMBAAGjIzAhMA8G
12
+ A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IB
13
+ AQA3GWpy4bYLOHLENDTUBeclF6cDdYiautD6gxd1SDLMWOhAUF7ywwT87OAJdr1I
14
+ +W1TUv5BRG21rNm1QsZfLbStdKA1mpiET/9nYN7m1YauL5hI3yD49TGuO9/sxcE5
15
+ zNW7D3VBVNq+pyT21/TvLAgxCNvjjm7byzyIOcoRUyZx8WhCf8nUT6cEShXqEg4Q
16
+ iUBSLI38tiQoZneuVzDRlXBY0PqoB19l2Kg9yThHjPTVhw5EAQSDKXCCvaxAbVw6
17
+ ZPLNnOdK6DvqEZ3GC5WlaHQdmLxmN4OfV6AEtpgqgGY9u8K1ylTr3ET7xLK7bhcA
18
+ oZsggEVZr1Ifx9BWIazRNwlw
44
19
  -----END CERTIFICATE-----
@@ -1,19 +1,19 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- MIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQGDAJKUDES
3
- MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxDjAMBgNVBAMMBVN1YkNB
4
- MB4XDTA0MDEzMTAzMTMxNloXDTMzMDEyMzAzMTMxNlowQzELMAkGA1UEBgwCSlAx
5
- EjAQBgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRIwEAYDVQQDDAlsb2Nh
6
- bGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANFJTxWqup3nV9dsJAku
7
- p+WaXnPNIzcpAA3qMGZDJTJsfa8Du7ZxTP0XJK5mETttBrn711cJxAuP3KjqnW9S
8
- vtZ9lY2sXJ6Zj62sN5LwG3VVe25dI28yR1EsbHjJ5Zjf9tmggMC6am52dxuHbt5/
9
- vHo4ngJuKE/U+eeGRivMn6gFAgMBAAGjgYUwgYIwDAYDVR0TAQH/BAIwADAxBglg
10
- hkgBhvhCAQ0EJBYiUnVieS9PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
11
- BgNVHQ4EFgQUpZIyygD9JxFYHHOTEuWOLbCKfckwCwYDVR0PBAQDAgWgMBMGA1Ud
12
- JQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQBwAIj5SaBHaA5X31IP
13
- CFCJiep96awfp7RANO0cuUj+ZpGoFn9d6FXY0g+Eg5wAkCNIzZU5NHN9xsdOpnUo
14
- zIBbyTfQEPrge1CMWMvL6uGaoEXytq84VTitF/xBTky4KtTn6+es4/e7jrrzeUXQ
15
- RC46gkHObmDT91RkOEGjHLyld2328jo3DIN/VTHIryDeVHDWjY5dENwpwdkhhm60
16
- DR9IrNBbXWEe9emtguNXeN0iu1ux0lG1Hc6pWGQxMlRKNvGh0yZB9u5EVe38tOV0
17
- jQaoNyL7qzcQoXD3Dmbi1p0iRmg/+HngISsz8K7k7MBNVsSclztwgCzTZOBiVtkM
18
- rRlQ
2
+ MIIDBDCCAeygAwIBAgIBBzANBgkqhkiG9w0BAQsFADA4MRMwEQYKCZImiZPyLGQB
3
+ GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCQ0EwHhcNMjAw
4
+ ODAxMDAwMDAwWhcNMjQwODAxMDAwMDAwWjA/MRMwEQYKCZImiZPyLGQBGRYDbmV0
5
+ MRQwEgYKCZImiZPyLGQBGRYEcHVtYTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjAN
6
+ BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvXOg3gTrGJfVft9cSrfGRnEZezDB
7
+ L93fcLwJAoaXGxbEg1RW/fOrSpSNemuqOvbzczV7m5eYTf1lHPBJsndbYyijIR1+
8
+ Fp4tjFDp76SC3hxCIc3uYXIz0qQwSOAi1z15zobS4xF29jlsXWtfBl9fivjzdj/f
9
+ pbZ+JPYOrlcJAf6Xmr3xh//13rOI0ytBMlWf51z/iAZBLm2wvbt+nR7B6koAdTgM
10
+ Coe+gOtcLWYY5ApJ4qB9knGdxWoF5p7guHHw2aGTM0jyhgBowfVkFRiE2JUmODae
11
+ g+dHsd8ogWbqhGyZTredJF/NRrLKU0h+t7ldKHvXEZy4qyqQlvKoTpODqQIDAQAB
12
+ oxIwEDAOBgNVHQ8BAf8EBAMCBLAwDQYJKoZIhvcNAQELBQADggEBAI/bcQP4Hu9O
13
+ OtaaIjVxN8+9jXUOrMpSogmZ4bRKImispt9SA+sbxec7iOMM2pG3Py2yi0hWGzii
14
+ hSebWIsM1JuPj7ks9l8nGRxpGeInJwTkJorG4ZLEypoS2wW3fQZGx3o4da5V+U2Z
15
+ HEY0wQTbPBqqnyeZ16ZFNVCzw8y9l7y7CEFjvUO3sq0pne9r7Z+XVgjGyBdBYkJS
16
+ 0kcqPBXFCMHrWH5UlacYlM5cqgoVztOp2STGmR3XR7a34oueeA10QSP+jzeYvWA1
17
+ wTYA762uU2ReCdujfNbf8V1tZWAH36KldM3hhDNWeveAGxxj1h2R9T/k2kHl/a7D
18
+ I3VdS59vjJY=
19
19
  -----END CERTIFICATE-----
@@ -1,15 +1,27 @@
1
1
  -----BEGIN RSA PRIVATE KEY-----
2
- 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
- cUz9FySuZhE7bQa5+9dXCcQLj9yo6p1vUr7WfZWNrFyemY+trDeS8Bt1VXtuXSNv
4
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
15
27
  -----END RSA PRIVATE KEY-----
@@ -0,0 +1,156 @@
1
+ require "spec_helper"
2
+ require "integration/support/server"
3
+
4
+ describe HTTPI::Adapter::HTTP do
5
+
6
+ subject(:adapter) { :http }
7
+
8
+ context "http requests" do
9
+ before :all do
10
+ @server = IntegrationServer.run
11
+ end
12
+
13
+ after :all do
14
+ @server.stop
15
+ end
16
+
17
+ it "sends and receives HTTP headers" do
18
+ request = HTTPI::Request.new(@server.url + "x-header")
19
+ request.headers["X-Header"] = "HTTPI"
20
+
21
+ response = HTTPI.get(request, adapter)
22
+ expect(response.body).to include("HTTPI")
23
+ end
24
+
25
+ it "it supports headers with multiple values" do
26
+ request = HTTPI::Request.new(@server.url + "cookies")
27
+
28
+ response = HTTPI.get(request, adapter)
29
+ cookies = ["cookie1=chip1; path=/", "cookie2=chip2; path=/"]
30
+ expect(response.headers["Set-Cookie"]).to eq(cookies)
31
+ end
32
+
33
+ it "it supports read timeout" do
34
+ require "http"
35
+
36
+ request = HTTPI::Request.new(@server.url + "timeout")
37
+ request.read_timeout = 0.5 # seconds
38
+
39
+ expect do
40
+ HTTPI.get(request, adapter)
41
+ end.to raise_exception(HTTP::TimeoutError)
42
+ end
43
+
44
+
45
+ it "executes GET requests" do
46
+ response = HTTPI.get(@server.url, adapter)
47
+ expect(response.body).to eq("get")
48
+ expect(response.headers["Content-Type"]).to eq("text/plain")
49
+ end
50
+
51
+ it "executes POST requests" do
52
+ response = HTTPI.post(@server.url, "<some>xml</some>", adapter)
53
+ expect(response.body).to eq("post")
54
+ expect(response.headers["Content-Type"]).to eq("text/plain")
55
+ end
56
+
57
+ it "executes HEAD requests" do
58
+ response = HTTPI.head(@server.url, adapter)
59
+ expect(response.code).to eq(200)
60
+ expect(response.headers["Content-Type"]).to eq("text/plain")
61
+ end
62
+
63
+ it "executes PUT requests" do
64
+ response = HTTPI.put(@server.url, "<some>xml</some>", adapter)
65
+ expect(response.body).to eq("put")
66
+ expect(response.headers["Content-Type"]).to eq("text/plain")
67
+ end
68
+
69
+ it "executes DELETE requests" do
70
+ response = HTTPI.delete(@server.url, adapter)
71
+ expect(response.body).to eq("delete")
72
+ expect(response.headers["Content-Type"]).to eq("text/plain")
73
+ end
74
+
75
+ it "supports basic authentication" do
76
+ request = HTTPI::Request.new(@server.url + "basic-auth")
77
+ request.auth.basic("admin", "secret")
78
+
79
+ response = HTTPI.get(request, adapter)
80
+ expect(response.body).to eq("basic-auth")
81
+ end
82
+
83
+ it "does not support digest authentication" do
84
+ request = HTTPI::Request.new(@server.url + "digest-auth")
85
+ request.auth.digest("admin", "secret")
86
+
87
+ expect { HTTPI.get(request, adapter) }.
88
+ to raise_error(HTTPI::NotSupportedError, /does not support HTTP digest authentication/)
89
+ end
90
+
91
+ it "does not support ntlm authentication" do
92
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
93
+ request.auth.ntlm("tester", "vReqSoafRe5O")
94
+
95
+ expect { HTTPI.get(request, adapter) }.
96
+ to raise_error(HTTPI::NotSupportedError, /does not support NTLM digest authentication/)
97
+ end
98
+
99
+ it "supports chunked response" do
100
+ skip("Needs investigation")
101
+ request = HTTPI::Request.new(@server.url)
102
+ res = ""
103
+ request.on_body do |body|
104
+ res += body
105
+ end
106
+ response = HTTPI.post(request, adapter)
107
+ expect(res).to eq("post")
108
+ expect(response.body).to eq("")
109
+ end
110
+ end
111
+
112
+ if RUBY_PLATFORM =~ /java/
113
+ pending "Puma Server complains: SSL not supported on JRuby"
114
+ else
115
+ context "https requests" do
116
+ before :all do
117
+ @server = IntegrationServer.run(:ssl => true)
118
+ end
119
+ after :all do
120
+ @server.stop
121
+ end
122
+
123
+ it "raises when no certificate was set up" do
124
+ expect { HTTPI.post(@server.url, "", adapter) }.to raise_error(HTTPI::SSLError)
125
+ end
126
+
127
+ it "works when set up properly" do
128
+ request = HTTPI::Request.new(@server.url)
129
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
130
+
131
+ response = HTTPI.get(request, adapter)
132
+ expect(response.body).to eq("get")
133
+ end
134
+
135
+ it "works with min_version/max_version" do
136
+ request = HTTPI::Request.new(@server.url)
137
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
138
+ request.auth.ssl.min_version = :TLS1_2
139
+ request.auth.ssl.max_version = :TLS1_2
140
+
141
+ response = HTTPI.get(request, adapter)
142
+ expect(response.body).to eq("get")
143
+ end
144
+
145
+ it "works with ciphers" do
146
+ request = HTTPI::Request.new(@server.url)
147
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
148
+ request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
149
+
150
+ response = HTTPI.get(request, adapter)
151
+ expect(response.body).to eq("get")
152
+ end
153
+ end
154
+ end
155
+
156
+ end
@@ -30,6 +30,17 @@ describe HTTPI::Adapter::HTTPClient do
30
30
  expect(response.headers["Set-Cookie"]).to eq(cookies)
31
31
  end
32
32
 
33
+ it "it supports read timeout" do
34
+ require "httpclient"
35
+
36
+ request = HTTPI::Request.new(@server.url + "timeout")
37
+ request.read_timeout = 0.5 # seconds
38
+
39
+ expect do
40
+ HTTPI.get(request, adapter)
41
+ end.to raise_exception(HTTPClient::ReceiveTimeoutError)
42
+ end
43
+
33
44
  it "executes GET requests" do
34
45
  response = HTTPI.get(@server.url, adapter)
35
46
  expect(response.body).to eq("get")
@@ -110,6 +121,15 @@ describe HTTPI::Adapter::HTTPClient do
110
121
  response = HTTPI.get(request, adapter)
111
122
  expect(response.body).to eq("get")
112
123
  end
124
+
125
+ it "works with ciphers" do
126
+ request = HTTPI::Request.new(@server.url)
127
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
128
+ request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
129
+
130
+ response = HTTPI.get(request, adapter)
131
+ expect(response.body).to eq("get")
132
+ end
113
133
  end
114
134
  end
115
135
 
@@ -1,7 +1,8 @@
1
1
  require "spec_helper"
2
2
  require "integration/support/server"
3
+ require "net/http/persistent"
3
4
 
4
- describe HTTPI::Adapter::NetHTTP do
5
+ describe HTTPI::Adapter::NetHTTPPersistent do
5
6
 
6
7
  subject(:adapter) { :net_http_persistent }
7
8
 
@@ -30,6 +31,17 @@ describe HTTPI::Adapter::NetHTTP do
30
31
  expect(response.headers["Set-Cookie"]).to eq(cookies)
31
32
  end
32
33
 
34
+ it "it supports read timeout" do
35
+ require "net/http/persistent"
36
+
37
+ request = HTTPI::Request.new(@server.url + "timeout")
38
+ request.read_timeout = 0.5 # seconds
39
+
40
+ expect do
41
+ HTTPI.get(request, adapter)
42
+ end.to raise_exception(Net::ReadTimeout)
43
+ end
44
+
33
45
  it "executes GET requests" do
34
46
  response = HTTPI.get(@server.url, adapter)
35
47
  expect(response.body).to eq("get")
@@ -37,7 +49,9 @@ describe HTTPI::Adapter::NetHTTP do
37
49
  end
38
50
 
39
51
  it "executes POST requests" do
40
- response = HTTPI.post(@server.url, "<some>xml</some>", adapter)
52
+ request = HTTPI::Request.new(url: @server.url, body: "<some>xml</some>")
53
+
54
+ response = HTTPI.post(request, adapter)
41
55
  expect(response.body).to eq("post")
42
56
  expect(response.headers["Content-Type"]).to eq("text/plain")
43
57
  end
@@ -68,6 +82,14 @@ describe HTTPI::Adapter::NetHTTP do
68
82
  expect(response.body).to eq("basic-auth")
69
83
  end
70
84
 
85
+ it "does not support ntlm authentication" do
86
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
87
+ request.auth.ntlm("tester", "vReqSoafRe5O")
88
+
89
+ expect { HTTPI.get(request, adapter) }.
90
+ to raise_error(HTTPI::NotSupportedError, /does not support NTLM authentication/)
91
+ end
92
+
71
93
  # it does not support digest authentication
72
94
 
73
95
  it "supports chunked response" do
@@ -89,6 +111,7 @@ describe HTTPI::Adapter::NetHTTP do
89
111
  before :all do
90
112
  @server = IntegrationServer.run(:ssl => true)
91
113
  end
114
+
92
115
  after :all do
93
116
  @server.stop
94
117
  end
@@ -101,6 +124,15 @@ describe HTTPI::Adapter::NetHTTP do
101
124
  response = HTTPI.get(request, adapter)
102
125
  expect(response.body).to eq("get")
103
126
  end
127
+
128
+ it "works with ciphers" do
129
+ request = HTTPI::Request.new(@server.url)
130
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
131
+ request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
132
+
133
+ response = HTTPI.get(request, adapter)
134
+ expect(response.body).to eq("get")
135
+ end
104
136
  end
105
137
  end
106
138