Skip to content

Commit

Permalink
fix for leftover data with interrupted persistent connections
Browse files Browse the repository at this point in the history
Thanks to @pje for disclosure, initial patch, and input
  • Loading branch information
geemus committed Dec 12, 2019
1 parent f8de8cf commit ccb57d7
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
8 changes: 8 additions & 0 deletions lib/excon/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ def request(params={}, &block)

datum[:connection] = self

# cleanup data left behind on persistent connection after interrupt
if datum[:persistent] && !@persistent_socket_reusable
reset
end

datum[:stack] = datum[:middlewares].map do |middleware|
lambda {|stack| middleware.new(stack)}
end.reverse.inject(self) do |middlewares, middleware|
Expand All @@ -270,7 +275,9 @@ def request(params={}, &block)
datum = datum[:stack].request_call(datum)

unless datum[:pipeline]
@persistent_socket_reusable = false
datum = response(datum)
@persistent_socket_reusable = true

if datum[:persistent]
if key = datum[:response][:headers].keys.detect {|k| k.casecmp('Connection') == 0 }
Expand Down Expand Up @@ -344,6 +351,7 @@ def reset
if old_socket = sockets.delete(@socket_key)
old_socket.close rescue nil
end
@persistent_socket_reusable = true
end

# Generate HTTP request verb methods
Expand Down
23 changes: 23 additions & 0 deletions tests/connection_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,29 @@
connection.send(:socket) # creates/connects socket
connection.data[:remote_ip]
end

tests("persistent connections") do
connection = Excon.new('http://127.0.0.1:9292', persistent: true)

response_body = connection.request(path: '/foo', method: 'get').body
test("successful uninterrupted request") do
connection.request(path: '/foo', method: 'get').body == 'foo'
end

begin
# simulate an interrupted connection which leaves data behind
Timeout::timeout(0.0000000001) do
connection.request(path: '/foo', method: 'get')
end
rescue Timeout::Error
nil
end

test("resets connection after interrupt") do
response = connection.request(path: '/bar', method: 'get')
response.body == 'bar'
end
end
end

tests("inspect redaction") do
Expand Down
8 changes: 8 additions & 0 deletions tests/rackups/basic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ class Basic < Sinatra::Base
echo
end

get('/foo') do
'foo'
end

get('/bar') do
'bar'
end

private

def echo
Expand Down

0 comments on commit ccb57d7

Please sign in to comment.