Skip to content

Commit

Permalink
Merge pull request httprb#473 from janko-m/handle-early-responses
Browse files Browse the repository at this point in the history
Handle early responses
  • Loading branch information
ixti authored May 25, 2018
2 parents 2bd7f84 + 1c3d6a0 commit 55ca249
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
26 changes: 19 additions & 7 deletions lib/http/request/writer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,32 @@ def join_headers
@request_header.join(CRLF) + CRLF * 2
end

# Writes HTTP request data into the socket.
def send_request
# It's important to send the request in a single write call when
# possible in order to play nicely with Nagle's algorithm. Making
# two writes in a row triggers a pathological case where Nagle is
# expecting a third write that never happens.
each_chunk { |chunk| write chunk }
rescue Errno::EPIPE
# server doesn't need any more data
nil
end

# Yields chunks of request data that should be sent to the socket.
#
# It's important to send the request in a single write call when possible
# in order to play nicely with Nagle's algorithm. Making two writes in a
# row triggers a pathological case where Nagle is expecting a third write
# that never happens.
def each_chunk
data = join_headers

@body.each do |chunk|
data << encode_chunk(chunk)
write(data)
yield data
data.clear
end

write(data) unless data.empty?
yield data unless data.empty?

write(CHUNKED_END) if chunked?
yield CHUNKED_END if chunked?
end

# Returns the chunk encoded for to the specified "Transfer-Encoding" header.
Expand All @@ -100,6 +110,8 @@ def write(data)
break unless data.bytesize > length
data = data.byteslice(length..-1)
end
rescue Errno::EPIPE
raise
rescue IOError, SocketError, SystemCallError => ex
raise ConnectionError, "error writing to socket: #{ex}", ex.backtrace
end
Expand Down
12 changes: 11 additions & 1 deletion spec/lib/http/request/writer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,21 @@
end
end

context "when writing to socket raises an exception" do
context "when server won't accept any more data" do
before do
expect(io).to receive(:write).and_raise(Errno::EPIPE)
end

it "aborts silently" do
writer.stream
end
end

context "when writing to socket raises an exception" do
before do
expect(io).to receive(:write).and_raise(Errno::ECONNRESET)
end

it "raises a ConnectionError" do
expect { writer.stream }.to raise_error(HTTP::ConnectionError)
end
Expand Down

0 comments on commit 55ca249

Please sign in to comment.