Bug #14466
closedErrno::ECONNRESET or Errno::EPIPE raised instead of HTTPResponse returned when POSTing with large body
Description
Using net/http
, when trying to POST to an endpoint with a large body, Errno::ECONNRESET or Errno::EPIPE would be raised.
How to reproduce:
- In a terminal, run
ruby -run -e httpd -- -p 3000 .
to run a HTTP webserver. - In another terminal, run the code below:
require 'net/http'
def post_with_size(dest_url, size)
string_to_send = ' ' * size
uri_to_post = URI(dest_url)
request = Net::HTTP::Post.new(uri_to_post)
request.body = string_to_send
http_client = Net::HTTP.new(uri_to_post.host, uri_to_post.port)
http_client.use_ssl = (uri_to_post.scheme == 'https')
response = http_client.request(request)
puts response.body
puts response.code
puts response
end
dest_url = 'http://localhost:3000'
size = 6000000
post_with_size(dest_url, size)
Expected: HTTPResponse with status code of 404.
Observed: Errno::ECONNRESET or Errno::EPIPE error.
Files
Updated by carl.hoerberg (Carl Hörberg) almost 7 years ago
sk (SK Liew) wrote:
Expected: HTTPResponse with status code of 404.
Observed: Errno::ECONNRESET or Errno::EPIPE error.
are you sure it's not the server that's aborting the connection before returning a 404? use eg. wireshark to confirm.
Updated by sk (SK Liew) almost 7 years ago
I have just confirmed with wireshark that a 404 is returned before the connection aborts.
Updated by jeremyevans0 (Jeremy Evans) over 5 years ago
- File net-http-epipe.patch net-http-epipe.patch added
- Status changed from Open to Assigned
- Assignee set to naruse (Yui NARUSE)
I tried this example against an nginx instance, and received normal HTTP error codes (413 or 404 depending on payload size). However, on some other webservers (OpenBSD httpd and Webrick), I did see EPIPE failures in write_nonblock. Ignoring Errno::EPIPE when sending the request allows the request to complete and return results for those webservers. Attached is a patch that does that.
I don't know about handling Errno::ECONNRESET. That implies the socket is no longer usable and you should not be able to read from it. I wasn't able to trigger that condition in the webservers I tested, and don't feel comfortable trying to ignore it as well.
Updated by jeremyevans (Jeremy Evans) about 5 years ago
- Status changed from Assigned to Closed
Applied in changeset git|2b6a9f3a1ffcdb00bf89798979d475c6d189d419.
Ignore Errno::EPIPE when sending requests in net/http
An EPIPE when sending the request should be ignored. Even if you
cannot write more data, you may still be able to read the server's
response.
Fixes [Bug #14466]