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,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ethon::Multi do
4
+ describe ".new" do
5
+ it "inits curl" do
6
+ Ethon::Curl.should_receive(:init)
7
+ Ethon::Multi.new
8
+ end
9
+
10
+ context "when options not empty" do
11
+ context "when pipelining is set" do
12
+ let(:options) { { :pipelining => true } }
13
+
14
+ it "sets pipelining" do
15
+ Ethon::Multi.any_instance.should_receive(:pipelining=).with(true)
16
+ Ethon::Multi.new(options)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
3
+
4
+ require 'bundler'
5
+ Bundler.setup
6
+ require "ethon"
7
+ require 'rspec'
8
+
9
+ if defined? require_relative
10
+ require_relative 'support/localhost_server'
11
+ require_relative 'support/server'
12
+ else
13
+ require 'support/localhost_server'
14
+ require 'support/server'
15
+ end
16
+
17
+ # Ethon.logger = Logger.new($stdout).tap do |log|
18
+ # log.level = Logger::DEBUG
19
+ # end
20
+
21
+ RSpec.configure do |config|
22
+ # config.order = :rand
23
+
24
+ config.before(:suite) do
25
+ LocalhostServer.new(TESTSERVER.new, 3001)
26
+ end
27
+ end
@@ -0,0 +1,94 @@
1
+ require 'rack'
2
+ require 'rack/handler/webrick'
3
+ require 'net/http'
4
+
5
+ # The code for this is inspired by Capybara's server:
6
+ # http://github.com/jnicklas/capybara/blob/0.3.9/lib/capybara/server.rb
7
+ class LocalhostServer
8
+ READY_MESSAGE = "Server ready"
9
+
10
+ class Identify
11
+ def initialize(app)
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ if env["PATH_INFO"] == "/__identify__"
17
+ [200, {}, [LocalhostServer::READY_MESSAGE]]
18
+ else
19
+ @app.call(env)
20
+ end
21
+ end
22
+ end
23
+
24
+ attr_reader :port
25
+
26
+ def initialize(rack_app, port = nil)
27
+ @port = port || find_available_port
28
+ @rack_app = rack_app
29
+ concurrently { boot }
30
+ wait_until(10, "Boot failed.") { booted? }
31
+ end
32
+
33
+ private
34
+
35
+ def find_available_port
36
+ server = TCPServer.new('127.0.0.1', 0)
37
+ server.addr[1]
38
+ ensure
39
+ server.close if server
40
+ end
41
+
42
+ def boot
43
+ # Use WEBrick since it's part of the ruby standard library and is available on all ruby interpreters.
44
+ options = { :Port => port }
45
+ options.merge!(:AccessLog => [], :Logger => WEBrick::BasicLog.new(StringIO.new)) unless ENV['VERBOSE_SERVER']
46
+ Rack::Handler::WEBrick.run(Identify.new(@rack_app), options)
47
+ end
48
+
49
+ def booted?
50
+ res = ::Net::HTTP.get_response("localhost", '/__identify__', port)
51
+ if res.is_a?(::Net::HTTPSuccess) or res.is_a?(::Net::HTTPRedirection)
52
+ return res.body == READY_MESSAGE
53
+ end
54
+ rescue Errno::ECONNREFUSED, Errno::EBADF
55
+ return false
56
+ end
57
+
58
+ def concurrently
59
+ if should_use_subprocess?
60
+ pid = Process.fork do
61
+ trap(:INT) { ::Rack::Handler::WEBrick.shutdown }
62
+ yield
63
+ exit # manually exit; otherwise this sub-process will re-run the specs that haven't run yet.
64
+ end
65
+
66
+ at_exit do
67
+ Process.kill('INT', pid)
68
+ begin
69
+ Process.wait(pid)
70
+ rescue Errno::ECHILD
71
+ # ignore this error...I think it means the child process has already exited.
72
+ end
73
+ end
74
+ else
75
+ Thread.new { yield }
76
+ end
77
+ end
78
+
79
+ def should_use_subprocess?
80
+ # !ENV['THREADED']
81
+ false
82
+ end
83
+
84
+ def wait_until(timeout, error_message, &block)
85
+ start_time = Time.now
86
+
87
+ while true
88
+ return if yield
89
+ raise TimeoutError.new(error_message) if (Time.now - start_time) > timeout
90
+ sleep(0.05)
91
+ end
92
+ end
93
+ end
94
+
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env ruby
2
+ require 'json'
3
+ require 'zlib'
4
+ require 'sinatra/base'
5
+
6
+ TESTSERVER = Sinatra.new do
7
+ set :logging, false
8
+
9
+ fail_count = 0
10
+
11
+ post '/file' do
12
+ {
13
+ 'content-type' => params[:file][:type],
14
+ 'filename' => params[:file][:filename],
15
+ 'content' => params[:file][:tempfile].read,
16
+ 'request-content-type' => request.env['CONTENT_TYPE']
17
+ }.to_json
18
+ end
19
+
20
+ get '/multiple-headers' do
21
+ [200, { 'Set-Cookie' => %w[ foo bar ], 'Content-Type' => 'text/plain' }, ['']]
22
+ end
23
+
24
+ get '/fail/:number' do
25
+ if fail_count >= params[:number].to_i
26
+ "ok"
27
+ else
28
+ fail_count += 1
29
+ error 500, "oh noes!"
30
+ end
31
+ end
32
+
33
+ get '/fail_forever' do
34
+ error 500, "oh noes!"
35
+ end
36
+
37
+ get '/redirect' do
38
+ redirect '/'
39
+ end
40
+
41
+ post '/redirect' do
42
+ redirect '/'
43
+ end
44
+
45
+ get '/bad_redirect' do
46
+ redirect '/bad_redirect'
47
+ end
48
+
49
+ get '/auth_basic/:username/:password' do
50
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
51
+ # Check that we've got a basic auth, and that it's credentials match the ones
52
+ # provided in the request
53
+ if @auth.provided? && @auth.basic? && @auth.credentials == [ params[:username], params[:password] ]
54
+ # auth is valid - confirm it
55
+ true
56
+ else
57
+ # invalid auth - request the authentication
58
+ response['WWW-Authenticate'] = %(Basic realm="Testing HTTP Auth")
59
+ throw(:halt, [401, "Not authorized\n"])
60
+ end
61
+ end
62
+
63
+ get '/auth_ntlm' do
64
+ # we're just checking for the existence if NTLM auth header here. It's validation
65
+ # is too troublesome and really doesn't bother is much, it's up to libcurl to make
66
+ # it valid
67
+ response['WWW-Authenticate'] = 'NTLM'
68
+ is_ntlm_auth = /^NTLM/ =~ request.env['HTTP_AUTHORIZATION']
69
+ true if is_ntlm_auth
70
+ throw(:halt, [401, "Not authorized\n"]) if !is_ntlm_auth
71
+ end
72
+
73
+ get '/gzipped' do
74
+ req_env = request.env.to_json
75
+ z = Zlib::Deflate.new
76
+ gzipped_env = z.deflate(req_env, Zlib::FINISH)
77
+ z.close
78
+ response['Content-Encoding'] = 'gzip'
79
+ gzipped_env
80
+ end
81
+
82
+ get '/**' do
83
+ sleep params["delay"].to_i if params.has_key?("delay")
84
+ request.env.merge!(:body => request.body.read).to_json
85
+ end
86
+
87
+ head '/**' do
88
+ sleep params["delay"].to_i if params.has_key?("delay")
89
+ end
90
+
91
+ put '/**' do
92
+ request.env.merge!(:body => request.body.read).to_json
93
+ end
94
+
95
+ post '/**' do
96
+ request.env.merge!(:body => request.body.read).to_json
97
+ end
98
+
99
+ delete '/**' do
100
+ request.env.merge!(:body => request.body.read).to_json
101
+ end
102
+
103
+ patch '/**' do
104
+ request.env.merge!(:body => request.body.read).to_json
105
+ end
106
+
107
+ options '/**' do
108
+ request.env.merge!(:body => request.body.read).to_json
109
+ end
110
+
111
+ route 'PURGE', '/**' do
112
+ request.env.merge!(:body => request.body.read).to_json
113
+ end
114
+ end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ethon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.12
5
- prerelease:
4
+ version: 0.6.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Hans Hasselberg
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-04-21 00:00:00.000000000 Z
11
+ date: 2013-08-11 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: ffi
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: mime-types
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
@@ -50,25 +45,33 @@ executables: []
50
45
  extensions: []
51
46
  extra_rdoc_files: []
52
47
  files:
48
+ - .gitignore
49
+ - .rspec
50
+ - .travis.yml
51
+ - CHANGELOG.md
52
+ - Gemfile
53
+ - Guardfile
54
+ - LICENSE
55
+ - README.md
56
+ - Rakefile
57
+ - ethon.gemspec
58
+ - lib/ethon.rb
53
59
  - lib/ethon/curl.rb
54
- - lib/ethon/curls/auth_types.rb
55
60
  - lib/ethon/curls/classes.rb
56
61
  - lib/ethon/curls/codes.rb
57
62
  - lib/ethon/curls/constants.rb
58
63
  - lib/ethon/curls/form_options.rb
59
64
  - lib/ethon/curls/functions.rb
60
- - lib/ethon/curls/http_versions.rb
61
65
  - lib/ethon/curls/infos.rb
62
66
  - lib/ethon/curls/messages.rb
63
67
  - lib/ethon/curls/options.rb
64
- - lib/ethon/curls/postredir.rb
65
- - lib/ethon/curls/protocols.rb
66
- - lib/ethon/curls/proxy_types.rb
67
68
  - lib/ethon/curls/settings.rb
68
- - lib/ethon/curls/ssl_versions.rb
69
+ - lib/ethon/easy.rb
69
70
  - lib/ethon/easy/callbacks.rb
71
+ - lib/ethon/easy/debug_info.rb
70
72
  - lib/ethon/easy/form.rb
71
73
  - lib/ethon/easy/header.rb
74
+ - lib/ethon/easy/http.rb
72
75
  - lib/ethon/easy/http/actionable.rb
73
76
  - lib/ethon/easy/http/custom.rb
74
77
  - lib/ethon/easy/http/delete.rb
@@ -80,15 +83,15 @@ files:
80
83
  - lib/ethon/easy/http/postable.rb
81
84
  - lib/ethon/easy/http/put.rb
82
85
  - lib/ethon/easy/http/putable.rb
83
- - lib/ethon/easy/http.rb
84
86
  - lib/ethon/easy/informations.rb
87
+ - lib/ethon/easy/mirror.rb
85
88
  - lib/ethon/easy/operations.rb
86
89
  - lib/ethon/easy/options.rb
87
90
  - lib/ethon/easy/params.rb
88
91
  - lib/ethon/easy/queryable.rb
89
92
  - lib/ethon/easy/response_callbacks.rb
90
93
  - lib/ethon/easy/util.rb
91
- - lib/ethon/easy.rb
94
+ - lib/ethon/errors.rb
92
95
  - lib/ethon/errors/ethon_error.rb
93
96
  - lib/ethon/errors/global_init.rb
94
97
  - lib/ethon/errors/invalid_option.rb
@@ -98,45 +101,102 @@ files:
98
101
  - lib/ethon/errors/multi_remove.rb
99
102
  - lib/ethon/errors/multi_timeout.rb
100
103
  - lib/ethon/errors/select.rb
101
- - lib/ethon/errors.rb
102
104
  - lib/ethon/libc.rb
103
105
  - lib/ethon/loggable.rb
106
+ - lib/ethon/multi.rb
104
107
  - lib/ethon/multi/operations.rb
105
108
  - lib/ethon/multi/options.rb
106
109
  - lib/ethon/multi/stack.rb
107
- - lib/ethon/multi.rb
108
110
  - lib/ethon/version.rb
109
- - lib/ethon.rb
110
- - CHANGELOG.md
111
- - Gemfile
112
- - LICENSE
113
- - README.md
114
- - Rakefile
111
+ - profile/benchmarks.rb
112
+ - profile/memory_leaks.rb
113
+ - profile/perf_spec_helper.rb
114
+ - profile/support/memory_test_helpers.rb
115
+ - profile/support/os_memory_leak_tracker.rb
116
+ - profile/support/ruby_object_leak_tracker.rb
117
+ - spec/ethon/curl_spec.rb
118
+ - spec/ethon/easy/callbacks_spec.rb
119
+ - spec/ethon/easy/debug_info_spec.rb
120
+ - spec/ethon/easy/form_spec.rb
121
+ - spec/ethon/easy/header_spec.rb
122
+ - spec/ethon/easy/http/custom_spec.rb
123
+ - spec/ethon/easy/http/delete_spec.rb
124
+ - spec/ethon/easy/http/get_spec.rb
125
+ - spec/ethon/easy/http/head_spec.rb
126
+ - spec/ethon/easy/http/options_spec.rb
127
+ - spec/ethon/easy/http/patch_spec.rb
128
+ - spec/ethon/easy/http/post_spec.rb
129
+ - spec/ethon/easy/http/put_spec.rb
130
+ - spec/ethon/easy/http_spec.rb
131
+ - spec/ethon/easy/informations_spec.rb
132
+ - spec/ethon/easy/mirror_spec.rb
133
+ - spec/ethon/easy/operations_spec.rb
134
+ - spec/ethon/easy/options_spec.rb
135
+ - spec/ethon/easy/queryable_spec.rb
136
+ - spec/ethon/easy/response_callbacks_spec.rb
137
+ - spec/ethon/easy/util_spec.rb
138
+ - spec/ethon/easy_spec.rb
139
+ - spec/ethon/libc_spec.rb
140
+ - spec/ethon/loggable_spec.rb
141
+ - spec/ethon/multi/operations_spec.rb
142
+ - spec/ethon/multi/options_spec.rb
143
+ - spec/ethon/multi/stack_spec.rb
144
+ - spec/ethon/multi_spec.rb
145
+ - spec/spec_helper.rb
146
+ - spec/support/localhost_server.rb
147
+ - spec/support/server.rb
115
148
  homepage: https://github.com/typhoeus/ethon
116
149
  licenses: []
150
+ metadata: {}
117
151
  post_install_message:
118
152
  rdoc_options: []
119
153
  require_paths:
120
154
  - lib
121
155
  required_ruby_version: !ruby/object:Gem::Requirement
122
- none: false
123
156
  requirements:
124
157
  - - ! '>='
125
158
  - !ruby/object:Gem::Version
126
159
  version: '0'
127
- segments:
128
- - 0
129
- hash: 2640646266244561120
130
160
  required_rubygems_version: !ruby/object:Gem::Requirement
131
- none: false
132
161
  requirements:
133
162
  - - ! '>='
134
163
  - !ruby/object:Gem::Version
135
164
  version: 1.3.6
136
165
  requirements: []
137
166
  rubyforge_project: ! '[none]'
138
- rubygems_version: 1.8.23
167
+ rubygems_version: 2.0.3
139
168
  signing_key:
140
- specification_version: 3
169
+ specification_version: 4
141
170
  summary: Libcurl wrapper.
142
- test_files: []
171
+ test_files:
172
+ - spec/ethon/curl_spec.rb
173
+ - spec/ethon/easy/callbacks_spec.rb
174
+ - spec/ethon/easy/debug_info_spec.rb
175
+ - spec/ethon/easy/form_spec.rb
176
+ - spec/ethon/easy/header_spec.rb
177
+ - spec/ethon/easy/http/custom_spec.rb
178
+ - spec/ethon/easy/http/delete_spec.rb
179
+ - spec/ethon/easy/http/get_spec.rb
180
+ - spec/ethon/easy/http/head_spec.rb
181
+ - spec/ethon/easy/http/options_spec.rb
182
+ - spec/ethon/easy/http/patch_spec.rb
183
+ - spec/ethon/easy/http/post_spec.rb
184
+ - spec/ethon/easy/http/put_spec.rb
185
+ - spec/ethon/easy/http_spec.rb
186
+ - spec/ethon/easy/informations_spec.rb
187
+ - spec/ethon/easy/mirror_spec.rb
188
+ - spec/ethon/easy/operations_spec.rb
189
+ - spec/ethon/easy/options_spec.rb
190
+ - spec/ethon/easy/queryable_spec.rb
191
+ - spec/ethon/easy/response_callbacks_spec.rb
192
+ - spec/ethon/easy/util_spec.rb
193
+ - spec/ethon/easy_spec.rb
194
+ - spec/ethon/libc_spec.rb
195
+ - spec/ethon/loggable_spec.rb
196
+ - spec/ethon/multi/operations_spec.rb
197
+ - spec/ethon/multi/options_spec.rb
198
+ - spec/ethon/multi/stack_spec.rb
199
+ - spec/ethon/multi_spec.rb
200
+ - spec/spec_helper.rb
201
+ - spec/support/localhost_server.rb
202
+ - spec/support/server.rb