Issue #14466 has been updated by jeremyevans0 (Jeremy Evans).

Assignee set to naruse (Yui NARUSE)
Status changed from Open to Assigned
File net-http-epipe.patch added

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.



----------------------------------------
Bug #14466: Errno::ECONNRESET or Errno::EPIPE raised instead of HTTPResponse returned when POSTing with large body
https://bugs.ruby-lang.org/issues/14466#change-78757

* Author: sk (SK Liew)
* Status: Assigned
* Priority: Normal
* Assignee: naruse (Yui NARUSE)
* Target version: 
* ruby -v: ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux], ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
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:

1. In a terminal, run `ruby -run -e httpd -- -p 3000 .` to run a HTTP webserver.
2. In another terminal, run the code below:

~~~ ruby
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--------------------------------
net-http-epipe.patch (1.85 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>