ethon 0.11.0 → 0.16.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 +19 -1
  5. data/Gemfile +5 -0
  6. data/Guardfile +1 -0
  7. data/README.md +24 -1
  8. data/Rakefile +1 -0
  9. data/ethon.gemspec +2 -1
  10. data/lib/ethon/curl.rb +1 -0
  11. data/lib/ethon/curls/classes.rb +13 -2
  12. data/lib/ethon/curls/codes.rb +1 -1
  13. data/lib/ethon/curls/constants.rb +18 -0
  14. data/lib/ethon/curls/form_options.rb +1 -0
  15. data/lib/ethon/curls/functions.rb +5 -13
  16. data/lib/ethon/curls/infos.rb +4 -3
  17. data/lib/ethon/curls/messages.rb +1 -0
  18. data/lib/ethon/curls/options.rb +65 -27
  19. data/lib/ethon/curls/settings.rb +3 -0
  20. data/lib/ethon/easy/callbacks.rb +6 -4
  21. data/lib/ethon/easy/debug_info.rb +1 -0
  22. data/lib/ethon/easy/features.rb +1 -0
  23. data/lib/ethon/easy/form.rb +1 -0
  24. data/lib/ethon/easy/header.rb +1 -0
  25. data/lib/ethon/easy/http/actionable.rb +1 -0
  26. data/lib/ethon/easy/http/custom.rb +1 -0
  27. data/lib/ethon/easy/http/delete.rb +1 -0
  28. data/lib/ethon/easy/http/get.rb +1 -0
  29. data/lib/ethon/easy/http/head.rb +1 -0
  30. data/lib/ethon/easy/http/options.rb +1 -0
  31. data/lib/ethon/easy/http/patch.rb +1 -0
  32. data/lib/ethon/easy/http/post.rb +1 -0
  33. data/lib/ethon/easy/http/postable.rb +1 -0
  34. data/lib/ethon/easy/http/put.rb +1 -0
  35. data/lib/ethon/easy/http/putable.rb +1 -0
  36. data/lib/ethon/easy/http.rb +1 -0
  37. data/lib/ethon/easy/informations.rb +23 -1
  38. data/lib/ethon/easy/mirror.rb +1 -0
  39. data/lib/ethon/easy/operations.rb +1 -0
  40. data/lib/ethon/easy/options.rb +1 -0
  41. data/lib/ethon/easy/params.rb +1 -0
  42. data/lib/ethon/easy/queryable.rb +4 -1
  43. data/lib/ethon/easy/response_callbacks.rb +7 -1
  44. data/lib/ethon/easy/util.rb +1 -0
  45. data/lib/ethon/easy.rb +1 -1
  46. data/lib/ethon/errors/ethon_error.rb +1 -0
  47. data/lib/ethon/errors/global_init.rb +1 -0
  48. data/lib/ethon/errors/invalid_option.rb +1 -0
  49. data/lib/ethon/errors/invalid_value.rb +1 -0
  50. data/lib/ethon/errors/multi_add.rb +1 -0
  51. data/lib/ethon/errors/multi_fdset.rb +1 -0
  52. data/lib/ethon/errors/multi_remove.rb +1 -0
  53. data/lib/ethon/errors/multi_timeout.rb +1 -0
  54. data/lib/ethon/errors/select.rb +1 -0
  55. data/lib/ethon/errors.rb +1 -0
  56. data/lib/ethon/libc.rb +1 -0
  57. data/lib/ethon/loggable.rb +1 -0
  58. data/lib/ethon/multi/operations.rb +46 -8
  59. data/lib/ethon/multi/options.rb +9 -8
  60. data/lib/ethon/multi/stack.rb +1 -0
  61. data/lib/ethon/multi.rb +23 -0
  62. data/lib/ethon/version.rb +2 -1
  63. data/lib/ethon.rb +1 -0
  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 +23 -0
  72. data/spec/ethon/easy/debug_info_spec.rb +1 -0
  73. data/spec/ethon/easy/features_spec.rb +1 -0
  74. data/spec/ethon/easy/form_spec.rb +1 -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 +29 -0
  86. data/spec/ethon/easy/mirror_spec.rb +3 -1
  87. data/spec/ethon/easy/operations_spec.rb +4 -0
  88. data/spec/ethon/easy/options_spec.rb +2 -1
  89. data/spec/ethon/easy/queryable_spec.rb +9 -0
  90. data/spec/ethon/easy/response_callbacks_spec.rb +1 -0
  91. data/spec/ethon/easy/util_spec.rb +1 -0
  92. data/spec/ethon/easy_spec.rb +3 -2
  93. data/spec/ethon/libc_spec.rb +1 -0
  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 +114 -0
  97. data/spec/ethon/multi/stack_spec.rb +1 -0
  98. data/spec/ethon/multi_spec.rb +131 -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 +9 -10
  103. data/.travis.yml +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ac54c9df1c6dfd22a65124a64c7bb93b2792dc55
4
- data.tar.gz: 5fedd427db76181d6bde8c7c4af4116bdf1cc272
2
+ SHA256:
3
+ metadata.gz: 30f75feeae963db1b4648a0b88e028361c78fda7aec43524a35f93b287ab2305
4
+ data.tar.gz: eb0ccd002c324dedaaceaa001172a61c520cd58e34d1a92440182faada17df74
5
5
  SHA512:
6
- metadata.gz: 538f6d8f6af52a294d72ecc3f63f8a2a7ed97f90154382979edfbdc6085f38e16ea4e336f1cdff3d107551402ba2408b87f8632added41b2915744b97da47c3c
7
- data.tar.gz: 54695f47f42ea0838c8da9531d136b52d6d77a8e5cd10374929c878b6ff55f572727d1e8afa3b854672ba6bbbcb5eff1d0d25091bc6d5f1ad6df0d757eeecb6e
6
+ metadata.gz: b6ec09378cd37ec552caee9a9153fb9e0582a770b18da882ec27f59028799885e1a9d9d7c496f1cfb4803ba3eb14bdd5e508f930cdc9523d16747d2a87ba1dfb
7
+ data.tar.gz: 77a50827108e8c6bc44f293bae5c2bfe6e871c94f40f93904ff611245143ef7900cf4cc2aa8a1511d0797dd80c03578e06b4e256f929deab544c73f9ef0d9e33
@@ -0,0 +1,41 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+ runs-on: ${{ matrix.os }}-latest
19
+ strategy:
20
+ fail-fast: false
21
+ matrix:
22
+ os: [ubuntu, macos]
23
+ ruby-version: [2.5, 2.6, 2.7, 3.0, head, debug, truffleruby]
24
+ continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
25
+ steps:
26
+ - uses: actions/checkout@v2
27
+ - name: Install libcurl header
28
+ run: |
29
+ if ${{ matrix.os == 'macos' }}
30
+ then
31
+ brew install curl
32
+ else
33
+ sudo apt update && sudo apt install -y --no-install-recommends libcurl4-openssl-dev
34
+ fi
35
+ - name: Set up Ruby
36
+ uses: ruby/setup-ruby@v1
37
+ with:
38
+ ruby-version: ${{ matrix.ruby-version }}
39
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
40
+ - name: Run tests
41
+ run: bundle exec rake
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ Gemfile.lock
5
5
  .yardoc
6
6
  doc
7
7
  coverage
8
+ .idea
data/CHANGELOG.md CHANGED
@@ -2,7 +2,25 @@
2
2
 
3
3
  ## Master
4
4
 
5
- [Full Changelog](https://github.com/typhoeus/ethon/compare/v0.10.1...master)
5
+ [Full Changelog](https://github.com/typhoeus/ethon/compare/v0.15.0...master)
6
+
7
+ * Added `redirect_url` value to available informations and `Easy::Mirror`.
8
+ ([Adrien Rey-Jarthon](https://github.com/jarthod)
9
+
10
+ ## 0.15.0
11
+
12
+ [Full Changelog](https://github.com/typhoeus/ethon/compare/v0.14.0...v0.15.0)
13
+
14
+ ## 0.12.0
15
+
16
+ [Full Changelog](https://github.com/typhoeus/ethon/compare/v0.11.0...v0.12.0)
17
+
18
+ - Removed deprecated `CURLE_SSL_CACERT` pinned in curl v7.62.0 ([@arku](https://github.com/arku) in [#158](https://github.com/typhoeus/ethon/pull/158))
19
+
20
+
21
+ ## 0.11.0
22
+
23
+ [Full Changelog](https://github.com/typhoeus/ethon/compare/v0.10.1...v0.11.0)
6
24
 
7
25
  ## 0.10.1
8
26
 
data/Gemfile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  source "https://rubygems.org"
2
3
  gemspec
3
4
 
@@ -29,6 +30,10 @@ group :development, :test do
29
30
  elsif Gem.ruby_version >= Gem::Version.new("2.0.0")
30
31
  gem "mustermann", "0.3.1"
31
32
  end
33
+
34
+ if Gem.ruby_version >= Gem::Version.new("3.0.0")
35
+ gem "webrick"
36
+ end
32
37
  end
33
38
 
34
39
  group :perf do
data/Guardfile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # vim:set filetype=ruby:
2
3
  guard(
3
4
  "rspec",
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/ethon.svg)](https://badge.fury.io/rb/ethon)
2
- [![Build Status](https://travis-ci.org/typhoeus/ethon.svg?branch=master)](https://travis-ci.org/typhoeus/ethon)
2
+ [![Build Status](https://github.com/typhoeus/ethon/workflows/Ruby/badge.svg)](https://github.com/typhoeus/ethon/actions/workflows/ruby.yml)
3
3
 
4
4
  # Ethon
5
5
 
@@ -70,6 +70,29 @@ easy.perform
70
70
  This is really handy when making requests since you don't have to care about setting
71
71
  everything up correctly.
72
72
 
73
+ ## Http2
74
+ Standard http2 servers require the client to connect once and create a session (multi) and then add simple requests to the multi handler.
75
+ The `perform` method then takes all the requests in the multi handler and sends them to the server.
76
+
77
+ See the following example
78
+ ```ruby
79
+ multi = Ethon::Multi.new
80
+ easy = Ethon::Easy.new
81
+
82
+ easy.http_request("www.example.com/get", :get, { http_version: :httpv2_0 })
83
+
84
+ # Sending a request with http version 2 will send an Upgrade header to the server, which many older servers will not support
85
+ # See below for more info: https://everything.curl.dev/http/http2
86
+ # If this is a problem, send the below:
87
+ easy.http_request("www.example.com/get", :get, { http_version: :httpv2_prior_knowledge })
88
+
89
+ # To set the server to use http2 with https and http1 with http, send the following:
90
+ easy.http_request("www.example.com/get", :get, { http_version: :httpv2_tls }
91
+
92
+ multi.add(easy)
93
+ multi.perform
94
+ ```
95
+
73
96
  ## LICENSE
74
97
 
75
98
  (The MIT License)
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "bundler"
2
3
  Bundler.setup
3
4
 
data/ethon.gemspec CHANGED
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
  lib = File.expand_path('../lib/', __FILE__)
3
4
  $:.unshift lib unless $:.include?(lib)
4
5
 
@@ -17,7 +18,7 @@ Gem::Specification.new do |s|
17
18
  s.required_rubygems_version = ">= 1.3.6"
18
19
  s.license = 'MIT'
19
20
 
20
- s.add_dependency('ffi', ['>= 1.3.0'])
21
+ s.add_dependency('ffi', ['>= 1.15.0'])
21
22
 
22
23
  s.files = `git ls-files`.split("\n")
23
24
  s.test_files = `git ls-files -- spec/*`.split("\n")
data/lib/ethon/curl.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'ethon/curls/codes'
2
3
  require 'ethon/curls/options'
3
4
  require 'ethon/curls/infos'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  module Curl
3
4
  # :nodoc:
@@ -31,8 +32,18 @@ module Ethon
31
32
 
32
33
  def clear; self[:fd_count] = 0; end
33
34
  else
34
- # FD Set size.
35
- FD_SETSIZE = ::Ethon::Libc.getdtablesize
35
+ # https://github.com/typhoeus/ethon/issues/182
36
+ FD_SETSIZE = begin
37
+ # Allow to override the (new) default cap
38
+ if ENV['ETHON_FD_SIZE']
39
+ ENV['ETHON_FD_SIZE']
40
+
41
+ # auto-detect ulimit, but cap at 2^16
42
+ else
43
+ [::Ethon::Libc.getdtablesize, 65_536].min
44
+ end
45
+ end
46
+
36
47
  layout :fds_bits, [:long, FD_SETSIZE / ::FFI::Type::LONG.size]
37
48
 
38
49
  # :nodoc:
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  module Curls # :nodoc:
3
4
 
@@ -69,7 +70,6 @@ module Ethon
69
70
  :obsolete57,
70
71
  :ssl_certproblem,
71
72
  :ssl_cipher,
72
- :ssl_cacert,
73
73
  :bad_content_encoding,
74
74
  :ldap_invalid_url,
75
75
  :filesize_exceeded,
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  module Curl
3
4
  # :nodoc:
@@ -58,5 +59,22 @@ module Ethon
58
59
  VERSION_NTLM_WB = (1<<15) # NTLM delegating to winbind helper
59
60
  VERSION_HTTP2 = (1<<16) # HTTP2 support built
60
61
  VERSION_GSSAPI = (1<<17) # GSS-API is supported
62
+
63
+ SOCKET_BAD = -1
64
+ SOCKET_TIMEOUT = SOCKET_BAD
65
+
66
+ PollAction = enum(:poll_action, [
67
+ :none,
68
+ :in,
69
+ :out,
70
+ :inout,
71
+ :remove
72
+ ])
73
+
74
+ SocketReadiness = bitmask(:socket_readiness, [
75
+ :in, # CURL_CSELECT_IN - 0x01 (bit 0)
76
+ :out, # CURL_CSELECT_OUT - 0x02 (bit 1)
77
+ :err, # CURL_CSELECT_ERR - 0x04 (bit 2)
78
+ ])
61
79
  end
62
80
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  module Curls
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  module Curls
3
4
 
@@ -13,14 +14,8 @@ module Ethon
13
14
 
14
15
  base.attach_function :easy_init, :curl_easy_init, [], :pointer
15
16
  base.attach_function :easy_cleanup, :curl_easy_cleanup, [:pointer], :void
16
- base.attach_function :easy_getinfo, :curl_easy_getinfo, [:pointer, :info, :pointer], :easy_code
17
- base.attach_function :easy_setopt_ffipointer, :curl_easy_setopt, [:pointer, :easy_option, :pointer], :easy_code
18
- base.attach_function :easy_setopt_string, :curl_easy_setopt, [:pointer, :easy_option, :string], :easy_code
19
- base.attach_function :easy_setopt_long, :curl_easy_setopt, [:pointer, :easy_option, :long], :easy_code
20
- base.attach_function :easy_setopt_callback, :curl_easy_setopt, [:pointer, :easy_option, :callback], :easy_code
21
- base.attach_function :easy_setopt_debug_callback, :curl_easy_setopt, [:pointer, :easy_option, :debug_callback], :easy_code
22
- base.attach_function :easy_setopt_progress_callback, :curl_easy_setopt, [:pointer, :easy_option, :progress_callback], :easy_code
23
- base.attach_function :easy_setopt_off_t, :curl_easy_setopt, [:pointer, :easy_option, :int64], :easy_code
17
+ base.attach_function :easy_getinfo, :curl_easy_getinfo, [:pointer, :info, :varargs], :easy_code
18
+ base.attach_function :easy_setopt, :curl_easy_setopt, [:pointer, :easy_option, :varargs], :easy_code
24
19
  base.instance_variable_set(:@blocking, true)
25
20
  base.attach_function :easy_perform, :curl_easy_perform, [:pointer], :easy_code
26
21
  base.attach_function :easy_strerror, :curl_easy_strerror, [:easy_code], :string
@@ -40,11 +35,8 @@ module Ethon
40
35
  base.attach_function :multi_timeout, :curl_multi_timeout, [:pointer, :pointer], :multi_code
41
36
  base.attach_function :multi_fdset, :curl_multi_fdset, [:pointer, Curl::FDSet.ptr, Curl::FDSet.ptr, Curl::FDSet.ptr, :pointer], :multi_code
42
37
  base.attach_function :multi_strerror, :curl_multi_strerror, [:int], :string
43
- base.attach_function :multi_setopt_ffipointer, :curl_multi_setopt, [:pointer, :multi_option, :pointer], :multi_code
44
- base.attach_function :multi_setopt_string, :curl_multi_setopt, [:pointer, :multi_option, :string], :multi_code
45
- base.attach_function :multi_setopt_long, :curl_multi_setopt, [:pointer, :multi_option, :long], :multi_code
46
- base.attach_function :multi_setopt_callback, :curl_multi_setopt, [:pointer, :multi_option, :callback], :multi_code
47
- base.attach_function :multi_setopt_off_t, :curl_multi_setopt, [:pointer, :multi_option, :int64], :multi_code
38
+ base.attach_function :multi_setopt, :curl_multi_setopt, [:pointer, :multi_option, :varargs], :multi_code
39
+ base.attach_function :multi_socket_action, :curl_multi_socket_action, [:pointer, :int, :socket_readiness, :pointer], :multi_code
48
40
 
49
41
  base.attach_function :version, :curl_version, [], :string
50
42
  base.attach_function :version_info, :curl_version_info, [], Curl::VersionInfoData.ptr
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  module Curls
3
4
 
@@ -106,7 +107,7 @@ module Ethon
106
107
  def get_info_string(option, handle)
107
108
  string_ptr = ::FFI::MemoryPointer.new(:pointer)
108
109
 
109
- if easy_getinfo(handle, option, string_ptr) == :ok
110
+ if easy_getinfo(handle, option, :pointer, string_ptr) == :ok
110
111
  ptr=string_ptr.read_pointer
111
112
  ptr.null? ? nil : ptr.read_string
112
113
  end
@@ -124,7 +125,7 @@ module Ethon
124
125
  def get_info_long(option, handle)
125
126
  long_ptr = ::FFI::MemoryPointer.new(:long)
126
127
 
127
- if easy_getinfo(handle, option, long_ptr) == :ok
128
+ if easy_getinfo(handle, option, :pointer, long_ptr) == :ok
128
129
  long_ptr.read_long
129
130
  end
130
131
  end
@@ -141,7 +142,7 @@ module Ethon
141
142
  def get_info_double(option, handle)
142
143
  double_ptr = ::FFI::MemoryPointer.new(:double)
143
144
 
144
- if easy_getinfo(handle, option, double_ptr) == :ok
145
+ if easy_getinfo(handle, option, :pointer, double_ptr) == :ok
145
146
  double_ptr.read_double
146
147
  end
147
148
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  module Curls
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  module Curls
3
4
 
@@ -7,8 +8,7 @@ module Ethon
7
8
 
8
9
  OPTION_STRINGS = { :easy => 'easy_options', :multi => 'multi_options' }.freeze
9
10
  FOPTION_STRINGS = { :easy => 'EASY_OPTIONS', :multi => 'MULTI_OPTIONS' }.freeze
10
- FTYPES = [:long, :string, :ffipointer, :callback, :debug_callback, :progress_callback, :off_t]
11
- FUNCS = Hash[*[:easy, :multi].zip([:easy, :multi].map { |t| Hash[*FTYPES.zip(FTYPES.map { |ft| "#{t}_setopt_#{ft}" }).flatten] }).flatten]
11
+ FUNCS = { :easy => 'easy_setopt', :multi => 'multi_setopt' }.freeze
12
12
  # Sets appropriate option for easy, depending on value type.
13
13
  def set_option(option, value, handle, type = :easy)
14
14
  type = type.to_sym unless type.is_a?(Symbol)
@@ -20,22 +20,22 @@ module Ethon
20
20
  when :none
21
21
  return if value.nil?
22
22
  value=1
23
- func=:long
23
+ va_type=:long
24
24
  when :int
25
25
  return if value.nil?
26
- func=:long
26
+ va_type=:long
27
27
  value=value.to_i
28
28
  when :bool
29
29
  return if value.nil?
30
- func=:long
30
+ va_type=:long
31
31
  value=(value&&value!=0) ? 1 : 0
32
32
  when :time
33
33
  return if value.nil?
34
- func=:long
34
+ va_type=:long
35
35
  value=value.to_i
36
36
  when :enum
37
37
  return if value.nil?
38
- func=:long
38
+ va_type=:long
39
39
  value = case value
40
40
  when Symbol
41
41
  opthash[option][:opts][value]
@@ -46,7 +46,7 @@ module Ethon
46
46
  end.to_i
47
47
  when :bitmask
48
48
  return if value.nil?
49
- func=:long
49
+ va_type=:long
50
50
  value = case value
51
51
  when Symbol
52
52
  opthash[option][:opts][value]
@@ -56,22 +56,22 @@ module Ethon
56
56
  value
57
57
  end.to_i
58
58
  when :string
59
- func=:string
59
+ va_type=:string
60
60
  value=value.to_s unless value.nil?
61
61
  when :string_as_pointer
62
- func = :ffipointer
62
+ va_type = :pointer
63
63
  s = ''
64
64
  s = value.to_s unless value.nil?
65
65
  value = FFI::MemoryPointer.new(:char, s.bytesize)
66
66
  value.put_bytes(0, s)
67
67
  when :string_escape_null
68
- func=:string
68
+ va_type=:string
69
69
  value=Util.escape_zero_byte(value) unless value.nil?
70
70
  when :ffipointer
71
- func=:ffipointer
71
+ va_type=:pointer
72
72
  raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? FFI::Pointer
73
73
  when :curl_slist
74
- func=:ffipointer
74
+ va_type=:pointer
75
75
  raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? FFI::Pointer
76
76
  when :buffer
77
77
  raise NotImplementedError, "Ethon::Curls::Options option #{option} buffer type not implemented."
@@ -80,27 +80,32 @@ module Ethon
80
80
  when :cbdata
81
81
  raise NotImplementedError, "Ethon::Curls::Options option #{option} callback data type not implemented. Use Ruby closures."
82
82
  when :callback
83
- func=:callback
83
+ va_type=:callback
84
+ raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc
85
+ when :socket_callback
86
+ va_type=:socket_callback
87
+ raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc
88
+ when :timer_callback
89
+ va_type=:timer_callback
84
90
  raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc
85
91
  when :debug_callback
86
- func=:debug_callback
92
+ va_type=:debug_callback
87
93
  raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc
88
94
  when :progress_callback
89
- func=:progress_callback
95
+ va_type=:progress_callback
90
96
  raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc
91
97
  when :off_t
92
98
  return if value.nil?
93
- func=:off_t
99
+ va_type=:int64
94
100
  value=value.to_i
95
101
  end
96
102
 
97
- if func==:long or func==:off_t then
98
- bits=FFI.type_size(:long)*8 if func==:long
99
- bits=FFI.type_size(:int64)*8 if func==:off_t
103
+ if va_type==:long or va_type==:int64 then
104
+ bits=FFI.type_size(va_type)*8
100
105
  tv=((value<0) ? value.abs-1 : value)
101
106
  raise Errors::InvalidValue.new(option,value) unless tv<(1<<bits)
102
107
  end
103
- send(FUNCS[type][func], handle, opthash[option][:opt], value)
108
+ send(FUNCS[type], handle, opthash[option][:opt], va_type, value)
104
109
  end
105
110
 
106
111
  OPTION_TYPE_BASE = {
@@ -138,6 +143,8 @@ module Ethon
138
143
  :dontuse_object => :objectpoint, # An object we don't support (e.g. FILE*)
139
144
  :cbdata => :objectpoint,
140
145
  :callback => :functionpoint,
146
+ :socket_callback => :functionpoint,
147
+ :timer_callback => :functionpoint,
141
148
  :debug_callback => :functionpoint,
142
149
  :progress_callback => :functionpoint,
143
150
  :off_t => :off_t,
@@ -209,10 +216,10 @@ module Ethon
209
216
  # Documentation @ http://curl.haxx.se/libcurl/c/curl_multi_setopt.html
210
217
  option_type :multi
211
218
 
212
- option :multi, :socketfunction, :callback, 1
219
+ option :multi, :socketfunction, :socket_callback, 1
213
220
  option :multi, :socketdata, :cbdata, 2
214
- option :multi, :pipelining, :bool, 3
215
- option :multi, :timerfunction, :callback, 4
221
+ option :multi, :pipelining, :int, 3
222
+ option :multi, :timerfunction, :timer_callback, 4
216
223
  option :multi, :timerdata, :cbdata, 5
217
224
  option :multi, :maxconnects, :int, 6
218
225
  option :multi, :max_host_connections, :int, 7
@@ -251,6 +258,7 @@ module Ethon
251
258
  option :easy, :opensocketdata, :cbdata, 164
252
259
  option :easy, :closesocketfunction, :callback, 208
253
260
  option :easy, :closesocketdata, :cbdata, 209
261
+ option :easy, :path_as_is, :bool, 234
254
262
  option :easy, :progressfunction, :progress_callback, 56
255
263
  option :easy, :progressdata, :cbdata, 57
256
264
  option :easy, :headerfunction, :callback, 79
@@ -282,7 +290,7 @@ module Ethon
282
290
  option :easy, :redir_protocols, :bitmask, 182, [nil, :http, :https, :ftp, :ftps, :scp, :sftp, :telnet, :ldap, :ldaps, :dict, :file, :tftp, :imap, :imaps, :pop3, :pop3s, :smtp, :smtps, :rtsp, :rtmp, :rtmpt, :rtmpe, :rtmpte, :rtmps, :rtmpts, :gopher]
283
291
  option :easy, :proxy, :string, 4
284
292
  option :easy, :proxyport, :int, 59
285
- option :easy, :proxytype, :enum, 101, [:http, :http_1_0, nil, nil, :socks4, :socks5, :socks4a, :socks5_hostname]
293
+ option :easy, :proxytype, :enum, 101, [:http, :http_1_0, :https, nil, :socks4, :socks5, :socks4a, :socks5_hostname]
286
294
  option :easy, :noproxy, :string, 177
287
295
  option :easy, :httpproxytunnel, :bool, 61
288
296
  option :easy, :socks5_gssapi_service, :string, 179
@@ -292,10 +300,14 @@ module Ethon
292
300
  option :easy, :localportrange, :int, 140
293
301
  option :easy, :dns_cache_timeout, :int, 92
294
302
  option :easy, :dns_use_global_cache, :bool, 91 # Obsolete
303
+ option :easy, :dns_interface, :string, 221
304
+ option :easy, :dns_local_ip4, :string, 222
305
+ option :easy, :dns_shuffle_addresses, :bool, 275
295
306
  option :easy, :buffersize, :int, 98
296
307
  option :easy, :port, :int, 3
297
308
  option :easy, :tcp_nodelay, :bool, 121
298
309
  option :easy, :address_scope, :int, 171
310
+ option :easy, :tcp_fastopen, :bool, 212
299
311
  option :easy, :tcp_keepalive, :bool, 213
300
312
  option :easy, :tcp_keepidle, :int, 214
301
313
  option :easy, :tcp_keepintvl, :int, 215
@@ -341,7 +353,7 @@ module Ethon
341
353
  option :easy, :cookiesession, :bool, 96
342
354
  option :easy, :cookielist, :string, 135
343
355
  option :easy, :httpget, :bool, 80
344
- option :easy, :http_version, :enum, 84, [:none, :httpv1_0, :httpv1_1, :httpv2_0]
356
+ option :easy, :http_version, :enum, 84, [:none, :httpv1_0, :httpv1_1, :httpv2_0, :httpv2_tls, :httpv2_prior_knowledge]
345
357
  option :easy, :ignore_content_length, :bool, 136
346
358
  option :easy, :http_content_decoding, :bool, 158
347
359
  option :easy, :http_transfer_decoding, :bool, 157
@@ -417,6 +429,7 @@ module Ethon
417
429
  option :easy, :dns_servers, :string, 211
418
430
  option :easy, :accepttimeout_ms, :int, 212
419
431
  option :easy, :unix_socket_path, :string, 231
432
+ option :easy, :pipewait, :bool, 237
420
433
  option_alias :easy, :unix_socket_path, :unix_socket
421
434
  ## SSL and SECURITY OPTIONS
422
435
  option :easy, :sslcert, :string, 25
@@ -428,7 +441,7 @@ module Ethon
428
441
  option_alias :easy, :keypasswd, :sslkeypasswd
429
442
  option :easy, :sslengine, :string, 89
430
443
  option :easy, :sslengine_default, :none, 90
431
- option :easy, :sslversion, :enum, 32, [:default, :tlsv1, :sslv2, :sslv3, :tlsv1_0, :tlsv1_1, :tlsv1_2]
444
+ option :easy, :sslversion, :enum, 32, [:default, :tlsv1, :sslv2, :sslv3, :tlsv1_0, :tlsv1_1, :tlsv1_2, :tlsv1_3]
432
445
  option :easy, :ssl_verifypeer, :bool, 64
433
446
  option :easy, :cainfo, :string, 65
434
447
  option :easy, :issuercert, :string, 170
@@ -444,6 +457,31 @@ module Ethon
444
457
  option :easy, :krblevel, :string, 63
445
458
  option_alias :easy, :krblevel, :krb4level
446
459
  option :easy, :gssapi_delegation, :bitmask, 210, [:none, :policy_flag, :flag]
460
+ option :easy, :pinnedpublickey, :string, 230
461
+ option_alias :easy, :pinnedpublickey, :pinned_public_key
462
+ ## PROXY SSL OPTIONS
463
+ option :easy, :proxy_cainfo, :string, 246
464
+ option :easy, :proxy_capath, :string, 247
465
+ option :easy, :proxy_ssl_verifypeer, :bool, 248
466
+ option :easy, :proxy_ssl_verifyhost, :int, 249
467
+ option :easy, :proxy_sslversion, :enum, 250, [:default, :tlsv1, :sslv2, :sslv3, :tlsv1_0, :tlsv1_1, :tlsv1_2, :tlsv1_3]
468
+ option :easy, :proxy_tlsauth_username, :string, 251
469
+ option :easy, :proxy_tlsauth_password, :string, 252
470
+ option :easy, :proxy_tlsauth_type, :enum, 253, [:none, :srp]
471
+ option :easy, :proxy_sslcert, :string, 254
472
+ option :easy, :proxy_sslcerttype, :string, 255
473
+ option :easy, :proxy_sslkey, :string, 256
474
+ option :easy, :proxy_sslkeytype, :string, 257
475
+ option :easy, :proxy_keypasswd, :string, 258
476
+ option_alias :easy, :proxy_keypasswd, :proxy_sslcertpasswd
477
+ option_alias :easy, :proxy_keypasswd, :proxy_sslkeypasswd
478
+ option :easy, :proxy_ssl_cipher_list, :string, 259
479
+ option :easy, :proxy_crlfile, :string, 260
480
+ option :easy, :proxy_ssl_options, :bitmask, 261, [nil, :allow_beast]
481
+ option :easy, :pre_proxy, :string, 262
482
+ option :easy, :proxy_pinnedpublickey, :string, 263
483
+ option_alias :easy, :proxy_pinnedpublickey, :proxy_pinned_public_key
484
+ option :easy, :proxy_issuercert, :string, 296
447
485
  ## SSH OPTIONS
448
486
  option :easy, :ssh_auth_types, :bitmask, 151, [:none, :publickey, :password, :host, :keyboard, :agent, {:any => [:all], :default => [:any]}]
449
487
  option :easy, :ssh_host_public_key_md5, :string, 162
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  module Curl
3
4
  callback :callback, [:pointer, :size_t, :size_t, :pointer], :size_t
5
+ callback :socket_callback, [:pointer, :int, :poll_action, :pointer, :pointer], :multi_code
6
+ callback :timer_callback, [:pointer, :long, :pointer], :multi_code
4
7
  callback :debug_callback, [:pointer, :debug_info_type, :pointer, :size_t, :pointer], :int
5
8
  callback :progress_callback, [:pointer, :long_long, :long_long, :long_long, :long_long], :int
6
9
  ffi_lib_flags :now, :global
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  class Easy
3
4
 
@@ -22,8 +23,8 @@ module Ethon
22
23
  Curl.set_option(:writefunction, body_write_callback, handle)
23
24
  Curl.set_option(:headerfunction, header_write_callback, handle)
24
25
  Curl.set_option(:debugfunction, debug_callback, handle)
25
- @response_body = ""
26
- @response_headers = ""
26
+ @response_body = String.new
27
+ @response_headers = String.new
27
28
  @headers_called = false
28
29
  @debug_info = Ethon::Easy::DebugInfo.new
29
30
  end
@@ -51,8 +52,9 @@ module Ethon
51
52
  # @return [ Proc ] The callback.
52
53
  def header_write_callback
53
54
  @header_write_callback ||= proc {|stream, size, num, object|
55
+ result = headers
54
56
  @response_headers << stream.read_string(size * num)
55
- size * num
57
+ result != :abort ? size * num : -1
56
58
  }
57
59
  end
58
60
 
@@ -60,7 +62,7 @@ module Ethon
60
62
  # write the raw http request headers.
61
63
  #
62
64
  # @example Return the callback.
63
- # easy.body_write_callback
65
+ # easy.debug_callback
64
66
  #
65
67
  # @return [ Proc ] The callback.
66
68
  def debug_callback
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  class Easy
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  class Easy
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'ethon/easy/util'
2
3
  require 'ethon/easy/queryable'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  class Easy
3
4
  # This module contains the logic around adding headers to libcurl.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'ethon/easy/http/putable'
2
3
  require 'ethon/easy/http/postable'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  class Easy
3
4
  module Http
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  class Easy
3
4
  module Http
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  class Easy
3
4
  module Http
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ethon
2
3
  class Easy
3
4
  module Http