excon 1.7.3 → 1.9.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/CONTRIBUTING.md +1 -0
- data/README.md +3 -1
- data/data/cacert.pem +120 -54
- data/excon.gemspec +1 -12
- data/lib/excon/connection.rb +24 -16
- data/lib/excon/instrumentors/logging_instrumentor.rb +10 -3
- data/lib/excon/middlewares/redirect_follower.rb +20 -5
- data/lib/excon/version.rb +1 -1
- data/lib/excon.rb +3 -0
- metadata +4 -149
- data/lib/excon/test/plugin/server/exec.rb +0 -26
- data/lib/excon/test/plugin/server/puma.rb +0 -23
- data/lib/excon/test/plugin/server/unicorn.rb +0 -40
- data/lib/excon/test/plugin/server/webrick.rb +0 -26
- data/lib/excon/test/server.rb +0 -99
data/excon.gemspec
CHANGED
|
@@ -23,20 +23,9 @@ Gem::Specification.new do |s|
|
|
|
23
23
|
]
|
|
24
24
|
s.required_ruby_version = '>= 3.3.0'
|
|
25
25
|
|
|
26
|
-
s.
|
|
27
|
-
|
|
28
|
-
s.add_development_dependency('activesupport')
|
|
29
|
-
s.add_development_dependency('delorean')
|
|
30
|
-
s.add_development_dependency('eventmachine', '>= 1.0.4')
|
|
31
|
-
s.add_development_dependency('json', '>= 1.8.5')
|
|
32
|
-
s.add_development_dependency('open4')
|
|
26
|
+
s.add_development_dependency('minitest', '>= 6')
|
|
33
27
|
s.add_development_dependency('puma')
|
|
34
28
|
s.add_development_dependency('rake')
|
|
35
|
-
s.add_development_dependency('rdoc')
|
|
36
|
-
s.add_development_dependency('rspec', '>= 3.5.0')
|
|
37
|
-
s.add_development_dependency('shindo')
|
|
38
|
-
s.add_development_dependency('sinatra')
|
|
39
|
-
s.add_development_dependency('sinatra-contrib')
|
|
40
29
|
s.add_development_dependency('webrick')
|
|
41
30
|
|
|
42
31
|
s.metadata = {
|
data/lib/excon/connection.rb
CHANGED
|
@@ -56,14 +56,15 @@ module Excon
|
|
|
56
56
|
# @option params [String] :socket The path to the unix socket (required for 'unix://' connections)
|
|
57
57
|
# @option params [String] :ciphers Only use the specified SSL/TLS cipher suites; use OpenSSL cipher spec format e.g. 'HIGH:!aNULL:!3DES' or 'AES256-SHA:DES-CBC3-SHA'
|
|
58
58
|
# @option params [String] :proxy Proxy server; e.g. 'http://myproxy.com:8888'
|
|
59
|
-
# @option params [Fixnum] :retry_limit Set how many times we'll retry a failed request. (Default 4)
|
|
60
|
-
# @option params [Fixnum] :retry_interval Set how long to wait between retries. (Default 0)
|
|
59
|
+
# @option params [Fixnum] :retry_limit Set how many times we'll retry a failed request. (Default 4) Only applies to :idempotent requests.
|
|
60
|
+
# @option params [Fixnum] :retry_interval Set how long to wait between retries. (Default 0) Only applies to :idempotent requests.
|
|
61
61
|
# @option params [Class] :instrumentor Responds to #instrument as in ActiveSupport::Notifications
|
|
62
62
|
# @option params [String] :instrumentor_name Name prefix for #instrument events. Defaults to 'excon'
|
|
63
63
|
# @option params [Resolv, nil] :resolv_resolver A ready to use +Resolv+ resolver instance.
|
|
64
64
|
# @option params [Class] :resolver_factory Const of the resolver factory. Defaults to 'Excon::ResolverFactory'
|
|
65
65
|
def initialize(params = {})
|
|
66
66
|
@pid = Process.pid
|
|
67
|
+
@sockets_mutex = Mutex.new
|
|
67
68
|
@data = Excon.defaults.dup
|
|
68
69
|
# merge does not deep-dup, so make sure headers is not the original
|
|
69
70
|
@data[:headers] = @data[:headers].dup
|
|
@@ -512,21 +513,26 @@ module Excon
|
|
|
512
513
|
end
|
|
513
514
|
|
|
514
515
|
def sockets
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
516
|
+
# Threads sharing this connection all read and write @_excon_sockets.
|
|
517
|
+
# On a Ruby without a GVL (JRuby) concurrent updates can lose another
|
|
518
|
+
# thread's entry, so that thread opens a new socket mid-request.
|
|
519
|
+
@sockets_mutex.synchronize do
|
|
520
|
+
if @pid != Process.pid
|
|
521
|
+
@_excon_sockets&.clear # GC will take care of closing sockets
|
|
522
|
+
@pid = Process.pid
|
|
523
|
+
end
|
|
519
524
|
|
|
520
|
-
|
|
521
|
-
|
|
525
|
+
if @data[:thread_safe_sockets]
|
|
526
|
+
@_excon_sockets ||= ObjectSpace::WeakKeyMap.new
|
|
522
527
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
528
|
+
# In a multi-threaded world, if the same connection is used by multiple
|
|
529
|
+
# threads at the same time to connect to the same destination, they may
|
|
530
|
+
# stomp on each other's sockets. This ensures every thread gets their
|
|
531
|
+
# own socket cache, within the context of a single connection.
|
|
532
|
+
@_excon_sockets[Thread.current] ||= {}
|
|
533
|
+
else
|
|
534
|
+
@_excon_sockets ||= {}.compare_by_identity
|
|
535
|
+
end
|
|
530
536
|
end
|
|
531
537
|
end
|
|
532
538
|
|
|
@@ -545,8 +551,10 @@ module Excon
|
|
|
545
551
|
rescue IPAddr::Error
|
|
546
552
|
false
|
|
547
553
|
end
|
|
554
|
+
elsif host == '*'
|
|
555
|
+
true
|
|
548
556
|
else
|
|
549
|
-
/(^|\.)#{host}$/.match(@data[:host])
|
|
557
|
+
/(^|\.)#{Regexp.escape(host)}$/.match(@data[:host])
|
|
550
558
|
end
|
|
551
559
|
host_match && (port.nil? || port.to_i == @data[:port])
|
|
552
560
|
end
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
require 'logger'
|
|
2
|
-
|
|
3
1
|
module Excon
|
|
4
2
|
class LoggingInstrumentor
|
|
5
3
|
|
|
4
|
+
# Stand-in for Logger.new($stderr), matching Logger's default format, so
|
|
5
|
+
# excon does not need to depend on the logger gem.
|
|
6
|
+
module StderrLogger
|
|
7
|
+
def self.info(message)
|
|
8
|
+
timestamp = Time.now.strftime('%Y-%m-%dT%H:%M:%S.%6N')
|
|
9
|
+
$stderr.write("I, [#{timestamp} ##{Process.pid}] INFO -- : #{message}\n")
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
6
13
|
def self.instrument(name, params = {})
|
|
7
14
|
params = params.dup
|
|
8
15
|
|
|
9
|
-
logger = params[:logger] ||
|
|
16
|
+
logger = params[:logger] || StderrLogger
|
|
10
17
|
|
|
11
18
|
# reduce duplication/noise of output
|
|
12
19
|
params.delete(:connection)
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
module Excon
|
|
3
3
|
module Middleware
|
|
4
4
|
class RedirectFollower < Excon::Middleware::Base
|
|
5
|
+
CONTENT_HEADERS = %w[
|
|
6
|
+
Content-Encoding
|
|
7
|
+
Content-Language
|
|
8
|
+
Content-Length
|
|
9
|
+
Content-Location
|
|
10
|
+
Content-Type
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
5
13
|
REDACTION_HEADERS = %w[
|
|
6
14
|
Authorization
|
|
7
15
|
Cookie
|
|
@@ -39,6 +47,10 @@ module Excon
|
|
|
39
47
|
if datum.has_key?(:response)
|
|
40
48
|
case datum[:response][:status]
|
|
41
49
|
when 301, 302, 303, 307, 308
|
|
50
|
+
location = get_header(datum, 'Location')
|
|
51
|
+
# Without a Location there is nowhere to go, so return the response as is
|
|
52
|
+
return @stack.response_call(datum) unless location
|
|
53
|
+
|
|
42
54
|
if datum[:redirects_remaining] <= 0
|
|
43
55
|
raise Excon::Errors::TooManyRedirects
|
|
44
56
|
end
|
|
@@ -47,7 +59,6 @@ module Excon
|
|
|
47
59
|
|
|
48
60
|
uri_parser = datum[:uri_parser] || Excon.defaults[:uri_parser]
|
|
49
61
|
|
|
50
|
-
location = get_header(datum, 'Location')
|
|
51
62
|
base_uri = Excon::Utils.request_uri(datum)
|
|
52
63
|
uri = uri_parser.join(base_uri, location)
|
|
53
64
|
|
|
@@ -61,14 +72,18 @@ module Excon
|
|
|
61
72
|
params.delete(:stack)
|
|
62
73
|
params.delete(:user)
|
|
63
74
|
|
|
75
|
+
params[:headers] = datum[:headers].dup
|
|
64
76
|
if [301, 302, 303].include?(response[:status])
|
|
65
77
|
params[:method] = :get
|
|
66
78
|
params.delete(:body)
|
|
67
|
-
|
|
79
|
+
# The body is not sent again, so neither are the header fields describing it
|
|
80
|
+
params[:headers].delete_if do |key, _|
|
|
81
|
+
CONTENT_HEADERS.any? { |header| key.to_s.casecmp?(header) }
|
|
82
|
+
end
|
|
68
83
|
end
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
84
|
+
# drop sensitive headers in any casing
|
|
85
|
+
params[:headers].delete_if do |key, _|
|
|
86
|
+
REDACTION_HEADERS.any? { |header| key.to_s.casecmp?(header) }
|
|
72
87
|
end
|
|
73
88
|
params.merge!(
|
|
74
89
|
:scheme => uri.scheme || datum[:scheme],
|
data/lib/excon/version.rb
CHANGED
data/lib/excon.rb
CHANGED
|
@@ -139,6 +139,9 @@ module Excon
|
|
|
139
139
|
# @param request_params [Hash<Symbol, >] request params to match against, omitted params match all
|
|
140
140
|
# @param response_params [Hash<Symbol, >] response params to return or block to call with matched params
|
|
141
141
|
def stub(request_params = {}, response_params = nil, &block)
|
|
142
|
+
# copy, so later changes to the caller's hash (e.g. stub_for adding
|
|
143
|
+
# :captures) don't change the stored stub
|
|
144
|
+
request_params = request_params.dup
|
|
142
145
|
if (method = request_params.delete(:method))
|
|
143
146
|
request_params[:method] = method.to_s.downcase.to_sym
|
|
144
147
|
end
|
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: 1.
|
|
4
|
+
version: 1.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- dpiddy (Dan Peterson)
|
|
@@ -12,89 +12,19 @@ cert_chain: []
|
|
|
12
12
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
|
-
name:
|
|
15
|
+
name: minitest
|
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
|
17
17
|
requirements:
|
|
18
18
|
- - ">="
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
|
-
version: '
|
|
21
|
-
type: :runtime
|
|
22
|
-
prerelease: false
|
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
-
requirements:
|
|
25
|
-
- - ">="
|
|
26
|
-
- !ruby/object:Gem::Version
|
|
27
|
-
version: '0'
|
|
28
|
-
- !ruby/object:Gem::Dependency
|
|
29
|
-
name: activesupport
|
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
|
31
|
-
requirements:
|
|
32
|
-
- - ">="
|
|
33
|
-
- !ruby/object:Gem::Version
|
|
34
|
-
version: '0'
|
|
35
|
-
type: :development
|
|
36
|
-
prerelease: false
|
|
37
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
-
requirements:
|
|
39
|
-
- - ">="
|
|
40
|
-
- !ruby/object:Gem::Version
|
|
41
|
-
version: '0'
|
|
42
|
-
- !ruby/object:Gem::Dependency
|
|
43
|
-
name: delorean
|
|
44
|
-
requirement: !ruby/object:Gem::Requirement
|
|
45
|
-
requirements:
|
|
46
|
-
- - ">="
|
|
47
|
-
- !ruby/object:Gem::Version
|
|
48
|
-
version: '0'
|
|
20
|
+
version: '6'
|
|
49
21
|
type: :development
|
|
50
22
|
prerelease: false
|
|
51
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
52
24
|
requirements:
|
|
53
25
|
- - ">="
|
|
54
26
|
- !ruby/object:Gem::Version
|
|
55
|
-
version: '
|
|
56
|
-
- !ruby/object:Gem::Dependency
|
|
57
|
-
name: eventmachine
|
|
58
|
-
requirement: !ruby/object:Gem::Requirement
|
|
59
|
-
requirements:
|
|
60
|
-
- - ">="
|
|
61
|
-
- !ruby/object:Gem::Version
|
|
62
|
-
version: 1.0.4
|
|
63
|
-
type: :development
|
|
64
|
-
prerelease: false
|
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
-
requirements:
|
|
67
|
-
- - ">="
|
|
68
|
-
- !ruby/object:Gem::Version
|
|
69
|
-
version: 1.0.4
|
|
70
|
-
- !ruby/object:Gem::Dependency
|
|
71
|
-
name: json
|
|
72
|
-
requirement: !ruby/object:Gem::Requirement
|
|
73
|
-
requirements:
|
|
74
|
-
- - ">="
|
|
75
|
-
- !ruby/object:Gem::Version
|
|
76
|
-
version: 1.8.5
|
|
77
|
-
type: :development
|
|
78
|
-
prerelease: false
|
|
79
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
80
|
-
requirements:
|
|
81
|
-
- - ">="
|
|
82
|
-
- !ruby/object:Gem::Version
|
|
83
|
-
version: 1.8.5
|
|
84
|
-
- !ruby/object:Gem::Dependency
|
|
85
|
-
name: open4
|
|
86
|
-
requirement: !ruby/object:Gem::Requirement
|
|
87
|
-
requirements:
|
|
88
|
-
- - ">="
|
|
89
|
-
- !ruby/object:Gem::Version
|
|
90
|
-
version: '0'
|
|
91
|
-
type: :development
|
|
92
|
-
prerelease: false
|
|
93
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
94
|
-
requirements:
|
|
95
|
-
- - ">="
|
|
96
|
-
- !ruby/object:Gem::Version
|
|
97
|
-
version: '0'
|
|
27
|
+
version: '6'
|
|
98
28
|
- !ruby/object:Gem::Dependency
|
|
99
29
|
name: puma
|
|
100
30
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -123,76 +53,6 @@ dependencies:
|
|
|
123
53
|
- - ">="
|
|
124
54
|
- !ruby/object:Gem::Version
|
|
125
55
|
version: '0'
|
|
126
|
-
- !ruby/object:Gem::Dependency
|
|
127
|
-
name: rdoc
|
|
128
|
-
requirement: !ruby/object:Gem::Requirement
|
|
129
|
-
requirements:
|
|
130
|
-
- - ">="
|
|
131
|
-
- !ruby/object:Gem::Version
|
|
132
|
-
version: '0'
|
|
133
|
-
type: :development
|
|
134
|
-
prerelease: false
|
|
135
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
136
|
-
requirements:
|
|
137
|
-
- - ">="
|
|
138
|
-
- !ruby/object:Gem::Version
|
|
139
|
-
version: '0'
|
|
140
|
-
- !ruby/object:Gem::Dependency
|
|
141
|
-
name: rspec
|
|
142
|
-
requirement: !ruby/object:Gem::Requirement
|
|
143
|
-
requirements:
|
|
144
|
-
- - ">="
|
|
145
|
-
- !ruby/object:Gem::Version
|
|
146
|
-
version: 3.5.0
|
|
147
|
-
type: :development
|
|
148
|
-
prerelease: false
|
|
149
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
150
|
-
requirements:
|
|
151
|
-
- - ">="
|
|
152
|
-
- !ruby/object:Gem::Version
|
|
153
|
-
version: 3.5.0
|
|
154
|
-
- !ruby/object:Gem::Dependency
|
|
155
|
-
name: shindo
|
|
156
|
-
requirement: !ruby/object:Gem::Requirement
|
|
157
|
-
requirements:
|
|
158
|
-
- - ">="
|
|
159
|
-
- !ruby/object:Gem::Version
|
|
160
|
-
version: '0'
|
|
161
|
-
type: :development
|
|
162
|
-
prerelease: false
|
|
163
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
164
|
-
requirements:
|
|
165
|
-
- - ">="
|
|
166
|
-
- !ruby/object:Gem::Version
|
|
167
|
-
version: '0'
|
|
168
|
-
- !ruby/object:Gem::Dependency
|
|
169
|
-
name: sinatra
|
|
170
|
-
requirement: !ruby/object:Gem::Requirement
|
|
171
|
-
requirements:
|
|
172
|
-
- - ">="
|
|
173
|
-
- !ruby/object:Gem::Version
|
|
174
|
-
version: '0'
|
|
175
|
-
type: :development
|
|
176
|
-
prerelease: false
|
|
177
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
178
|
-
requirements:
|
|
179
|
-
- - ">="
|
|
180
|
-
- !ruby/object:Gem::Version
|
|
181
|
-
version: '0'
|
|
182
|
-
- !ruby/object:Gem::Dependency
|
|
183
|
-
name: sinatra-contrib
|
|
184
|
-
requirement: !ruby/object:Gem::Requirement
|
|
185
|
-
requirements:
|
|
186
|
-
- - ">="
|
|
187
|
-
- !ruby/object:Gem::Version
|
|
188
|
-
version: '0'
|
|
189
|
-
type: :development
|
|
190
|
-
prerelease: false
|
|
191
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
192
|
-
requirements:
|
|
193
|
-
- - ">="
|
|
194
|
-
- !ruby/object:Gem::Version
|
|
195
|
-
version: '0'
|
|
196
56
|
- !ruby/object:Gem::Dependency
|
|
197
57
|
name: webrick
|
|
198
58
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -247,11 +107,6 @@ files:
|
|
|
247
107
|
- lib/excon/socks5_socket.rb
|
|
248
108
|
- lib/excon/socks5_ssl_socket.rb
|
|
249
109
|
- lib/excon/ssl_socket.rb
|
|
250
|
-
- lib/excon/test/plugin/server/exec.rb
|
|
251
|
-
- lib/excon/test/plugin/server/puma.rb
|
|
252
|
-
- lib/excon/test/plugin/server/unicorn.rb
|
|
253
|
-
- lib/excon/test/plugin/server/webrick.rb
|
|
254
|
-
- lib/excon/test/server.rb
|
|
255
110
|
- lib/excon/unix_socket.rb
|
|
256
111
|
- lib/excon/utils.rb
|
|
257
112
|
- lib/excon/version.rb
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
module Excon
|
|
2
|
-
module Test
|
|
3
|
-
module Plugin
|
|
4
|
-
module Server
|
|
5
|
-
module Exec
|
|
6
|
-
def start(app_str = app)
|
|
7
|
-
open_process(app_str)
|
|
8
|
-
process_stderr = ""
|
|
9
|
-
line = ''
|
|
10
|
-
until line =~ /\Aready\Z/
|
|
11
|
-
line = error.gets
|
|
12
|
-
raise process_stderr if line.nil?
|
|
13
|
-
process_stderr << line
|
|
14
|
-
fatal_time = elapsed_time > timeout
|
|
15
|
-
if fatal_time
|
|
16
|
-
msg = "executable #{app_str} has taken too long to start"
|
|
17
|
-
raise msg
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
true
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module Excon
|
|
2
|
-
module Test
|
|
3
|
-
module Plugin
|
|
4
|
-
module Server
|
|
5
|
-
module Puma
|
|
6
|
-
def start(app_str = app, bind_uri = bind)
|
|
7
|
-
open_process(RbConfig.ruby, '-S', 'puma', '-b', bind_uri.to_s, app_str)
|
|
8
|
-
process_stderr = ""
|
|
9
|
-
line = ''
|
|
10
|
-
until line.include?('Use Ctrl-C to stop')
|
|
11
|
-
line = read.gets
|
|
12
|
-
raise process_stderr if line.nil?
|
|
13
|
-
process_stderr << line
|
|
14
|
-
fatal_time = elapsed_time > timeout
|
|
15
|
-
raise 'puma server has taken too long to start' if fatal_time
|
|
16
|
-
end
|
|
17
|
-
true
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
module Excon
|
|
2
|
-
module Test
|
|
3
|
-
module Plugin
|
|
4
|
-
module Server
|
|
5
|
-
module Unicorn
|
|
6
|
-
def start(app_str = app, bind_uri = bind)
|
|
7
|
-
bind_uri = URI.parse(bind_uri) unless bind_uri.is_a? URI::Generic
|
|
8
|
-
is_unix_socket = (bind_uri.scheme == "unix")
|
|
9
|
-
if is_unix_socket
|
|
10
|
-
bind_str = bind_uri.to_s
|
|
11
|
-
else
|
|
12
|
-
host = bind_uri.host.gsub(/[\[\]]/, '')
|
|
13
|
-
bind_str = "#{host}:#{bind_uri.port}"
|
|
14
|
-
end
|
|
15
|
-
args = [
|
|
16
|
-
RbConfig.ruby,
|
|
17
|
-
'-S',
|
|
18
|
-
'unicorn',
|
|
19
|
-
'--no-default-middleware',
|
|
20
|
-
'-l',
|
|
21
|
-
bind_str,
|
|
22
|
-
app_str
|
|
23
|
-
]
|
|
24
|
-
open_process(*args)
|
|
25
|
-
process_stderr = ''
|
|
26
|
-
line = ''
|
|
27
|
-
until line.include?('worker=0 ready')
|
|
28
|
-
line = error.gets
|
|
29
|
-
raise process_stderr if line.nil?
|
|
30
|
-
process_stderr << line
|
|
31
|
-
fatal_time = elapsed_time > timeout
|
|
32
|
-
raise 'unicorn server has taken too long to start' if fatal_time
|
|
33
|
-
end
|
|
34
|
-
true
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
module Excon
|
|
2
|
-
module Test
|
|
3
|
-
module Plugin
|
|
4
|
-
module Server
|
|
5
|
-
module Webrick
|
|
6
|
-
def start(app_str = app, bind_uri = bind)
|
|
7
|
-
bind_uri = URI.parse(bind_uri) unless bind_uri.is_a? URI::Generic
|
|
8
|
-
host = bind_uri.host.gsub(/[\[\]]/, '')
|
|
9
|
-
port = bind_uri.port.to_s
|
|
10
|
-
open_process(RbConfig.ruby, '-S', 'rackup', '-s', 'webrick', '--host', host, '--port', port, app_str)
|
|
11
|
-
process_stderr = ""
|
|
12
|
-
line = ''
|
|
13
|
-
until line.include?('Server#start')
|
|
14
|
-
line = error.gets
|
|
15
|
-
raise process_stderr if line.nil?
|
|
16
|
-
process_stderr << line
|
|
17
|
-
fatal_time = elapsed_time > timeout
|
|
18
|
-
raise 'webrick server has taken too long to start' if fatal_time
|
|
19
|
-
end
|
|
20
|
-
true
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
data/lib/excon/test/server.rb
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
require 'open4'
|
|
2
|
-
require 'excon'
|
|
3
|
-
require 'excon/test/plugin/server/webrick'
|
|
4
|
-
require 'excon/test/plugin/server/unicorn'
|
|
5
|
-
require 'excon/test/plugin/server/puma'
|
|
6
|
-
require 'excon/test/plugin/server/exec'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
module Excon
|
|
10
|
-
module Test
|
|
11
|
-
class Server
|
|
12
|
-
attr_accessor :app, :server, :bind, :pid, :read, :write, :error, :started_at, :timeout
|
|
13
|
-
|
|
14
|
-
# Methods that must be implemented by a plugin
|
|
15
|
-
INSTANCE_REQUIRES = [:start]
|
|
16
|
-
|
|
17
|
-
def initialize(args)
|
|
18
|
-
# TODO: Validate these args
|
|
19
|
-
@server = args.keys.first
|
|
20
|
-
@app = args[server]
|
|
21
|
-
args[:bind] ||= 'tcp://127.0.0.1:9292'
|
|
22
|
-
@bind = URI.parse(args[:bind])
|
|
23
|
-
@is_unix_socket = (@bind.scheme == 'unix')
|
|
24
|
-
@bind.host = @bind.host.gsub(/[\[\]]/, '') unless @is_unix_socket
|
|
25
|
-
if args[:timeout]
|
|
26
|
-
@timeout = args[:timeout]
|
|
27
|
-
else
|
|
28
|
-
@timeout = 20
|
|
29
|
-
end
|
|
30
|
-
name = @server.to_s.split('_').collect(&:capitalize).join
|
|
31
|
-
plug = nested_const_get("Excon::Test::Plugin::Server::#{name}")
|
|
32
|
-
self.extend plug
|
|
33
|
-
check_implementation(plug)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def open_process(*args)
|
|
37
|
-
if RUBY_PLATFORM == 'java'
|
|
38
|
-
@pid, @write, @read, @error = IO.popen4(*args)
|
|
39
|
-
else
|
|
40
|
-
@pid, @write, @read, @error = Open4.popen4(*args)
|
|
41
|
-
end
|
|
42
|
-
@started_at = Time.now
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def elapsed_time
|
|
46
|
-
Time.now - started_at
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def stop
|
|
50
|
-
if RUBY_PLATFORM == 'java'
|
|
51
|
-
Process.kill('USR1', pid)
|
|
52
|
-
else
|
|
53
|
-
Process.kill('KILL', pid)
|
|
54
|
-
Process.wait(pid)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
if @is_unix_socket
|
|
58
|
-
socket = @bind.path
|
|
59
|
-
File.delete(socket) if File.exist?(socket)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# TODO: Ensure process is really dead
|
|
63
|
-
dump_errors
|
|
64
|
-
true
|
|
65
|
-
end
|
|
66
|
-
def dump_errors
|
|
67
|
-
lines = error.read.split($/)
|
|
68
|
-
while (line = lines.shift)
|
|
69
|
-
case line
|
|
70
|
-
when /(ERROR|Error)/
|
|
71
|
-
unless line.match?(/(null cert chain|did not return a certificate|SSL_read:: internal error)/)
|
|
72
|
-
in_err = true
|
|
73
|
-
puts
|
|
74
|
-
end
|
|
75
|
-
when /^(127|localhost)/
|
|
76
|
-
in_err = false
|
|
77
|
-
end
|
|
78
|
-
puts line if in_err
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
private
|
|
83
|
-
|
|
84
|
-
def nested_const_get(namespace)
|
|
85
|
-
namespace.split('::').inject(Object) do |mod, klass|
|
|
86
|
-
mod.const_get(klass)
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def check_implementation(plug)
|
|
91
|
-
INSTANCE_REQUIRES.each do |m|
|
|
92
|
-
unless self.respond_to? m
|
|
93
|
-
raise "FATAL: #{plug} does not implement ##{m}"
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
end
|