ethon 0.9.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +41 -0
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +20 -1
  5. data/Gemfile +14 -4
  6. data/Guardfile +1 -0
  7. data/README.md +4 -1
  8. data/Rakefile +1 -0
  9. data/ethon.gemspec +2 -1
  10. data/lib/ethon.rb +2 -0
  11. data/lib/ethon/curl.rb +1 -0
  12. data/lib/ethon/curls/classes.rb +2 -1
  13. data/lib/ethon/curls/codes.rb +1 -1
  14. data/lib/ethon/curls/constants.rb +1 -0
  15. data/lib/ethon/curls/form_options.rb +1 -0
  16. data/lib/ethon/curls/functions.rb +4 -12
  17. data/lib/ethon/curls/infos.rb +4 -3
  18. data/lib/ethon/curls/messages.rb +1 -0
  19. data/lib/ethon/curls/options.rb +35 -23
  20. data/lib/ethon/curls/settings.rb +2 -0
  21. data/lib/ethon/easy.rb +3 -1
  22. data/lib/ethon/easy/callbacks.rb +25 -3
  23. data/lib/ethon/easy/debug_info.rb +1 -0
  24. data/lib/ethon/easy/features.rb +1 -0
  25. data/lib/ethon/easy/form.rb +7 -4
  26. data/lib/ethon/easy/header.rb +1 -0
  27. data/lib/ethon/easy/http.rb +1 -0
  28. data/lib/ethon/easy/http/actionable.rb +2 -1
  29. data/lib/ethon/easy/http/custom.rb +1 -0
  30. data/lib/ethon/easy/http/delete.rb +1 -0
  31. data/lib/ethon/easy/http/get.rb +1 -0
  32. data/lib/ethon/easy/http/head.rb +1 -0
  33. data/lib/ethon/easy/http/options.rb +1 -0
  34. data/lib/ethon/easy/http/patch.rb +1 -0
  35. data/lib/ethon/easy/http/post.rb +1 -0
  36. data/lib/ethon/easy/http/postable.rb +1 -0
  37. data/lib/ethon/easy/http/put.rb +1 -0
  38. data/lib/ethon/easy/http/putable.rb +1 -0
  39. data/lib/ethon/easy/informations.rb +1 -0
  40. data/lib/ethon/easy/mirror.rb +1 -0
  41. data/lib/ethon/easy/operations.rb +16 -1
  42. data/lib/ethon/easy/options.rb +11 -2
  43. data/lib/ethon/easy/params.rb +1 -0
  44. data/lib/ethon/easy/queryable.rb +4 -1
  45. data/lib/ethon/easy/response_callbacks.rb +27 -0
  46. data/lib/ethon/easy/util.rb +1 -0
  47. data/lib/ethon/errors.rb +1 -0
  48. data/lib/ethon/errors/ethon_error.rb +1 -0
  49. data/lib/ethon/errors/global_init.rb +1 -0
  50. data/lib/ethon/errors/invalid_option.rb +1 -0
  51. data/lib/ethon/errors/invalid_value.rb +1 -0
  52. data/lib/ethon/errors/multi_add.rb +1 -0
  53. data/lib/ethon/errors/multi_fdset.rb +1 -0
  54. data/lib/ethon/errors/multi_remove.rb +1 -0
  55. data/lib/ethon/errors/multi_timeout.rb +1 -0
  56. data/lib/ethon/errors/select.rb +1 -0
  57. data/lib/ethon/libc.rb +16 -1
  58. data/lib/ethon/loggable.rb +1 -0
  59. data/lib/ethon/multi.rb +1 -0
  60. data/lib/ethon/multi/operations.rb +1 -0
  61. data/lib/ethon/multi/options.rb +2 -1
  62. data/lib/ethon/multi/stack.rb +1 -0
  63. data/lib/ethon/version.rb +2 -1
  64. data/profile/benchmarks.rb +1 -0
  65. data/profile/memory_leaks.rb +1 -0
  66. data/profile/perf_spec_helper.rb +1 -0
  67. data/profile/support/memory_test_helpers.rb +1 -0
  68. data/profile/support/os_memory_leak_tracker.rb +1 -0
  69. data/profile/support/ruby_object_leak_tracker.rb +1 -0
  70. data/spec/ethon/curl_spec.rb +1 -0
  71. data/spec/ethon/easy/callbacks_spec.rb +8 -1
  72. data/spec/ethon/easy/debug_info_spec.rb +2 -0
  73. data/spec/ethon/easy/features_spec.rb +1 -0
  74. data/spec/ethon/easy/form_spec.rb +28 -0
  75. data/spec/ethon/easy/header_spec.rb +1 -0
  76. data/spec/ethon/easy/http/custom_spec.rb +1 -0
  77. data/spec/ethon/easy/http/delete_spec.rb +1 -0
  78. data/spec/ethon/easy/http/get_spec.rb +1 -0
  79. data/spec/ethon/easy/http/head_spec.rb +1 -0
  80. data/spec/ethon/easy/http/options_spec.rb +1 -0
  81. data/spec/ethon/easy/http/patch_spec.rb +1 -0
  82. data/spec/ethon/easy/http/post_spec.rb +1 -0
  83. data/spec/ethon/easy/http/put_spec.rb +1 -0
  84. data/spec/ethon/easy/http_spec.rb +1 -0
  85. data/spec/ethon/easy/informations_spec.rb +1 -0
  86. data/spec/ethon/easy/mirror_spec.rb +1 -0
  87. data/spec/ethon/easy/operations_spec.rb +1 -0
  88. data/spec/ethon/easy/options_spec.rb +31 -1
  89. data/spec/ethon/easy/queryable_spec.rb +14 -3
  90. data/spec/ethon/easy/response_callbacks_spec.rb +58 -1
  91. data/spec/ethon/easy/util_spec.rb +1 -0
  92. data/spec/ethon/easy_spec.rb +8 -2
  93. data/spec/ethon/libc_spec.rb +4 -3
  94. data/spec/ethon/loggable_spec.rb +1 -0
  95. data/spec/ethon/multi/operations_spec.rb +1 -0
  96. data/spec/ethon/multi/options_spec.rb +1 -0
  97. data/spec/ethon/multi/stack_spec.rb +1 -0
  98. data/spec/ethon/multi_spec.rb +1 -0
  99. data/spec/spec_helper.rb +1 -0
  100. data/spec/support/localhost_server.rb +2 -1
  101. data/spec/support/server.rb +1 -0
  102. metadata +6 -7
  103. data/.travis.yml +0 -27
data/lib/ethon/libc.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
 
3
4
  # FFI Wrapper module for Libc.
@@ -13,7 +14,21 @@ module Ethon
13
14
  end
14
15
 
15
16
  unless windows?
16
- attach_function :getdtablesize, [], :int
17
+ fcg = FFI::ConstGenerator.new do |gen|
18
+ gen.include 'unistd.h'
19
+ %w[
20
+ _SC_OPEN_MAX
21
+ ].each do |const|
22
+ ruby_name = const.sub(/^_SC_/, '').downcase.to_sym
23
+ gen.const(const, "%d", nil, ruby_name, &:to_i)
24
+ end
25
+ end
26
+
27
+ CONF = enum(*fcg.constants.map{|_, const|
28
+ [const.ruby_name, const.converted_value]
29
+ }.flatten)
30
+
31
+ attach_function :sysconf, [CONF], :long
17
32
  attach_function :free, [:pointer], :void
18
33
  end
19
34
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
  module Ethon
3
4
 
4
5
  # Contains logging behaviour.
data/lib/ethon/multi.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'ethon/easy/util'
2
3
  require 'ethon/multi/stack'
3
4
  require 'ethon/multi/operations'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  class Multi # :nodoc
3
4
  # This module contains logic to run a multi.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  class Multi
3
4
 
@@ -38,7 +39,7 @@ module Ethon
38
39
  #
39
40
  # @return [ void ]
40
41
  def pipelining=(value)
41
- Curl.set_option(:pipelining, value_for(value, :bool), handle, :multi)
42
+ Curl.set_option(:pipelining, value_for(value, :int), handle, :multi)
42
43
  end
43
44
 
44
45
  # Sets socketdata option.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  class Multi
3
4
 
data/lib/ethon/version.rb CHANGED
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
 
3
4
  # Ethon version.
4
- VERSION = '0.9.1'
5
+ VERSION = '0.13.0'
5
6
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
  require 'ethon'
3
4
  require 'open-uri'
4
5
  require 'patron'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'ethon'
2
3
  require 'ethon/easy'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  #### SETUP
2
3
  require 'bundler'
3
4
  Bundler.setup
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require_relative 'ruby_object_leak_tracker'
2
3
  require_relative 'os_memory_leak_tracker'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class OSMemoryLeakTracker
2
3
  attr_reader :current_run
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class RubyObjectLeakTracker
2
3
  attr_reader :previous_count_hash, :current_count_hash
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Curl do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Callbacks do
@@ -8,7 +9,7 @@ describe Ethon::Easy::Callbacks do
8
9
  expect(Ethon::Curl).to receive(:set_option).exactly(3).times
9
10
  end
10
11
 
11
- it "sets write- and headerfunction" do
12
+ it "sets write-, debug-, and headerfunction" do
12
13
  easy.set_callbacks
13
14
  end
14
15
 
@@ -28,6 +29,12 @@ describe Ethon::Easy::Callbacks do
28
29
  end
29
30
  end
30
31
 
32
+ describe "#progress_callback" do
33
+ it "returns 0" do
34
+ expect(easy.progress_callback.call(0,1,1,1,1)).to be(0)
35
+ end
36
+ end
37
+
31
38
  describe "#body_write_callback" do
32
39
  let(:body_write_callback) { easy.instance_variable_get(:@body_write_callback) }
33
40
  let(:stream) { double(:read_string => "") }
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::DebugInfo do
@@ -23,6 +24,7 @@ describe Ethon::Easy::DebugInfo do
23
24
  end
24
25
 
25
26
  after do
27
+ easy.verbose = false
26
28
  easy.reset
27
29
  end
28
30
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Informations do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Form do
@@ -41,6 +42,15 @@ describe Ethon::Easy::Form do
41
42
  expect(form.multipart?).to be_truthy
42
43
  end
43
44
  end
45
+
46
+ context "when options contains multipart=true" do
47
+ before { form.instance_variable_set(:@multipart, true) }
48
+ let(:pairs) { [['a', '1'], ['b', '2']] }
49
+
50
+ it "returns true" do
51
+ expect(form.multipart?).to be_truthy
52
+ end
53
+ end
44
54
  end
45
55
 
46
56
  describe "#materialize" do
@@ -72,5 +82,23 @@ describe Ethon::Easy::Form do
72
82
  form.materialize
73
83
  end
74
84
  end
85
+
86
+ context "when query_pairs contains file and string values" do
87
+ let(:pairs) { [['a', ["file", "type", "path/file"]], ['b', '1']] }
88
+
89
+ it "adds file to form" do
90
+ expect(Ethon::Curl).to receive(:formadd).twice
91
+ form.materialize
92
+ end
93
+ end
94
+
95
+ context "when query_pairs contains file, string and int values" do
96
+ let(:pairs) { [['a', ["file", "type", "path/file"]], ['b', '1'], ['c', 1]] }
97
+
98
+ it "adds file to form" do
99
+ expect(Ethon::Curl).to receive(:formadd).exactly(3).times
100
+ form.materialize
101
+ end
102
+ end
75
103
  end
76
104
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Header do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Http::Custom do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Http::Delete do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Http::Get do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Http::Head do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Http::Options do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Http::Patch do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Http::Post do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Http::Put do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Http do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Informations do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Mirror do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Operations do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::Options do
@@ -12,7 +13,7 @@ describe Ethon::Easy::Options do
12
13
  :proxyuserpwd, :readdata, :readfunction, :redir_protocols, :ssl_verifyhost,
13
14
  :ssl_verifypeer, :sslcert, :sslcerttype, :sslkey, :sslkeytype, :sslversion,
14
15
  :timeout, :timeout_ms, :unrestricted_auth, :upload, :url, :useragent,
15
- :userpwd, :verbose
16
+ :userpwd, :verbose, :pipewait, :dns_shuffle_addresses, :path_as_is
16
17
  ].each do |name|
17
18
  describe "#{name}=" do
18
19
  it "responds_to" do
@@ -74,6 +75,35 @@ describe Ethon::Easy::Options do
74
75
  end
75
76
  end
76
77
 
78
+ describe '#multipart?' do
79
+ context 'by default' do
80
+ it 'returns false' do
81
+ expect(easy.multipart?).to be_falsey
82
+ end
83
+ end
84
+
85
+ context 'when #multipart=nil' do
86
+ it 'returns false' do
87
+ easy.multipart = nil
88
+ expect(easy.multipart?).to be_falsey
89
+ end
90
+ end
91
+
92
+ context 'when #multipart=true' do
93
+ it 'returns true' do
94
+ easy.multipart = true
95
+ expect(easy.multipart?).to be_truthy
96
+ end
97
+ end
98
+
99
+ context 'when #multipart=false' do
100
+ it 'returns false' do
101
+ easy.multipart = false
102
+ expect(easy.multipart?).to be_falsey
103
+ end
104
+ end
105
+ end
106
+
77
107
  describe "#httppost=" do
78
108
  it "raises unless given a FFI::Pointer" do
79
109
  expect{ easy.httppost = 1 }.to raise_error(Ethon::Errors::InvalidValue)
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
  require 'spec_helper'
3
4
 
4
5
  describe Ethon::Easy::Queryable do
@@ -122,6 +123,14 @@ describe Ethon::Easy::Queryable do
122
123
  expect(pairs).to include(["b[]", 3])
123
124
  end
124
125
  end
126
+
127
+ context "when params_encoding is :none" do
128
+ before { params.params_encoding = :none }
129
+ it "does no transformation" do
130
+ expect(pairs).to include([:a, 1])
131
+ expect(pairs).to include([:b, [2, 3]])
132
+ end
133
+ end
125
134
  end
126
135
 
127
136
  context "when params contains something nested in an array" do
@@ -152,9 +161,11 @@ describe Ethon::Easy::Queryable do
152
161
  end
153
162
 
154
163
  context "when MIME" do
155
- context "when mime type" do
156
- it "sets mime type to text" do
157
- expect(mime_type).to eq("application/x-ruby")
164
+ if defined?(MIME)
165
+ context "when mime type" do
166
+ it "sets mime type to text" do
167
+ expect(mime_type).to eq("application/x-ruby")
168
+ end
158
169
  end
159
170
  end
160
171
 
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Ethon::Easy::ResponseCallbacks do
4
5
  let(:easy) { Ethon::Easy.new }
5
6
 
6
- [:on_complete, :on_headers, :on_body].each do |callback_type|
7
+ [:on_complete, :on_headers, :on_body, :on_progress].each do |callback_type|
7
8
  describe "##{callback_type}" do
8
9
  it "responds" do
9
10
  expect(easy).to respond_to("#{callback_type}")
@@ -68,6 +69,62 @@ describe Ethon::Easy::ResponseCallbacks do
68
69
  end
69
70
  end
70
71
 
72
+ describe "#progress" do
73
+ context "when requesting for realz" do
74
+ it "executes callback" do
75
+ post = Ethon::Easy::Http::Post.new("http://localhost:3001", {:body => "bar=fu"})
76
+ post.setup(easy)
77
+ @called = false
78
+ @has_dltotal = false
79
+ @has_ultotal = false
80
+ easy.on_progress { @called = true }
81
+ easy.on_progress { |dltotal, _, _, _| @has_dltotal ||= true }
82
+ easy.on_progress { |_, _, ultotal, _| @has_ultotal ||= true }
83
+ easy.perform
84
+ expect(@called).to be true
85
+ expect(@has_dltotal).to be true
86
+ expect(@has_ultotal).to be true
87
+ end
88
+ end
89
+
90
+ context "when pretending" do
91
+ before do
92
+ @dltotal = nil
93
+ @dlnow = nil
94
+ @ultotal = nil
95
+ @ulnow = nil
96
+ easy.on_progress { |dltotal, dlnow, ultotal, ulnow| @dltotal = dltotal ; @dlnow = dlnow; @ultotal = ultotal; @ulnow = ulnow }
97
+ end
98
+
99
+ it "executes blocks and passes dltotal" do
100
+ easy.progress(1, 2, 3, 4)
101
+ expect(@dltotal).to eq(1)
102
+ end
103
+
104
+ it "executes blocks and passes dlnow" do
105
+ easy.progress(1, 2, 3, 4)
106
+ expect(@dlnow).to eq(2)
107
+ end
108
+
109
+ it "executes blocks and passes ultotal" do
110
+ easy.progress(1, 2, 3, 4)
111
+ expect(@ultotal).to eq(3)
112
+ end
113
+
114
+ it "executes blocks and passes ulnow" do
115
+ easy.progress(1, 2, 3, 4)
116
+ expect(@ulnow).to eq(4)
117
+ end
118
+
119
+ context "when @on_progress nil" do
120
+ it "doesn't raise" do
121
+ easy.instance_variable_set(:@on_progress, nil)
122
+ expect{ easy.progress(1, 2, 3, 4) }.to_not raise_error
123
+ end
124
+ end
125
+ end
126
+ end
127
+
71
128
  describe "#body" do
72
129
  before do
73
130
  @chunk = nil