excon 0.7.12 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of excon might be problematic. Click here for more details.
- data/README.rdoc +3 -5
- data/changelog.txt +41 -0
- data/excon.gemspec +2 -2
- data/lib/excon/connection.rb +30 -25
- data/lib/excon/constants.rb +1 -1
- data/lib/excon/socket.rb +18 -6
- metadata +60 -87
data/README.rdoc
CHANGED
@@ -71,13 +71,11 @@ You can specify a proxy URL that Excon will use with both HTTP and HTTPS connect
|
|
71
71
|
connection = Excon.new('http://geemus.com', :proxy => 'http://my.proxy:3128')
|
72
72
|
connection.request(:method => 'GET')
|
73
73
|
|
74
|
-
The proxy URL must be fully specified, including scheme (e.g. "http://") and port.
|
74
|
+
The proxy URL must be fully specified, including scheme (e.g. "http://") and port.
|
75
75
|
|
76
|
-
|
76
|
+
Proxy support must be set when establishing a connection object and cannot be overridden in individual requests. Because of this it is unavailable in one-off requests (Excon.get, etc.)
|
77
77
|
|
78
|
-
If "https_proxy" is not set, the value of "http_proxy" will be used for both HTTP and HTTPS connections.
|
79
|
-
|
80
|
-
NOTE: Environment variables will take precedence over a :proxy option that has been specified in code.
|
78
|
+
NOTE: Excon will use the environment variables "http_proxy" and "https_proxy" if they are present. If these variables are set they will take precedence over a :proxy option specified in code. If "https_proxy" is not set, the value of "http_proxy" will be used for both HTTP and HTTPS connections.
|
81
79
|
|
82
80
|
== Stubs
|
83
81
|
|
data/changelog.txt
CHANGED
@@ -1,3 +1,44 @@
|
|
1
|
+
0.8.0 12/12/11
|
2
|
+
==============
|
3
|
+
|
4
|
+
* move mock handler to its own method
|
5
|
+
* better handling around openssl errors
|
6
|
+
* simplify writing by removing buffer
|
7
|
+
|
8
|
+
0.7.12 12/04/11
|
9
|
+
===============
|
10
|
+
|
11
|
+
* revert: explicitly close files after writing
|
12
|
+
|
13
|
+
0.7.11 12/24/11
|
14
|
+
==============
|
15
|
+
|
16
|
+
* rebuild gem broken gemspec with 1.8.x
|
17
|
+
|
18
|
+
0.7.10 12/04/11
|
19
|
+
===============
|
20
|
+
|
21
|
+
* explicitly close files after writing
|
22
|
+
|
23
|
+
0.7.9 11/30/11
|
24
|
+
==============
|
25
|
+
|
26
|
+
* add ability to modify retry limit
|
27
|
+
* use addrinfo to avoid localhost and other IPv6 issues
|
28
|
+
* update gemspec authors to add Dan Peterson and Matt Sanders
|
29
|
+
|
30
|
+
0.7.8 11/24/11
|
31
|
+
==============
|
32
|
+
|
33
|
+
* rebuild gem broken gemspec with 1.8.x
|
34
|
+
|
35
|
+
0.7.7 11/24/11
|
36
|
+
==============
|
37
|
+
|
38
|
+
* setup for travis ci automated testing
|
39
|
+
* fix EOFError
|
40
|
+
* use Socket.getaddrinfo to fix IPv6 issues
|
41
|
+
|
1
42
|
0.7.6 10/04/11
|
2
43
|
==============
|
3
44
|
|
data/excon.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
## If your rubyforge_project name is different, then edit it and comment out
|
14
14
|
## the sub! line in the Rakefile
|
15
15
|
s.name = 'excon'
|
16
|
-
s.version = '0.
|
17
|
-
s.date = '2011-12-
|
16
|
+
s.version = '0.8.0'
|
17
|
+
s.date = '2011-12-12'
|
18
18
|
s.rubyforge_project = 'excon'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
data/lib/excon/connection.rb
CHANGED
@@ -82,31 +82,8 @@ module Excon
|
|
82
82
|
unless params[:mock]
|
83
83
|
socket.params = params
|
84
84
|
else
|
85
|
-
|
86
|
-
|
87
|
-
if (stub.keys - [:headers]).all? {|key| stub[key] == params[key] } &&
|
88
|
-
(!stub.has_key?(:headers) || stub[:headers].keys.all? {|key| stub[:headers][key] == params[:headers][key]})
|
89
|
-
response_attributes = case response
|
90
|
-
when Proc
|
91
|
-
response.call(params)
|
92
|
-
else
|
93
|
-
response
|
94
|
-
end
|
95
|
-
if block_given? && response_attributes.has_key?(:body)
|
96
|
-
body = response_attributes.delete(:body)
|
97
|
-
content_length = remaining = body.bytesize
|
98
|
-
i = 0
|
99
|
-
while i < body.length
|
100
|
-
yield(body[i, CHUNK_SIZE], [remaining - CHUNK_SIZE, 0].max, content_length)
|
101
|
-
remaining -= CHUNK_SIZE
|
102
|
-
i += CHUNK_SIZE
|
103
|
-
end
|
104
|
-
end
|
105
|
-
return Excon::Response.new(response_attributes)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
# if we reach here no stubs matched
|
109
|
-
raise(Excon::Errors::StubNotFound.new('no stubs matched ' << params.inspect))
|
85
|
+
mocked_response = invoke_stub(params, &block)
|
86
|
+
return mocked_response unless mocked_response.nil?
|
110
87
|
end
|
111
88
|
|
112
89
|
# start with "METHOD /path"
|
@@ -215,6 +192,34 @@ module Excon
|
|
215
192
|
raise(request_error)
|
216
193
|
end
|
217
194
|
end
|
195
|
+
|
196
|
+
def invoke_stub(params)
|
197
|
+
for stub, response in Excon.stubs
|
198
|
+
# all specified non-headers params match and no headers were specified or all specified headers match
|
199
|
+
if (stub.keys - [:headers]).all? {|key| stub[key] == params[key] } &&
|
200
|
+
(!stub.has_key?(:headers) || stub[:headers].keys.all? {|key| stub[:headers][key] == params[:headers][key]})
|
201
|
+
response_attributes = case response
|
202
|
+
when Proc
|
203
|
+
response.call(params)
|
204
|
+
else
|
205
|
+
response
|
206
|
+
end
|
207
|
+
if block_given? && response_attributes.has_key?(:body)
|
208
|
+
body = response_attributes.delete(:body)
|
209
|
+
content_length = remaining = body.bytesize
|
210
|
+
i = 0
|
211
|
+
while i < body.length
|
212
|
+
yield(body[i, CHUNK_SIZE], [remaining - CHUNK_SIZE, 0].max, content_length)
|
213
|
+
remaining -= CHUNK_SIZE
|
214
|
+
i += CHUNK_SIZE
|
215
|
+
end
|
216
|
+
end
|
217
|
+
return Excon::Response.new(response_attributes)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
# if we reach here no stubs matched
|
221
|
+
raise(Excon::Errors::StubNotFound.new('no stubs matched ' << params.inspect))
|
222
|
+
end
|
218
223
|
|
219
224
|
def reset
|
220
225
|
(old_socket = sockets.delete(@socket_key)) && old_socket.close
|
data/lib/excon/constants.rb
CHANGED
data/lib/excon/socket.rb
CHANGED
@@ -10,7 +10,7 @@ module Excon
|
|
10
10
|
|
11
11
|
def initialize(params = {}, proxy = nil)
|
12
12
|
@params, @proxy = params, proxy
|
13
|
-
@read_buffer
|
13
|
+
@read_buffer = ''
|
14
14
|
@eof = false
|
15
15
|
|
16
16
|
connect
|
@@ -102,12 +102,11 @@ module Excon
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def write(data)
|
105
|
-
|
106
|
-
until @write_buffer.empty?
|
105
|
+
while true
|
107
106
|
begin
|
108
|
-
|
109
|
-
|
110
|
-
@
|
107
|
+
# I wish that this API accepted a start position, then we wouldn't
|
108
|
+
# have to slice data when there is a short write.
|
109
|
+
written = @socket.write_nonblock(data)
|
111
110
|
rescue OpenSSL::SSL::SSLError => error
|
112
111
|
if error.message == 'write would block'
|
113
112
|
if IO.select(nil, [@socket], nil, @params[:write_timeout])
|
@@ -116,12 +115,25 @@ module Excon
|
|
116
115
|
raise(Excon::Errors::Timeout.new("write timeout reached"))
|
117
116
|
end
|
118
117
|
end
|
118
|
+
|
119
|
+
# If there is an unknown OpenSSL error, don't just swallow
|
120
|
+
# it, raise it out.
|
121
|
+
raise Excon::Errors::SocketError.new(error)
|
119
122
|
rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable
|
120
123
|
if IO.select(nil, [@socket], nil, @params[:write_timeout])
|
121
124
|
retry
|
122
125
|
else
|
123
126
|
raise(Excon::Errors::Timeout.new("write timeout reached"))
|
124
127
|
end
|
128
|
+
else
|
129
|
+
# Fast, common case.
|
130
|
+
return if written == data.size
|
131
|
+
|
132
|
+
# This takes advantage of the fact that most ruby implementations
|
133
|
+
# have Copy-On-Write strings. Thusly why requesting a subrange
|
134
|
+
# of data, we actually don't copy data because the new string
|
135
|
+
# simply references a subrange of the original.
|
136
|
+
data = data[written, data.size]
|
125
137
|
end
|
126
138
|
end
|
127
139
|
end
|
metadata
CHANGED
@@ -1,88 +1,69 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: excon
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 7
|
8
|
-
- 12
|
9
|
-
segments_generated: true
|
10
|
-
version: 0.7.12
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.0
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- dpiddy (Dan Peterson)
|
14
9
|
- geemus (Wesley Beary)
|
15
10
|
- nextmat (Matt Sanders)
|
16
11
|
autorequire:
|
17
12
|
bindir: bin
|
18
13
|
cert_chain: []
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
dependencies:
|
23
|
-
- !ruby/object:Gem::Dependency
|
24
|
-
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
|
-
requirements:
|
26
|
-
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
segments:
|
29
|
-
- 0
|
30
|
-
segments_generated: true
|
31
|
-
version: "0"
|
32
|
-
requirement: *id001
|
14
|
+
date: 2011-12-12 00:00:00.000000000Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
33
17
|
name: open4
|
34
|
-
|
18
|
+
requirement: &5046310 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '0'
|
35
24
|
type: :development
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
version_requirements: &id002 !ruby/object:Gem::Requirement
|
38
|
-
requirements:
|
39
|
-
- - ">="
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
segments:
|
42
|
-
- 0
|
43
|
-
segments_generated: true
|
44
|
-
version: "0"
|
45
|
-
requirement: *id002
|
46
|
-
name: rake
|
47
25
|
prerelease: false
|
26
|
+
version_requirements: *5046310
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: &5046020 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
48
35
|
type: :development
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
version_requirements: &id003 !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
segments:
|
55
|
-
- 0
|
56
|
-
- 2
|
57
|
-
- 0
|
58
|
-
segments_generated: true
|
59
|
-
version: 0.2.0
|
60
|
-
requirement: *id003
|
61
|
-
name: shindo
|
62
36
|
prerelease: false
|
37
|
+
version_requirements: *5046020
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: shindo
|
40
|
+
requirement: &5045670 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - =
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.2.0
|
63
46
|
type: :development
|
64
|
-
- !ruby/object:Gem::Dependency
|
65
|
-
version_requirements: &id004 !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - ">="
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
segments:
|
70
|
-
- 0
|
71
|
-
segments_generated: true
|
72
|
-
version: "0"
|
73
|
-
requirement: *id004
|
74
|
-
name: sinatra
|
75
47
|
prerelease: false
|
48
|
+
version_requirements: *5045670
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: sinatra
|
51
|
+
requirement: &5045400 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
76
57
|
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: *5045400
|
77
60
|
description: EXtended http(s) CONnections
|
78
61
|
email: geemus@gmail.com
|
79
62
|
executables: []
|
80
|
-
|
81
63
|
extensions: []
|
82
|
-
|
83
|
-
extra_rdoc_files:
|
64
|
+
extra_rdoc_files:
|
84
65
|
- README.rdoc
|
85
|
-
files:
|
66
|
+
files:
|
86
67
|
- Gemfile
|
87
68
|
- README.rdoc
|
88
69
|
- Rakefile
|
@@ -130,37 +111,29 @@ files:
|
|
130
111
|
- tests/stub_tests.rb
|
131
112
|
- tests/test_helper.rb
|
132
113
|
- tests/thread_safety_tests.rb
|
133
|
-
has_rdoc: true
|
134
114
|
homepage: https://github.com/geemus/excon
|
135
115
|
licenses: []
|
136
|
-
|
137
116
|
post_install_message:
|
138
|
-
rdoc_options:
|
117
|
+
rdoc_options:
|
139
118
|
- --charset=UTF-8
|
140
|
-
require_paths:
|
119
|
+
require_paths:
|
141
120
|
- lib
|
142
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
segments:
|
155
|
-
- 0
|
156
|
-
segments_generated: true
|
157
|
-
version: "0"
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ! '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ! '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
158
133
|
requirements: []
|
159
|
-
|
160
134
|
rubyforge_project: excon
|
161
|
-
rubygems_version: 1.
|
135
|
+
rubygems_version: 1.8.6
|
162
136
|
signing_key:
|
163
137
|
specification_version: 2
|
164
138
|
summary: speed, persistence, http(s)
|
165
139
|
test_files: []
|
166
|
-
|