ethon 0.5.12 → 0.6.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.
Files changed (66) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +11 -0
  5. data/CHANGELOG.md +5 -0
  6. data/Gemfile +1 -1
  7. data/Guardfile +9 -0
  8. data/ethon.gemspec +26 -0
  9. data/lib/ethon/curl.rb +0 -12
  10. data/lib/ethon/curls/constants.rb +6 -22
  11. data/lib/ethon/curls/functions.rb +38 -41
  12. data/lib/ethon/curls/infos.rb +19 -0
  13. data/lib/ethon/curls/options.rb +416 -219
  14. data/lib/ethon/curls/settings.rb +1 -0
  15. data/lib/ethon/easy.rb +12 -18
  16. data/lib/ethon/easy/callbacks.rb +40 -6
  17. data/lib/ethon/easy/debug_info.rb +46 -0
  18. data/lib/ethon/easy/mirror.rb +39 -0
  19. data/lib/ethon/easy/options.rb +17 -1235
  20. data/lib/ethon/easy/queryable.rb +6 -8
  21. data/lib/ethon/easy/response_callbacks.rb +1 -1
  22. data/lib/ethon/version.rb +1 -1
  23. data/profile/benchmarks.rb +137 -0
  24. data/profile/memory_leaks.rb +113 -0
  25. data/profile/perf_spec_helper.rb +36 -0
  26. data/profile/support/memory_test_helpers.rb +75 -0
  27. data/profile/support/os_memory_leak_tracker.rb +47 -0
  28. data/profile/support/ruby_object_leak_tracker.rb +48 -0
  29. data/spec/ethon/curl_spec.rb +27 -0
  30. data/spec/ethon/easy/callbacks_spec.rb +31 -0
  31. data/spec/ethon/easy/debug_info_spec.rb +52 -0
  32. data/spec/ethon/easy/form_spec.rb +76 -0
  33. data/spec/ethon/easy/header_spec.rb +78 -0
  34. data/spec/ethon/easy/http/custom_spec.rb +176 -0
  35. data/spec/ethon/easy/http/delete_spec.rb +20 -0
  36. data/spec/ethon/easy/http/get_spec.rb +89 -0
  37. data/spec/ethon/easy/http/head_spec.rb +79 -0
  38. data/spec/ethon/easy/http/options_spec.rb +50 -0
  39. data/spec/ethon/easy/http/patch_spec.rb +50 -0
  40. data/spec/ethon/easy/http/post_spec.rb +220 -0
  41. data/spec/ethon/easy/http/put_spec.rb +124 -0
  42. data/spec/ethon/easy/http_spec.rb +44 -0
  43. data/spec/ethon/easy/informations_spec.rb +82 -0
  44. data/spec/ethon/easy/mirror_spec.rb +39 -0
  45. data/spec/ethon/easy/operations_spec.rb +251 -0
  46. data/spec/ethon/easy/options_spec.rb +135 -0
  47. data/spec/ethon/easy/queryable_spec.rb +188 -0
  48. data/spec/ethon/easy/response_callbacks_spec.rb +50 -0
  49. data/spec/ethon/easy/util_spec.rb +27 -0
  50. data/spec/ethon/easy_spec.rb +105 -0
  51. data/spec/ethon/libc_spec.rb +13 -0
  52. data/spec/ethon/loggable_spec.rb +21 -0
  53. data/spec/ethon/multi/operations_spec.rb +297 -0
  54. data/spec/ethon/multi/options_spec.rb +70 -0
  55. data/spec/ethon/multi/stack_spec.rb +79 -0
  56. data/spec/ethon/multi_spec.rb +21 -0
  57. data/spec/spec_helper.rb +27 -0
  58. data/spec/support/localhost_server.rb +94 -0
  59. data/spec/support/server.rb +114 -0
  60. metadata +91 -31
  61. data/lib/ethon/curls/auth_types.rb +0 -25
  62. data/lib/ethon/curls/http_versions.rb +0 -22
  63. data/lib/ethon/curls/postredir.rb +0 -15
  64. data/lib/ethon/curls/protocols.rb +0 -36
  65. data/lib/ethon/curls/proxy_types.rb +0 -25
  66. data/lib/ethon/curls/ssl_versions.rb +0 -23
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ethon::Easy::Http::Delete do
4
+ let(:easy) { Ethon::Easy.new }
5
+ let(:url) { "http://localhost:3001/" }
6
+ let(:params) { nil }
7
+ let(:form) { nil }
8
+ let(:delete) { described_class.new(url, {:params => params, :body => form}) }
9
+
10
+ context "when requesting" do
11
+ before do
12
+ delete.setup(easy)
13
+ easy.perform
14
+ end
15
+
16
+ it "makes a delete request" do
17
+ expect(easy.response_body).to include('"REQUEST_METHOD":"DELETE"')
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ethon::Easy::Http::Get do
4
+ let(:easy) { Ethon::Easy.new }
5
+ let(:url) { "http://localhost:3001/" }
6
+ let(:params) { nil }
7
+ let(:form) { nil }
8
+ let(:get) { described_class.new(url, {:params => params, :body => form}) }
9
+
10
+ describe "#setup" do
11
+ it "sets url" do
12
+ get.setup(easy)
13
+ expect(easy.url).to eq(url)
14
+ end
15
+
16
+ context "when body" do
17
+ let(:form) { { :a => 1 } }
18
+
19
+ it "sets customrequest" do
20
+ easy.should_receive(:customrequest=).with("GET")
21
+ get.setup(easy)
22
+ end
23
+ end
24
+
25
+ context "when no body" do
26
+ it "doesn't set customrequest" do
27
+ easy.should_receive(:customrequest=).never
28
+ get.setup(easy)
29
+ end
30
+ end
31
+
32
+ context "when requesting" do
33
+ before do
34
+ get.setup(easy)
35
+ easy.perform
36
+ end
37
+
38
+ context "when url already contains params" do
39
+ let(:url) { "http://localhost:3001/?query=here" }
40
+ let(:params) { {:a => "1&b=2"} }
41
+
42
+ it "returns ok" do
43
+ expect(easy.return_code).to eq(:ok)
44
+ end
45
+
46
+ it "is a get request" do
47
+ expect(easy.response_body).to include('"REQUEST_METHOD":"GET"')
48
+ end
49
+
50
+ it "requests parameterized url" do
51
+ expect(easy.effective_url).to eq("http://localhost:3001/?query=here&a=1%26b%3D2")
52
+ end
53
+ end
54
+
55
+ context "when params and no body" do
56
+ let(:params) { {:a => "1&b=2"} }
57
+
58
+ it "returns ok" do
59
+ expect(easy.return_code).to eq(:ok)
60
+ end
61
+
62
+ it "is a get request" do
63
+ expect(easy.response_body).to include('"REQUEST_METHOD":"GET"')
64
+ end
65
+
66
+ it "requests parameterized url" do
67
+ expect(easy.effective_url).to eq("http://localhost:3001/?a=1%26b%3D2")
68
+ end
69
+ end
70
+
71
+ context "when params and body" do
72
+ let(:params) { {:a => "1&b=2"} }
73
+ let(:form) { {:b => "2"} }
74
+
75
+ it "returns ok" do
76
+ expect(easy.return_code).to eq(:ok)
77
+ end
78
+
79
+ it "is a get request" do
80
+ expect(easy.response_body).to include('"REQUEST_METHOD":"GET"')
81
+ end
82
+
83
+ it "requests parameterized url" do
84
+ expect(easy.effective_url).to eq("http://localhost:3001/?a=1%26b%3D2")
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ethon::Easy::Http::Head do
4
+ let(:easy) { Ethon::Easy.new }
5
+ let(:url) { "http://localhost:3001/" }
6
+ let(:params) { nil }
7
+ let(:form) { nil }
8
+ let(:head) { described_class.new(url, {:params => params, :body => form}) }
9
+
10
+ describe "#setup" do
11
+ context "when nothing" do
12
+ it "sets nobody" do
13
+ easy.should_receive(:nobody=).with(true)
14
+ head.setup(easy)
15
+ end
16
+
17
+ it "sets url" do
18
+ head.setup(easy)
19
+ expect(easy.url).to eq(url)
20
+ end
21
+ end
22
+
23
+ context "when params" do
24
+ let(:params) { {:a => "1&b=2"} }
25
+
26
+ it "sets nobody" do
27
+ easy.should_receive(:nobody=).with(true)
28
+ head.setup(easy)
29
+ end
30
+
31
+ it "attaches escaped to url" do
32
+ head.setup(easy)
33
+ expect(easy.url).to eq("#{url}?a=1%26b%3D2")
34
+ end
35
+
36
+ context "when requesting" do
37
+ before do
38
+ head.setup(easy)
39
+ easy.perform
40
+ end
41
+
42
+ it "returns ok" do
43
+ expect(easy.return_code).to eq(:ok)
44
+ end
45
+
46
+ it "has no body" do
47
+ expect(easy.response_body).to be_empty
48
+ end
49
+
50
+ it "requests parameterized url" do
51
+ expect(easy.effective_url).to eq("http://localhost:3001/?a=1%26b%3D2")
52
+ end
53
+
54
+ context "when url already contains params" do
55
+ let(:url) { "http://localhost:3001/?query=here" }
56
+
57
+ it "requests parameterized url" do
58
+ expect(easy.effective_url).to eq("http://localhost:3001/?query=here&a=1%26b%3D2")
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ context "when body" do
65
+ let(:form) { {:a => 1} }
66
+
67
+ context "when requesting" do
68
+ before do
69
+ head.setup(easy)
70
+ easy.perform
71
+ end
72
+
73
+ it "returns ok" do
74
+ expect(easy.return_code).to eq(:ok)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ethon::Easy::Http::Options do
4
+ let(:easy) { Ethon::Easy.new }
5
+ let(:url) { "http://localhost:3001/" }
6
+ let(:params) { nil }
7
+ let(:form) { nil }
8
+ let(:options) { described_class.new(url, {:params => params, :body => form}) }
9
+
10
+ describe "#setup" do
11
+ it "sets customrequest" do
12
+ easy.should_receive(:customrequest=).with("OPTIONS")
13
+ options.setup(easy)
14
+ end
15
+
16
+ it "sets url" do
17
+ options.setup(easy)
18
+ expect(easy.url).to eq(url)
19
+ end
20
+
21
+ context "when requesting" do
22
+ let(:params) { {:a => "1&b=2"} }
23
+
24
+ before do
25
+ options.setup(easy)
26
+ easy.perform
27
+ end
28
+
29
+ it "returns ok" do
30
+ expect(easy.return_code).to eq(:ok)
31
+ end
32
+
33
+ it "is a options request" do
34
+ expect(easy.response_body).to include('"REQUEST_METHOD":"OPTIONS"')
35
+ end
36
+
37
+ it "requests parameterized url" do
38
+ expect(easy.effective_url).to eq("http://localhost:3001/?a=1%26b%3D2")
39
+ end
40
+
41
+ context "when url already contains params" do
42
+ let(:url) { "http://localhost:3001/?query=here" }
43
+
44
+ it "requests parameterized url" do
45
+ expect(easy.effective_url).to eq("http://localhost:3001/?query=here&a=1%26b%3D2")
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ethon::Easy::Http::Patch do
4
+ let(:easy) { Ethon::Easy.new }
5
+ let(:url) { "http://localhost:3001/" }
6
+ let(:params) { nil }
7
+ let(:form) { nil }
8
+ let(:patch) { described_class.new(url, {:params => params, :body => form}) }
9
+
10
+ describe "#setup" do
11
+ it "sets customrequest" do
12
+ easy.should_receive(:customrequest=).with("PATCH")
13
+ patch.setup(easy)
14
+ end
15
+
16
+ it "sets url" do
17
+ patch.setup(easy)
18
+ expect(easy.url).to eq(url)
19
+ end
20
+
21
+ context "when requesting" do
22
+ let(:params) { {:a => "1&b=2"} }
23
+
24
+ before do
25
+ patch.setup(easy)
26
+ easy.perform
27
+ end
28
+
29
+ it "returns ok" do
30
+ expect(easy.return_code).to eq(:ok)
31
+ end
32
+
33
+ it "is a patch request" do
34
+ expect(easy.response_body).to include('"REQUEST_METHOD":"PATCH"')
35
+ end
36
+
37
+ it "requests parameterized url" do
38
+ expect(easy.effective_url).to eq("http://localhost:3001/?a=1%26b%3D2")
39
+ end
40
+
41
+ context "when url already contains params" do
42
+ let(:url) { "http://localhost:3001/?query=here" }
43
+
44
+ it "requests parameterized url" do
45
+ expect(easy.effective_url).to eq("http://localhost:3001/?query=here&a=1%26b%3D2")
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,220 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ethon::Easy::Http::Post do
4
+ let(:easy) { Ethon::Easy.new }
5
+ let(:url) { "http://localhost:3001/" }
6
+ let(:params) { nil }
7
+ let(:form) { nil }
8
+ let(:post) { described_class.new(url, {:params => params, :body => form}) }
9
+
10
+ describe "#setup" do
11
+ context "when nothing" do
12
+ it "sets url" do
13
+ post.setup(easy)
14
+ expect(easy.url).to eq(url)
15
+ end
16
+
17
+ it "sets postfield_size" do
18
+ easy.should_receive(:postfieldsize=).with(0)
19
+ post.setup(easy)
20
+ end
21
+
22
+ it "sets copy_postfields" do
23
+ easy.should_receive(:copypostfields=).with("")
24
+ post.setup(easy)
25
+ end
26
+
27
+ it "makes a post request" do
28
+ post.setup(easy)
29
+ easy.perform
30
+ expect(easy.response_body).to include('"REQUEST_METHOD":"POST"')
31
+ end
32
+ end
33
+
34
+ context "when params" do
35
+ let(:params) { {:a => "1&"} }
36
+
37
+ it "attaches escaped to url" do
38
+ post.setup(easy)
39
+ expect(easy.url).to eq("#{url}?a=1%26")
40
+ end
41
+
42
+ it "sets postfieldsize" do
43
+ easy.should_receive(:postfieldsize=).with(0)
44
+ post.setup(easy)
45
+ end
46
+
47
+ it "sets copypostfields" do
48
+ easy.should_receive(:copypostfields=).with("")
49
+ post.setup(easy)
50
+ end
51
+
52
+ context "when requesting" do
53
+ let(:postredir) { nil }
54
+
55
+ before do
56
+ easy.headers = { 'Expect' => '' }
57
+ post.setup(easy)
58
+ easy.postredir = postredir
59
+ easy.followlocation = true
60
+ easy.perform
61
+ end
62
+
63
+ it "is a post" do
64
+ expect(easy.response_body).to include('"REQUEST_METHOD":"POST"')
65
+ end
66
+
67
+ it "uses application/x-www-form-urlencoded content type" do
68
+ expect(easy.response_body).to include('"CONTENT_TYPE":"application/x-www-form-urlencoded"')
69
+ end
70
+
71
+ it "requests parameterized url" do
72
+ expect(easy.response_body).to include('"REQUEST_URI":"http://localhost:3001/?a=1%26"')
73
+ end
74
+
75
+ context "when redirection" do
76
+ let(:url) { "localhost:3001/redirect" }
77
+
78
+ context "when no postredirs" do
79
+ it "is a get" do
80
+ expect(easy.response_body).to include('"REQUEST_METHOD":"GET"')
81
+ end
82
+ end
83
+
84
+ unless ENV['TRAVIS']
85
+ context "when postredirs" do
86
+ let(:postredir) { :post_all }
87
+
88
+ it "is a post" do
89
+ expect(easy.response_body).to include('"REQUEST_METHOD":"POST"')
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ context "when body" do
98
+ context "when multipart" do
99
+ let(:form) { {:a => File.open(__FILE__, 'r')} }
100
+
101
+ it "sets httppost" do
102
+ easy.should_receive(:httppost=)
103
+ post.setup(easy)
104
+ end
105
+
106
+ context "when requesting" do
107
+ before do
108
+ easy.headers = { 'Expect' => '' }
109
+ post.setup(easy)
110
+ easy.perform
111
+ end
112
+
113
+ it "returns ok" do
114
+ expect(easy.return_code).to eq(:ok)
115
+ end
116
+
117
+ it "is a post" do
118
+ expect(easy.response_body).to include('"REQUEST_METHOD":"POST"')
119
+ end
120
+
121
+ it "uses multipart/form-data content type" do
122
+ expect(easy.response_body).to include('"CONTENT_TYPE":"multipart/form-data')
123
+ end
124
+
125
+ it "submits a body" do
126
+ expect(easy.response_body).to match('"body":".+"')
127
+ end
128
+
129
+ it "submits the data" do
130
+ expect(easy.response_body).to include('"filename":"post_spec.rb"')
131
+ end
132
+ end
133
+ end
134
+
135
+ context "when not multipart" do
136
+ let(:form) { {:a => "1&b=2"} }
137
+ let(:encoded) { "a=1%26b%3D2" }
138
+
139
+ it "sets escaped copypostfields" do
140
+ easy.should_receive(:copypostfields=).with(encoded)
141
+ post.setup(easy)
142
+ end
143
+
144
+ it "sets postfieldsize" do
145
+ easy.should_receive(:postfieldsize=).with{ |value| expect(value).to be(encoded.bytesize) }
146
+ post.setup(easy)
147
+ end
148
+
149
+ context "when requesting" do
150
+ before do
151
+ easy.headers = { 'Expect' => '' }
152
+ post.setup(easy)
153
+ easy.perform
154
+ end
155
+
156
+ it "returns ok" do
157
+ expect(easy.return_code).to eq(:ok)
158
+ end
159
+
160
+ it "is a post" do
161
+ expect(easy.response_body).to include('"REQUEST_METHOD":"POST"')
162
+ end
163
+
164
+ it "uses multipart/form-data content type" do
165
+ expect(easy.response_body).to include('"CONTENT_TYPE":"application/x-www-form-urlencoded')
166
+ end
167
+
168
+ it "submits a body" do
169
+ expect(easy.response_body).to match('"body":"a=1%26b%3D2"')
170
+ end
171
+
172
+ it "submits the data" do
173
+ expect(easy.response_body).to include('"rack.request.form_hash":{"a":"1&b=2"}')
174
+ end
175
+ end
176
+ end
177
+
178
+ context "when string" do
179
+ let(:form) { "{a: 1}" }
180
+
181
+ context "when requesting" do
182
+ before do
183
+ easy.headers = { 'Expect' => '' }
184
+ post.setup(easy)
185
+ easy.perform
186
+ end
187
+
188
+ it "returns ok" do
189
+ expect(easy.return_code).to eq(:ok)
190
+ end
191
+
192
+ it "sends string" do
193
+ expect(easy.response_body).to include('"body":"{a: 1}"')
194
+ end
195
+ end
196
+ end
197
+ end
198
+
199
+ context "when params and body" do
200
+ let(:form) { {:a => "1"} }
201
+ let(:params) { {:b => "2"} }
202
+
203
+ context "when requesting" do
204
+ before do
205
+ easy.headers = { 'Expect' => '' }
206
+ post.setup(easy)
207
+ easy.perform
208
+ end
209
+
210
+ it "url contains params" do
211
+ expect(easy.response_body).to include('"REQUEST_URI":"http://localhost:3001/?b=2"')
212
+ end
213
+
214
+ it "body contains form" do
215
+ expect(easy.response_body).to include('"body":"a=1"')
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end