excon 0.112.0 → 1.0.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.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/lib/excon/connection.rb +6 -0
- data/lib/excon/constants.rb +8 -3
- data/lib/excon/middlewares/decompress.rb +17 -22
- data/lib/excon/ssl_socket.rb +1 -1
- data/lib/excon/utils.rb +25 -3
- data/lib/excon/version.rb +1 -1
- data/lib/excon.rb +8 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 955c2ed7f6ee55d4a279f386f6041f2d465640bd2c49930fcb213f0e63852e17
|
4
|
+
data.tar.gz: 49190e08fa385b6bd878096da5df9ad062c8e643477930e60916908581c1ef02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5fcebc27e76063b3be519a0eae585eabd4b3a40591fef96c1750cd7ddfcd9df940a760907f6f7717ab4628eb3f036640afe8da51312ec2741eb5eb8a13a612d
|
7
|
+
data.tar.gz: 10a234e21629066f1a6682c0c63a0f9bf60bd211ea13018ad5951c3012268e6826d88459d9bcee63518e2a3ccd1558dabb1fba03c9e7d450281d4ab7f8bc6c1a
|
data/README.md
CHANGED
@@ -190,6 +190,9 @@ connection.request(:timeout => 0.1) # timeout if the entire request takes longer
|
|
190
190
|
#
|
191
191
|
connection = Excon.new('http://geemus.com/', :tcp_nodelay => true)
|
192
192
|
|
193
|
+
# opt-in to having Excon add a default port (http:80 and https:443)
|
194
|
+
connection = Excon.new('http://geemus.com/', :include_default_port => true)
|
195
|
+
|
193
196
|
# set longer connect_timeout (default is 60 seconds)
|
194
197
|
connection = Excon.new('http://geemus.com/', :connect_timeout => 360)
|
195
198
|
|
data/lib/excon/connection.rb
CHANGED
@@ -446,6 +446,12 @@ module Excon
|
|
446
446
|
raise ArgumentError.new("Invalid validation type '#{validation}'")
|
447
447
|
end
|
448
448
|
|
449
|
+
if validation == :connection && params[:omit_default_port] != true
|
450
|
+
Excon.display_warning(
|
451
|
+
'The `omit_default_port` connection option is deprecated, please use `include_default_port` instead.'
|
452
|
+
)
|
453
|
+
end
|
454
|
+
|
449
455
|
invalid_keys = params.keys - valid_keys
|
450
456
|
unless invalid_keys.empty?
|
451
457
|
Excon.display_warning("Invalid Excon #{validation} keys: #{invalid_keys.map(&:inspect).join(', ')}")
|
data/lib/excon/constants.rb
CHANGED
@@ -14,9 +14,11 @@ module Excon
|
|
14
14
|
DEFAULT_RETRY_LIMIT = 4
|
15
15
|
|
16
16
|
DEFAULT_RETRY_ERRORS = [
|
17
|
-
Excon::Error::
|
17
|
+
Excon::Error::RequestTimeout,
|
18
|
+
Excon::Error::Server,
|
18
19
|
Excon::Error::Socket,
|
19
|
-
Excon::Error::
|
20
|
+
Excon::Error::Timeout,
|
21
|
+
Excon::Error::TooManyRequests
|
20
22
|
].freeze
|
21
23
|
|
22
24
|
FORCE_ENC = CR_NL.respond_to?(:force_encoding)
|
@@ -84,6 +86,7 @@ module Excon
|
|
84
86
|
keepalive
|
85
87
|
host
|
86
88
|
hostname
|
89
|
+
include_default_port
|
87
90
|
omit_default_port
|
88
91
|
nonblock
|
89
92
|
reuseaddr
|
@@ -151,14 +154,16 @@ module Excon
|
|
151
154
|
instrumentor_name: 'excon',
|
152
155
|
middlewares: [
|
153
156
|
Excon::Middleware::ResponseParser,
|
157
|
+
Excon::Middleware::Decompress,
|
154
158
|
Excon::Middleware::Expects,
|
155
159
|
Excon::Middleware::Idempotent,
|
156
160
|
Excon::Middleware::Instrumentor,
|
157
161
|
Excon::Middleware::Mock
|
158
162
|
],
|
159
163
|
mock: false,
|
164
|
+
include_default_port: false,
|
160
165
|
nonblock: true,
|
161
|
-
omit_default_port:
|
166
|
+
omit_default_port: true,
|
162
167
|
persistent: false,
|
163
168
|
read_timeout: 60,
|
164
169
|
resolv_resolver: nil,
|
@@ -1,41 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Excon
|
3
4
|
module Middleware
|
4
5
|
class Decompress < Excon::Middleware::Base
|
5
|
-
|
6
6
|
INFLATE_ZLIB_OR_GZIP = 47 # Zlib::MAX_WBITS + 32
|
7
7
|
INFLATE_RAW = -15 # Zlib::MAX_WBITS * -1
|
8
8
|
|
9
9
|
def request_call(datum)
|
10
|
-
unless datum.
|
11
|
-
key = datum[:headers].keys.detect {|k| k.to_s.casecmp('Accept-Encoding')
|
12
|
-
if datum[:headers][key].to_s.empty?
|
13
|
-
datum[:headers][key] = 'deflate, gzip'
|
14
|
-
end
|
10
|
+
unless datum.key?(:response_block)
|
11
|
+
key = datum[:headers].keys.detect { |k| k.to_s.casecmp('Accept-Encoding').zero? } || 'Accept-Encoding'
|
12
|
+
datum[:headers][key] = 'deflate, gzip' if datum[:headers][key].to_s.empty?
|
15
13
|
end
|
16
14
|
@stack.request_call(datum)
|
17
15
|
end
|
18
16
|
|
19
17
|
def response_call(datum)
|
20
18
|
body = datum[:response][:body]
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
Zlib::Inflate.new(INFLATE_RAW).inflate(body)
|
30
|
-
end
|
31
|
-
encodings.pop
|
32
|
-
elsif encoding.casecmp('gzip') == 0 || encoding.casecmp('x-gzip') == 0
|
33
|
-
datum[:response][:body] = Zlib::GzipReader.new(StringIO.new(body)).read
|
34
|
-
encodings.pop
|
35
|
-
end
|
36
|
-
datum[:response][:headers][key] = encodings.join(', ')
|
19
|
+
if !(datum.key?(:response_block) || body.nil? || body.empty?) &&
|
20
|
+
(key = datum[:response][:headers].keys.detect { |k| k.casecmp('Content-Encoding').zero? })
|
21
|
+
encodings = Utils.split_header_value(datum[:response][:headers][key])
|
22
|
+
if encodings.last.casecmp('deflate').zero?
|
23
|
+
datum[:response][:body] = begin
|
24
|
+
Zlib::Inflate.new(INFLATE_ZLIB_OR_GZIP).inflate(body)
|
25
|
+
rescue Zlib::DataError # fallback to raw on error
|
26
|
+
Zlib::Inflate.new(INFLATE_RAW).inflate(body)
|
37
27
|
end
|
28
|
+
encodings.pop
|
29
|
+
elsif encodings.last.casecmp('gzip').zero? || encodings.last.casecmp('x-gzip').zero?
|
30
|
+
datum[:response][:body] = Zlib::GzipReader.new(StringIO.new(body)).read
|
31
|
+
encodings.pop
|
38
32
|
end
|
33
|
+
datum[:response][:headers][key] = encodings.join(', ')
|
39
34
|
end
|
40
35
|
@stack.response_call(datum)
|
41
36
|
end
|
data/lib/excon/ssl_socket.rb
CHANGED
@@ -108,7 +108,7 @@ module Excon
|
|
108
108
|
end
|
109
109
|
|
110
110
|
if @data[:proxy]
|
111
|
-
request = "CONNECT #{@data[:host]}#{
|
111
|
+
request = "CONNECT #{@data[:host]}#{Excon::HTTP_1_1}" \
|
112
112
|
"Host: #{@data[:host]}#{port_string(@data)}#{Excon::CR_NL}"
|
113
113
|
|
114
114
|
if @data[:proxy].has_key?(:user) || @data[:proxy].has_key?(:password)
|
data/lib/excon/utils.rb
CHANGED
@@ -62,11 +62,33 @@ module Excon
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def port_string(datum)
|
65
|
-
if
|
66
|
-
|
65
|
+
if !default_port?(datum) || datum[:include_default_port] || !datum[:omit_default_port]
|
66
|
+
":#{datum[:port]}"
|
67
67
|
else
|
68
|
-
'
|
68
|
+
''
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Used to normalize queries for stubs, based on Rack::Utils.parse_query
|
73
|
+
def parse_query_string(string)
|
74
|
+
params = {}
|
75
|
+
|
76
|
+
string.split(/[&;] */n).each do |pair|
|
77
|
+
key, value = pair.split('=', 2).map { |x| CGI.unescape(x) }
|
78
|
+
|
79
|
+
params[key] = if params[key]
|
80
|
+
[params[key], value].flatten
|
81
|
+
else
|
82
|
+
value
|
83
|
+
end
|
69
84
|
end
|
85
|
+
|
86
|
+
params
|
87
|
+
end
|
88
|
+
|
89
|
+
def default_port?(datum)
|
90
|
+
(datum[:scheme].casecmp('http').zero? && datum[:port] == 80) ||
|
91
|
+
(datum[:scheme].casecmp('https').zero? && datum[:port] == 443)
|
70
92
|
end
|
71
93
|
|
72
94
|
def query_string(datum)
|
data/lib/excon/version.rb
CHANGED
data/lib/excon.rb
CHANGED
@@ -19,6 +19,7 @@ require 'excon/version'
|
|
19
19
|
require 'excon/extensions/uri'
|
20
20
|
|
21
21
|
require 'excon/middlewares/base'
|
22
|
+
require 'excon/middlewares/decompress'
|
22
23
|
require 'excon/middlewares/expects'
|
23
24
|
require 'excon/middlewares/idempotent'
|
24
25
|
require 'excon/middlewares/instrumentor'
|
@@ -32,7 +33,6 @@ require 'excon/utils'
|
|
32
33
|
require 'excon/connection'
|
33
34
|
require 'excon/headers'
|
34
35
|
require 'excon/response'
|
35
|
-
require 'excon/middlewares/decompress'
|
36
36
|
require 'excon/middlewares/escape_path'
|
37
37
|
require 'excon/middlewares/redirect_follower'
|
38
38
|
require 'excon/middlewares/capture_cookies'
|
@@ -143,7 +143,7 @@ module Excon
|
|
143
143
|
uri = URI.parse(url)
|
144
144
|
request_params = {
|
145
145
|
host: uri.host,
|
146
|
-
path: uri.path,
|
146
|
+
path: uri.path.empty? ? '/' : uri.path,
|
147
147
|
port: uri.port,
|
148
148
|
query: uri.query,
|
149
149
|
scheme: uri.scheme
|
@@ -162,6 +162,9 @@ module Excon
|
|
162
162
|
end
|
163
163
|
request_params[:headers] = headers
|
164
164
|
end
|
165
|
+
if request_params.key?(:query) && request_params[:query].instance_of?(String)
|
166
|
+
request_params[:query] = Utils.parse_query_string(request_params[:query])
|
167
|
+
end
|
165
168
|
if block_given?
|
166
169
|
raise(ArgumentError, 'stub requires either response_params OR a block') if response_params
|
167
170
|
|
@@ -182,6 +185,9 @@ module Excon
|
|
182
185
|
if (method = request_params.delete(:method))
|
183
186
|
request_params[:method] = method.to_s.downcase.to_sym
|
184
187
|
end
|
188
|
+
if request_params.key?(:query) && request_params[:query].instance_of?(String)
|
189
|
+
request_params[:query] = Utils.parse_query_string(request_params[:query])
|
190
|
+
end
|
185
191
|
Excon.stubs.each do |stub, response_params|
|
186
192
|
captures = { headers: {} }
|
187
193
|
headers_match = !stub.key?(:headers) || stub[:headers].keys.all? do |key|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: excon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- dpiddy (Dan Peterson)
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2024-10-
|
13
|
+
date: 2024-10-24 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|