ethon 0.8.0 → 0.8.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2f2d076d0f8210b0e2ac4f9a798b6f7091bc72e1
4
- data.tar.gz: e4e029697e2da2f8f0ff32eeae74dbe52b37342c
3
+ metadata.gz: 7a8e3e2daabb0f28d13cfec209027f4a3dfb588f
4
+ data.tar.gz: b5dc230d462c0972fa15bb811906e70ca4b6d8a7
5
5
  SHA512:
6
- metadata.gz: 44c3c55ce791f04ab8c0722b91473a0f16b897da96312b3f660e20929dfcaef3d961dedcb21b08cee0a08b152f597883cf6f02de23d912379237a3cf7b14e1dc
7
- data.tar.gz: 87306062771ee5c5fe442bb041b1b03aa55ae200fff87e65fe00ecf390b6e41212dc961973b71560d74c769ab5fb3c639a42182b41d6576822cde797c219e68b
6
+ metadata.gz: ba31326c9c9dd60a8635a32edde9b4936307e602097b2ca696333410aea60746fbda37b7c2d179ac2be01a46ccee66debfdd014deb073f87ffeb1fdeae00540b
7
+ data.tar.gz: 9f2b01584a1f175f9032febbd0fbc1b80a56dcda094a2825746e6e7ccca8254f07fc3ae7bf5c5249e7b75f52914a9229201dfb1a0e26fb17af457a6cfae5efe9
@@ -1,4 +1,5 @@
1
1
  script: "bundle exec rake"
2
+ sudo: false
2
3
  bundler_args: --without perf
3
4
  rvm:
4
5
  - 1.8.7
@@ -2,7 +2,16 @@
2
2
 
3
3
  ## Master
4
4
 
5
- [Full Changelog](https://github.com/typhoeus/ethon/compare/v0.7.4...master)
5
+ [Full Changelog](https://github.com/typhoeus/ethon/compare/v0.8.1...master)
6
+
7
+ ## 0.8.1
8
+
9
+ * Support optional escaping of params.
10
+ ([Tasos Laskos](https://github.com/zapotek)
11
+ * `Easy::Mirror`: Reduced object allocations and method calls during info handling.
12
+ ([Tasos Laskos](https://github.com/zapotek)
13
+
14
+ ## 0.8.0
6
15
 
7
16
  ## 0.7.4
8
17
 
@@ -2,8 +2,12 @@ require 'logger'
2
2
  require 'ffi'
3
3
  require 'thread'
4
4
  begin
5
- require 'mime/types'
5
+ require 'mime/types/columnar'
6
6
  rescue LoadError
7
+ begin
8
+ require 'mime/types'
9
+ rescue LoadError
10
+ end
7
11
  end
8
12
  require 'tempfile'
9
13
 
@@ -248,6 +248,7 @@ module Ethon
248
248
  # easy.reset
249
249
  def reset
250
250
  @url = nil
251
+ @escape = nil
251
252
  @hash = nil
252
253
  @on_complete = nil
253
254
  @on_headers = nil
@@ -93,13 +93,18 @@ module Ethon
93
93
  def setup(easy)
94
94
  @easy = easy
95
95
 
96
+ # Order is important, @easy will be used to provide access to options
97
+ # relevant to the following operations (like whether or not to escape
98
+ # values).
99
+ easy.set_attributes(options)
100
+
101
+ set_form(easy) unless form.empty?
102
+
96
103
  if params.empty?
97
104
  easy.url = url
98
105
  else
99
106
  set_params(easy)
100
107
  end
101
- set_form(easy) unless form.empty?
102
- easy.set_attributes(options)
103
108
  end
104
109
 
105
110
  # Setup request with params.
@@ -109,12 +114,16 @@ module Ethon
109
114
  #
110
115
  # @param [ Easy ] easy The easy to setup.
111
116
  def set_params(easy)
112
- params.escape = true
117
+ params.escape = easy.escape?
113
118
  params.params_encoding = params_encoding
114
119
 
115
- base_url, base_params = url.split("?")
116
- base_params += "&" if base_params
117
- easy.url = "#{base_url}?#{base_params}#{params.to_s}"
120
+ base_url, base_params = url.split('?')
121
+ base_url << '?'
122
+ base_url << base_params.to_s
123
+ base_url << '&' if base_params
124
+ base_url << params.to_s
125
+
126
+ easy.url = base_url
118
127
  end
119
128
 
120
129
  # Setup request with form.
@@ -20,7 +20,7 @@ module Ethon
20
20
  form.materialize
21
21
  easy.httppost = form.first.read_pointer
22
22
  else
23
- form.escape = true
23
+ form.escape = easy.escape?
24
24
  easy.postfieldsize = form.to_s.bytesize
25
25
  easy.copypostfields = form.to_s
26
26
  end
@@ -4,18 +4,14 @@ module Ethon
4
4
  attr_reader :options
5
5
  alias_method :to_hash, :options
6
6
 
7
- def self.informations_to_mirror
8
- Informations::AVAILABLE_INFORMATIONS.keys +
7
+ INFORMATIONS_TO_MIRROR = Informations::AVAILABLE_INFORMATIONS.keys +
9
8
  [:return_code, :response_headers, :response_body, :debug_info]
10
- end
11
9
 
12
- def self.informations_to_log
13
- [:effective_url, :response_code, :return_code, :total_time]
14
- end
10
+ INFORMATIONS_TO_LOG = [:effective_url, :response_code, :return_code, :total_time]
15
11
 
16
12
  def self.from_easy(easy)
17
13
  options = {}
18
- informations_to_mirror.each do |info|
14
+ INFORMATIONS_TO_MIRROR.each do |info|
19
15
  options[info] = easy.send(info)
20
16
  end
21
17
  new(options)
@@ -26,12 +22,12 @@ module Ethon
26
22
  end
27
23
 
28
24
  def log_informations
29
- Hash[*self.class.informations_to_log.map do |info|
25
+ Hash[*INFORMATIONS_TO_LOG.map do |info|
30
26
  [info, options[info]]
31
27
  end.flatten]
32
28
  end
33
29
 
34
- informations_to_mirror.each do |info|
30
+ INFORMATIONS_TO_MIRROR.each do |info|
35
31
  eval %Q|def #{info}; options[#{info}]; end|
36
32
  end
37
33
  end
@@ -10,7 +10,16 @@ module Ethon
10
10
  @url = value
11
11
  Curl.set_option(:url, value, handle)
12
12
  end
13
-
13
+
14
+ def escape=( b )
15
+ @escape = b
16
+ end
17
+
18
+ def escape?
19
+ return true if @escape
20
+ @escape.nil? ? true : false
21
+ end
22
+
14
23
  Curl.easy_options.each do |opt,props|
15
24
  eval %Q<
16
25
  def #{opt}=(value)
@@ -100,6 +100,8 @@ module Ethon
100
100
  when Array
101
101
  if params_encoding == :rack
102
102
  encode_rack_array_pairs(h, prefix, pairs)
103
+ elsif params_encoding == :multi
104
+ encode_multi_array_pairs(h, prefix, pairs)
103
105
  else
104
106
  encode_indexed_array_pairs(h, prefix, pairs)
105
107
  end
@@ -126,6 +128,13 @@ module Ethon
126
128
  pairs_for(v, key, pairs)
127
129
  end
128
130
  end
131
+
132
+ def encode_multi_array_pairs(h, prefix, pairs)
133
+ h.each_with_index do |v, i|
134
+ key = prefix
135
+ pairs_for(v, key, pairs)
136
+ end
137
+ end
129
138
 
130
139
  def pairs_for(v, key, pairs)
131
140
  case v
@@ -1,5 +1,5 @@
1
1
  module Ethon
2
2
 
3
3
  # Ethon version.
4
- VERSION = '0.8.0'
4
+ VERSION = '0.8.1'
5
5
  end
@@ -5,7 +5,8 @@ describe Ethon::Easy::Http::Get do
5
5
  let(:url) { "http://localhost:3001/" }
6
6
  let(:params) { nil }
7
7
  let(:form) { nil }
8
- let(:get) { described_class.new(url, {:params => params, :body => form}) }
8
+ let(:options) { {} }
9
+ let(:get) { described_class.new(url, {:params => params, :body => form}.merge(options)) }
9
10
 
10
11
  describe "#setup" do
11
12
  it "sets url" do
@@ -84,6 +85,41 @@ describe Ethon::Easy::Http::Get do
84
85
  expect(easy.effective_url).to eq("http://localhost:3001/?a=1%26b%3D2")
85
86
  end
86
87
  end
88
+
89
+ context "with :escape" do
90
+ let(:params) { {:a => "1&b=2"} }
91
+
92
+ context 'missing' do
93
+ it "escapes values" do
94
+ expect(easy.url).to eq("#{url}?a=1%26b%3D2")
95
+ end
96
+ end
97
+
98
+ context 'nil' do
99
+ let(:options) { {:escape => nil} }
100
+
101
+ it "escapes values" do
102
+ expect(easy.url).to eq("#{url}?a=1%26b%3D2")
103
+ end
104
+ end
105
+
106
+ context 'true' do
107
+ let(:options) { {:escape => true} }
108
+
109
+ it "escapes values" do
110
+ expect(easy.url).to eq("#{url}?a=1%26b%3D2")
111
+ end
112
+ end
113
+
114
+ context 'false' do
115
+ let(:options) { {:escape => false} }
116
+
117
+ it "sends raw values" do
118
+ expect(easy.url).to eq("#{url}?a=1&b=2")
119
+ end
120
+ end
121
+ end
122
+
87
123
  end
88
124
  end
89
125
  end
@@ -59,6 +59,42 @@ describe Ethon::Easy::Http::Post do
59
59
  end
60
60
  end
61
61
 
62
+ context "with :escape" do
63
+ context 'missing' do
64
+ it "escapes values" do
65
+ post.setup(easy)
66
+ expect(easy.url).to eq("#{url}?a=1%26")
67
+ end
68
+ end
69
+
70
+ context 'nil' do
71
+ let(:options) { {:escape => nil} }
72
+
73
+ it "escapes values" do
74
+ post.setup(easy)
75
+ expect(easy.url).to eq("#{url}?a=1%26")
76
+ end
77
+ end
78
+
79
+ context 'true' do
80
+ let(:options) { {:escape => true} }
81
+
82
+ it "escapes values" do
83
+ post.setup(easy)
84
+ expect(easy.url).to eq("#{url}?a=1%26")
85
+ end
86
+ end
87
+
88
+ context 'false' do
89
+ let(:options) { {:escape => false} }
90
+
91
+ it "sends raw values" do
92
+ post.setup(easy)
93
+ expect(easy.url).to eq("#{url}?a=1&")
94
+ end
95
+ end
96
+ end
97
+
62
98
  it "sets postfieldsize" do
63
99
  expect(easy).to receive(:postfieldsize=).with(0)
64
100
  post.setup(easy)
@@ -4,7 +4,7 @@ describe Ethon::Easy::Mirror do
4
4
  let(:options) { nil }
5
5
  let(:mirror) { described_class.new(options) }
6
6
 
7
- describe ".informations_to_mirror" do
7
+ describe "::INFORMATIONS_TO_LOG" do
8
8
  [
9
9
  :return_code, :response_code, :response_body, :response_headers,
10
10
  :total_time, :starttransfer_time, :appconnect_time,
@@ -12,7 +12,7 @@ describe Ethon::Easy::Mirror do
12
12
  :effective_url, :primary_ip, :redirect_count, :debug_info
13
13
  ].each do |name|
14
14
  it "contains #{name}" do
15
- expect(described_class.informations_to_mirror).to include(name)
15
+ expect(described_class::INFORMATIONS_TO_MIRROR).to include(name)
16
16
  end
17
17
  end
18
18
  end
@@ -33,7 +33,7 @@ describe Ethon::Easy::Mirror do
33
33
  end
34
34
 
35
35
  it "only calls methods that exist" do
36
- described_class.informations_to_log.each do |method_name|
36
+ described_class::INFORMATIONS_TO_LOG.each do |method_name|
37
37
  expect(mirror.respond_to? method_name).to eql(true)
38
38
  end
39
39
  end
@@ -45,6 +45,35 @@ describe Ethon::Easy::Options do
45
45
  end
46
46
  end
47
47
 
48
+ describe '#escape?' do
49
+ context 'by default' do
50
+ it 'returns true' do
51
+ expect(easy.escape?).to be_truthy
52
+ end
53
+ end
54
+
55
+ context 'when #escape=nil' do
56
+ it 'returns true' do
57
+ easy.escape = nil
58
+ expect(easy.escape?).to be_truthy
59
+ end
60
+ end
61
+
62
+ context 'when #escape=true' do
63
+ it 'returns true' do
64
+ easy.escape = true
65
+ expect(easy.escape?).to be_truthy
66
+ end
67
+ end
68
+
69
+ context 'when #escape=false' do
70
+ it 'returns true' do
71
+ easy.escape = false
72
+ expect(easy.escape?).to be_falsey
73
+ end
74
+ end
75
+ end
76
+
48
77
  describe "#httppost=" do
49
78
  it "raises unless given a FFI::Pointer" do
50
79
  expect{ easy.httppost = 1 }.to raise_error(Ethon::Errors::InvalidValue)
@@ -162,13 +162,14 @@ describe Ethon::Easy::Queryable do
162
162
  let(:file) { Tempfile.new("fubar") }
163
163
 
164
164
  it "sets mime type to default application/octet-stream" do
165
- Object.send(:remove_const, :MIME)
166
165
  expect(mime_type).to eq("application/octet-stream")
167
166
  end
168
167
  end
169
168
  end
170
169
 
171
170
  context "when no MIME" do
171
+ before { hide_const("MIME") }
172
+
172
173
  it "sets mime type to default application/octet-stream" do
173
174
  expect(mime_type).to eq("application/octet-stream")
174
175
  end
@@ -64,6 +64,12 @@ describe Ethon::Easy do
64
64
  expect(easy.url).to be_nil
65
65
  end
66
66
 
67
+ it "resets escape?" do
68
+ easy.escape = false
69
+ easy.reset
70
+ expect(easy.escape?).to be_truthy
71
+ end
72
+
67
73
  it "resets hash" do
68
74
  easy.reset
69
75
  expect(easy.instance_variable_get(:@hash)).to be_nil
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ethon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hans Hasselberg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-17 00:00:00.000000000 Z
11
+ date: 2016-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi