http 5.0.0.pre → 5.0.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +17 -1
- data/.travis.yml +6 -4
- data/CHANGES.md +83 -0
- data/Gemfile +2 -1
- data/README.md +7 -6
- data/http.gemspec +11 -4
- data/lib/http/chainable.rb +8 -3
- data/lib/http/client.rb +32 -34
- data/lib/http/connection.rb +5 -5
- data/lib/http/content_type.rb +2 -2
- data/lib/http/feature.rb +3 -0
- data/lib/http/features/auto_deflate.rb +13 -7
- data/lib/http/features/auto_inflate.rb +6 -5
- data/lib/http/features/normalize_uri.rb +17 -0
- data/lib/http/headers.rb +48 -11
- data/lib/http/headers/known.rb +3 -0
- data/lib/http/mime_type/adapter.rb +1 -1
- data/lib/http/mime_type/json.rb +1 -0
- data/lib/http/options.rb +4 -7
- data/lib/http/redirector.rb +3 -1
- data/lib/http/request.rb +32 -29
- data/lib/http/request/body.rb +26 -1
- data/lib/http/request/writer.rb +3 -2
- data/lib/http/response.rb +17 -15
- data/lib/http/response/body.rb +1 -0
- data/lib/http/response/parser.rb +20 -6
- data/lib/http/response/status.rb +2 -1
- data/lib/http/timeout/global.rb +1 -3
- data/lib/http/timeout/per_operation.rb +1 -0
- data/lib/http/uri.rb +13 -0
- data/lib/http/version.rb +1 -1
- data/spec/lib/http/client_spec.rb +96 -14
- data/spec/lib/http/connection_spec.rb +8 -5
- data/spec/lib/http/features/auto_inflate_spec.rb +4 -2
- data/spec/lib/http/features/instrumentation_spec.rb +7 -6
- data/spec/lib/http/features/logging_spec.rb +6 -5
- data/spec/lib/http/headers_spec.rb +52 -17
- data/spec/lib/http/options/headers_spec.rb +1 -1
- data/spec/lib/http/options/merge_spec.rb +16 -16
- data/spec/lib/http/redirector_spec.rb +15 -1
- data/spec/lib/http/request/body_spec.rb +22 -0
- data/spec/lib/http/request/writer_spec.rb +13 -1
- data/spec/lib/http/request_spec.rb +5 -5
- data/spec/lib/http/response/parser_spec.rb +45 -0
- data/spec/lib/http/response/status_spec.rb +3 -3
- data/spec/lib/http/response_spec.rb +11 -22
- data/spec/lib/http_spec.rb +30 -1
- data/spec/support/black_hole.rb +1 -1
- data/spec/support/dummy_server.rb +6 -6
- data/spec/support/dummy_server/servlet.rb +8 -4
- data/spec/support/http_handling_shared.rb +4 -4
- data/spec/support/ssl_helper.rb +4 -4
- metadata +23 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbaa69332ed43468d3388aa291c39b50104981ab648b25b3de6afe9f6272242d
|
4
|
+
data.tar.gz: 4d8aa977a340af1da8b7ce8386c66a37a48a13c4d50f36fdfc0ef7db09837132
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12fdc45dc637e65dcda24a1e3c056a3f215d87229d60c8997b2c4c63754d4ac21c5872f4dddd03b2061b5ee2767e3558370fe7e0506b73444e09f730f5e6101d
|
7
|
+
data.tar.gz: 45af15139df31af3f99b31c5b554ad225c793d65c2b8506dd8b6469ee79be201832cdaa1bd22c510671fcdd3febf2b9844b168d18ef5b0ed9cc2cff7f83975f9
|
data/.rubocop.yml
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
require: rubocop-performance
|
2
|
+
|
1
3
|
AllCops:
|
2
4
|
TargetRubyVersion: 2.3
|
3
5
|
DisplayCopNames: true
|
4
6
|
|
5
7
|
## Layout ######################################################################
|
6
8
|
|
9
|
+
Layout/AlignHash:
|
10
|
+
EnforcedColonStyle: table
|
11
|
+
EnforcedHashRocketStyle: table
|
12
|
+
|
7
13
|
Layout/DotPosition:
|
8
14
|
EnforcedStyle: trailing
|
9
15
|
|
@@ -20,7 +26,8 @@ Metrics/AbcSize:
|
|
20
26
|
|
21
27
|
Metrics/BlockLength:
|
22
28
|
Exclude:
|
23
|
-
- spec/**/*
|
29
|
+
- "spec/**/*"
|
30
|
+
- "**/*.gemspec"
|
24
31
|
|
25
32
|
Metrics/BlockNesting:
|
26
33
|
Max: 2
|
@@ -60,6 +67,9 @@ Metrics/ParameterLists:
|
|
60
67
|
Performance/RegexpMatch:
|
61
68
|
Enabled: false
|
62
69
|
|
70
|
+
Performance/UnfreezeString:
|
71
|
+
Enabled: false
|
72
|
+
|
63
73
|
## Style #######################################################################
|
64
74
|
|
65
75
|
Style/CollectionMethods:
|
@@ -109,3 +119,9 @@ Style/TrivialAccessors:
|
|
109
119
|
|
110
120
|
Style/YodaCondition:
|
111
121
|
Enabled: false
|
122
|
+
|
123
|
+
Style/FormatStringToken:
|
124
|
+
EnforcedStyle: unannotated
|
125
|
+
|
126
|
+
Style/RescueStandardError:
|
127
|
+
EnforcedStyle: implicit
|
data/.travis.yml
CHANGED
@@ -17,20 +17,22 @@ env: JRUBY_OPTS="$JRUBY_OPTS --debug"
|
|
17
17
|
|
18
18
|
rvm:
|
19
19
|
# Include JRuby first because it takes the longest
|
20
|
-
- jruby-9.
|
21
|
-
- 2.3
|
20
|
+
- jruby-9.2.5.0
|
22
21
|
- 2.4
|
23
22
|
- 2.5
|
23
|
+
- 2.6
|
24
|
+
- 2.7
|
24
25
|
|
25
26
|
matrix:
|
26
27
|
fast_finish: true
|
27
28
|
include:
|
28
29
|
# Only run RuboCop and Yardstick metrics on the latest Ruby
|
29
|
-
- rvm: 2.
|
30
|
+
- rvm: 2.7
|
30
31
|
env: SUITE="rubocop"
|
31
|
-
- rvm: 2.
|
32
|
+
- rvm: 2.7
|
32
33
|
env: SUITE="yardstick"
|
33
34
|
|
34
35
|
branches:
|
35
36
|
only:
|
36
37
|
- master
|
38
|
+
- 4-x-stable
|
data/CHANGES.md
CHANGED
@@ -1,9 +1,89 @@
|
|
1
1
|
## future is unwritten (master)
|
2
2
|
|
3
|
+
* [#590](https://github.com/httprb/http/pull/590)
|
4
|
+
[#589](https://github.com/httprb/http/issues/589)
|
5
|
+
Fix response headers paring.
|
6
|
+
([@Bonias])
|
7
|
+
|
8
|
+
* [#587](https://github.com/httprb/http/pull/587)
|
9
|
+
[#585](https://github.com/httprb/http/issues/585)
|
10
|
+
Fix redirections when server responds with multiple Location headers.
|
11
|
+
([@ixti])
|
12
|
+
|
13
|
+
* [#581](https://github.com/httprb/http/pull/581)
|
14
|
+
[#582](https://github.com/httprb/http/issues/582)
|
15
|
+
Add Ruby 2.7.x support.
|
16
|
+
([@janko])
|
17
|
+
|
18
|
+
* [#577](https://github.com/httprb/http/pull/577)
|
19
|
+
Fix `Chainable#timeout` with frozen Hash.
|
20
|
+
([@antonvolkoff])
|
21
|
+
|
22
|
+
* [#576](https://github.com/httprb/http/pull/576)
|
23
|
+
[#524](https://github.com/httprb/http/issues/524)
|
24
|
+
Preserve header names casing.
|
25
|
+
([@joshuaflanagan])
|
26
|
+
|
27
|
+
* [#532](https://github.com/httprb/http/pull/532)
|
28
|
+
Fix pipes support in request bodies.
|
29
|
+
([@ixti])
|
30
|
+
|
31
|
+
* [#530](https://github.com/httprb/http/pull/530)
|
32
|
+
Improve header fields name/value validation.
|
33
|
+
([@Bonias])
|
34
|
+
|
35
|
+
* [#506](https://github.com/httprb/http/pull/506)
|
36
|
+
[#521](https://github.com/httprb/http/issues/521)
|
37
|
+
Skip auto-deflate when there is no body.
|
38
|
+
([@Bonias])
|
39
|
+
|
3
40
|
* [#489](https://github.com/httprb/http/pull/489)
|
4
41
|
Fix HTTP parser.
|
5
42
|
([@ixti], [@fxposter])
|
6
43
|
|
44
|
+
* [#546](https://github.com/httprb/http/pull/546)
|
45
|
+
**BREAKING CHANGE**
|
46
|
+
Provide initiating `HTTP::Request` object on `HTTP::Response`.
|
47
|
+
([@joshuaflanagan])
|
48
|
+
|
49
|
+
* [#571](https://github.com/httprb/http/pull/571)
|
50
|
+
Drop Ruby 2.3.x support.
|
51
|
+
([@ixti])
|
52
|
+
|
53
|
+
|
54
|
+
## 4.2.0 (2019-10-22)
|
55
|
+
|
56
|
+
* Backport [#489](https://github.com/httprb/http/pull/489)
|
57
|
+
Fix HTTP parser.
|
58
|
+
([@ixti], [@fxposter])
|
59
|
+
|
60
|
+
|
61
|
+
## 4.1.1 (2019-03-12)
|
62
|
+
|
63
|
+
* Add `HTTP::Headers::ACCEPT_ENCODING` constant.
|
64
|
+
([@ixti])
|
65
|
+
|
66
|
+
|
67
|
+
## 4.1.0 (2019-03-11)
|
68
|
+
|
69
|
+
* [#533](https://github.com/httprb/http/pull/533)
|
70
|
+
Add URI normalizer feature that allows to swap default URI normalizer.
|
71
|
+
([@mamoonraja])
|
72
|
+
|
73
|
+
|
74
|
+
## 4.0.5 (2019-02-15)
|
75
|
+
|
76
|
+
* Backport [#532](https://github.com/httprb/http/pull/532) from master.
|
77
|
+
Fix pipes support in request bodies.
|
78
|
+
([@ixti])
|
79
|
+
|
80
|
+
|
81
|
+
## 4.0.4 (2019-02-12)
|
82
|
+
|
83
|
+
* Backport [#506](https://github.com/httprb/http/pull/506) from master.
|
84
|
+
Skip auto-deflate when there is no body.
|
85
|
+
([@Bonias])
|
86
|
+
|
7
87
|
|
8
88
|
## 4.0.3 (2019-01-18)
|
9
89
|
|
@@ -752,3 +832,6 @@ end
|
|
752
832
|
[@paul]: https://github.com/paul
|
753
833
|
[@RickCSong]: https://github.com/RickCSong
|
754
834
|
[@fxposter]: https://github.com/fxposter
|
835
|
+
[@mamoonraja]: https://github.com/mamoonraja
|
836
|
+
[@joshuaflanagan]: https://github.com/joshuaflanagan
|
837
|
+
[@antonvolkoff]: https://github.com/antonvolkoff
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -18,13 +18,14 @@ HTTP (The Gem! a.k.a. http.rb) is an easy-to-use client library for making reque
|
|
18
18
|
from Ruby. It uses a simple method chaining system for building requests, similar to
|
19
19
|
Python's [Requests].
|
20
20
|
|
21
|
-
Under the hood,
|
22
|
-
|
21
|
+
Under the hood, via [Ruby FFI bindings][http-parser-ffi], http.rb uses the Node.js
|
22
|
+
[http-parser], a fast HTTP parsing native extension. This library
|
23
23
|
isn't just yet another wrapper around Net::HTTP. It implements the HTTP protocol
|
24
24
|
natively and outsources the parsing to native extensions.
|
25
25
|
|
26
26
|
[requests]: http://docs.python-requests.org/en/latest/
|
27
|
-
[
|
27
|
+
[http-parser]: https://github.com/nodejs/http-parser
|
28
|
+
[http-parser-ffi]: https://github.com/cotag/http-parser
|
28
29
|
|
29
30
|
|
30
31
|
## Another Ruby HTTP library? Why should I care?
|
@@ -164,10 +165,10 @@ and call `#readpartial` on it repeatedly until it returns `nil`:
|
|
164
165
|
This library aims to support and is [tested against][travis] the following Ruby
|
165
166
|
versions:
|
166
167
|
|
167
|
-
* Ruby 2.3.x
|
168
168
|
* Ruby 2.4.x
|
169
169
|
* Ruby 2.5.x
|
170
|
-
*
|
170
|
+
* Ruby 2.6.x
|
171
|
+
* JRuby 9.2.x.x
|
171
172
|
|
172
173
|
If something doesn't work on one of these versions, it's a bug.
|
173
174
|
|
@@ -197,5 +198,5 @@ dropped.
|
|
197
198
|
|
198
199
|
## Copyright
|
199
200
|
|
200
|
-
Copyright (c) 2011-
|
201
|
+
Copyright (c) 2011-2019 Tony Arcieri, Alexey V. Zapparov, Erik Michaels-Ober, Zachary Anker.
|
201
202
|
See LICENSE.txt for further details.
|
data/http.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
lib = File.expand_path("
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
require "http/version"
|
6
6
|
|
@@ -27,10 +27,17 @@ Gem::Specification.new do |gem|
|
|
27
27
|
|
28
28
|
gem.required_ruby_version = ">= 2.3"
|
29
29
|
|
30
|
-
gem.add_runtime_dependency "http-parser", "~> 1.2.0"
|
31
|
-
gem.add_runtime_dependency "http-form_data", "~> 2.0"
|
32
|
-
gem.add_runtime_dependency "http-cookie", "~> 1.0"
|
33
30
|
gem.add_runtime_dependency "addressable", "~> 2.3"
|
31
|
+
gem.add_runtime_dependency "http-cookie", "~> 1.0"
|
32
|
+
gem.add_runtime_dependency "http-form_data", "~> 2.2"
|
33
|
+
gem.add_runtime_dependency "http-parser", "~> 1.2.0"
|
34
34
|
|
35
35
|
gem.add_development_dependency "bundler", "~> 2.0"
|
36
|
+
|
37
|
+
gem.metadata = {
|
38
|
+
"source_code_uri" => "https://github.com/httprb/http",
|
39
|
+
"wiki_uri" => "https://github.com/httprb/http/wiki",
|
40
|
+
"bug_tracker_uri" => "https://github.com/httprb/http/issues",
|
41
|
+
"changelog_uri" => "https://github.com/httprb/http/blob/v#{HTTP::VERSION}/CHANGES.md"
|
42
|
+
}
|
36
43
|
end
|
data/lib/http/chainable.rb
CHANGED
@@ -93,7 +93,7 @@ module HTTP
|
|
93
93
|
def timeout(options)
|
94
94
|
klass, options = case options
|
95
95
|
when Numeric then [HTTP::Timeout::Global, {:global => options}]
|
96
|
-
when Hash then [HTTP::Timeout::PerOperation, options]
|
96
|
+
when Hash then [HTTP::Timeout::PerOperation, options.dup]
|
97
97
|
when :null then [HTTP::Timeout::Null, {}]
|
98
98
|
else raise ArgumentError, "Use `.timeout(global_timeout_in_seconds)` or `.timeout(connect: x, write: y, read: z)`."
|
99
99
|
|
@@ -101,11 +101,12 @@ module HTTP
|
|
101
101
|
|
102
102
|
%i[global read write connect].each do |k|
|
103
103
|
next unless options.key? k
|
104
|
+
|
104
105
|
options["#{k}_timeout".to_sym] = options.delete k
|
105
106
|
end
|
106
107
|
|
107
108
|
branch default_options.merge(
|
108
|
-
:timeout_class
|
109
|
+
:timeout_class => klass,
|
109
110
|
:timeout_options => options
|
110
111
|
)
|
111
112
|
end
|
@@ -144,6 +145,7 @@ module HTTP
|
|
144
145
|
options = {:keep_alive_timeout => timeout}
|
145
146
|
p_client = branch default_options.merge(options).with_persistent host
|
146
147
|
return p_client unless block_given?
|
148
|
+
|
147
149
|
yield p_client
|
148
150
|
ensure
|
149
151
|
p_client.close if p_client
|
@@ -168,7 +170,7 @@ module HTTP
|
|
168
170
|
alias through via
|
169
171
|
|
170
172
|
# Make client follow redirects.
|
171
|
-
# @param
|
173
|
+
# @param options
|
172
174
|
# @return [HTTP::Client]
|
173
175
|
# @see Redirector#initialize
|
174
176
|
def follow(options = {}) # rubocop:disable Style/OptionHash
|
@@ -236,6 +238,9 @@ module HTTP
|
|
236
238
|
# Turn on given features. Available features are:
|
237
239
|
# * auto_inflate
|
238
240
|
# * auto_deflate
|
241
|
+
# * instrumentation
|
242
|
+
# * logging
|
243
|
+
# * normalize_uri
|
239
244
|
# @param features
|
240
245
|
def use(*features)
|
241
246
|
branch default_options.with_features(features)
|
data/lib/http/client.rb
CHANGED
@@ -16,7 +16,7 @@ module HTTP
|
|
16
16
|
extend Forwardable
|
17
17
|
include Chainable
|
18
18
|
|
19
|
-
HTTP_OR_HTTPS_RE = %r{^https?://}i
|
19
|
+
HTTP_OR_HTTPS_RE = %r{^https?://}i.freeze
|
20
20
|
|
21
21
|
def initialize(default_options = {})
|
22
22
|
@default_options = HTTP::Options.new(default_options)
|
@@ -42,14 +42,14 @@ module HTTP
|
|
42
42
|
uri = make_request_uri(uri, opts)
|
43
43
|
headers = make_request_headers(opts)
|
44
44
|
body = make_request_body(opts, headers)
|
45
|
-
proxy = opts.proxy
|
46
45
|
|
47
46
|
req = HTTP::Request.new(
|
48
|
-
:verb
|
49
|
-
:uri
|
50
|
-
:
|
51
|
-
:proxy
|
52
|
-
:
|
47
|
+
:verb => verb,
|
48
|
+
:uri => uri,
|
49
|
+
:uri_normalizer => opts.feature(:normalize_uri)&.normalizer,
|
50
|
+
:proxy => opts.proxy,
|
51
|
+
:headers => headers,
|
52
|
+
:body => body
|
53
53
|
)
|
54
54
|
|
55
55
|
opts.features.inject(req) do |request, (_name, feature)|
|
@@ -70,20 +70,18 @@ module HTTP
|
|
70
70
|
|
71
71
|
@connection ||= HTTP::Connection.new(req, options)
|
72
72
|
|
73
|
-
|
74
|
-
@connection.
|
75
|
-
|
73
|
+
begin
|
74
|
+
unless @connection.failed_proxy_connect?
|
75
|
+
@connection.send_request(req)
|
76
|
+
@connection.read_headers!
|
77
|
+
end
|
78
|
+
rescue Error => e
|
79
|
+
options.features.each_value do |feature|
|
80
|
+
feature.on_error(req, e)
|
81
|
+
end
|
82
|
+
raise
|
76
83
|
end
|
77
|
-
|
78
|
-
res = Response.new(
|
79
|
-
:status => @connection.status_code,
|
80
|
-
:version => @connection.http_version,
|
81
|
-
:headers => @connection.headers,
|
82
|
-
:proxy_headers => @connection.proxy_response_headers,
|
83
|
-
:connection => @connection,
|
84
|
-
:encoding => options.encoding,
|
85
|
-
:uri => req.uri
|
86
|
-
)
|
84
|
+
res = build_response(req, options)
|
87
85
|
|
88
86
|
res = options.features.inject(res) do |response, (_name, feature)|
|
89
87
|
feature.wrap_response(response)
|
@@ -106,6 +104,18 @@ module HTTP
|
|
106
104
|
|
107
105
|
private
|
108
106
|
|
107
|
+
def build_response(req, options)
|
108
|
+
Response.new(
|
109
|
+
:status => @connection.status_code,
|
110
|
+
:version => @connection.http_version,
|
111
|
+
:headers => @connection.headers,
|
112
|
+
:proxy_headers => @connection.proxy_response_headers,
|
113
|
+
:connection => @connection,
|
114
|
+
:encoding => options.encoding,
|
115
|
+
:request => req
|
116
|
+
)
|
117
|
+
end
|
118
|
+
|
109
119
|
# Verify our request isn't going to be made against another URI
|
110
120
|
def verify_connection!(uri)
|
111
121
|
if default_options.persistent? && uri.origin != default_options.persistent
|
@@ -128,15 +138,11 @@ module HTTP
|
|
128
138
|
def make_request_uri(uri, opts)
|
129
139
|
uri = uri.to_s
|
130
140
|
|
131
|
-
if default_options.persistent? && uri !~ HTTP_OR_HTTPS_RE
|
132
|
-
uri = "#{default_options.persistent}#{uri}"
|
133
|
-
end
|
141
|
+
uri = "#{default_options.persistent}#{uri}" if default_options.persistent? && uri !~ HTTP_OR_HTTPS_RE
|
134
142
|
|
135
143
|
uri = HTTP::URI.parse uri
|
136
144
|
|
137
|
-
if opts.params && !opts.params.empty?
|
138
|
-
uri.query_values = uri.query_values(Array).to_a.concat(opts.params.to_a)
|
139
|
-
end
|
145
|
+
uri.query_values = uri.query_values(Array).to_a.concat(opts.params.to_a) if opts.params && !opts.params.empty?
|
140
146
|
|
141
147
|
# Some proxies (seen on WEBRick) fail if URL has
|
142
148
|
# empty path (e.g. `http://example.com`) while it's RFC-complaint:
|
@@ -160,14 +166,6 @@ module HTTP
|
|
160
166
|
headers[Headers::COOKIE] = cookies
|
161
167
|
end
|
162
168
|
|
163
|
-
if (auto_deflate = opts.feature(:auto_deflate))
|
164
|
-
# We need to delete Content-Length header. It will be set automatically
|
165
|
-
# by HTTP::Request::Writer
|
166
|
-
headers.delete(Headers::CONTENT_LENGTH)
|
167
|
-
|
168
|
-
headers[Headers::CONTENT_ENCODING] = auto_deflate.method
|
169
|
-
end
|
170
|
-
|
171
169
|
headers
|
172
170
|
end
|
173
171
|
|
data/lib/http/connection.rb
CHANGED
@@ -45,8 +45,8 @@ module HTTP
|
|
45
45
|
send_proxy_connect_request(req)
|
46
46
|
start_tls(req, options)
|
47
47
|
reset_timer
|
48
|
-
rescue IOError, SocketError, SystemCallError =>
|
49
|
-
raise ConnectionError, "failed to connect: #{
|
48
|
+
rescue IOError, SocketError, SystemCallError => e
|
49
|
+
raise ConnectionError, "failed to connect: #{e}", e.backtrace
|
50
50
|
end
|
51
51
|
|
52
52
|
# @see (HTTP::Response::Parser#status_code)
|
@@ -93,7 +93,7 @@ module HTTP
|
|
93
93
|
chunk = @parser.read(size)
|
94
94
|
finish_response if finished
|
95
95
|
|
96
|
-
chunk.
|
96
|
+
chunk || "".b
|
97
97
|
end
|
98
98
|
|
99
99
|
# Reads data from socket up until headers are loaded
|
@@ -216,8 +216,8 @@ module HTTP
|
|
216
216
|
elsif value
|
217
217
|
@parser << value
|
218
218
|
end
|
219
|
-
rescue IOError, SocketError, SystemCallError =>
|
220
|
-
raise ConnectionError, "error reading from socket: #{
|
219
|
+
rescue IOError, SocketError, SystemCallError => e
|
220
|
+
raise ConnectionError, "error reading from socket: #{e}", e.backtrace
|
221
221
|
end
|
222
222
|
end
|
223
223
|
end
|