Project

General

Profile

Bug #6001 ยป net.http.retry_errors.2.patch

Improved patch - separates open from read errors - drbrain (Eric Hodel), 02/25/2012 05:04 AM

View differences:

lib/net/http.rb (working copy)
360 360
  #
361 361
  class HTTP < Protocol
362 362

  
363
    class OpenTimeout < Timeout::Error
364
    end
365

  
363 366
    # :stopdoc:
364 367
    Revision = %q$Revision$.split[1]
365 368
    HTTPVersion = '1.1'
......
788 791

  
789 792
    def connect
790 793
      D "opening connection to #{conn_address()}..."
791
      s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) }
794
      s = timeout(@open_timeout, OpenTimeout) {
795
        TCPSocket.open(conn_address(), conn_port())
796
      }
792 797
      D "opened"
793 798
      if use_ssl?
794 799
        ssl_parameters = Hash.new
......
824 829
          end
825 830
          # Server Name Indication (SNI) RFC 3546
826 831
          s.hostname = @address if s.respond_to? :hostname=
827
          timeout(@open_timeout) { s.connect }
832
          timeout(@open_timeout, OpenTimeout) { s.connect }
828 833
          if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
829 834
            s.post_connection_check(@address)
830 835
          end
......
1355 1360
          }
1356 1361
          res
1357 1362
        }
1358
        end_transport req, res
1359
        res
1360
      rescue EOFError, Errno::ECONNRESET => exception
1363
      rescue IOError, EOFError,
1364
             Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPIPE,
1365
             OpenSSL::SSL::SSLError, Timeout::Error => exception
1366
        raise if OpenTimeout === exception
1367

  
1361 1368
        if count == 0 && IDEMPOTENT_METHODS_.include?(req.method)
1362 1369
          count += 1
1363 1370
          @socket.close if @socket and not @socket.closed?
......
1367 1374
        D "Conn close because of error #{exception}"
1368 1375
        @socket.close if @socket and not @socket.closed?
1369 1376
        raise
1370
      rescue => exception
1371
        D "Conn close because of error #{exception}"
1372
        @socket.close if @socket and not @socket.closed?
1373
        raise exception
1374 1377
      end
1378

  
1379
      end_transport req, res
1380
      res
1381
    rescue => exception
1382
      D "Conn close because of error #{exception}"
1383
      @socket.close if @socket and not @socket.closed?
1384
      raise exception
1375 1385
    end
1376 1386

  
1377 1387
    def begin_transport(req)
test/net/http/test_http.rb (working copy)
195 195
  def test_timeout_during_HTTP_session
196 196
    bug4246 = "expected the HTTP session to have timed out but have not. c.f. [ruby-core:34203]"
197 197

  
198
    # listen for connections... but deliberately do not complete SSL handshake
198
    # listen for connections... but deliberately do not read
199 199
    TCPServer.open('localhost', 0) {|server|
200 200
      port = server.addr[1]
201 201

  
202 202
      conn = Net::HTTP.new('localhost', port)
203
      conn.read_timeout = 1
204
      conn.open_timeout = 1
203
      conn.read_timeout = 0.01
204
      conn.open_timeout = 0.01
205 205

  
206 206
      th = Thread.new do
207 207
        assert_raise(Timeout::Error) {
......
598 598
      assert_kind_of Net::HTTPResponse, res
599 599
      assert_kind_of String, res.body
600 600
      sleep 1.5
601
      assert_nothing_raised {
602
        res = http.get('/')
603
      }
601
      res = http.get('/')
604 602
      assert_kind_of Net::HTTPResponse, res
605 603
      assert_kind_of String, res.body
606 604
    }
607 605
  end
608 606

  
609
  def test_keep_alive_EOF
607
  def test_keep_alive_server_close
610 608
    def @server.run(sock)
611 609
      sock.close
612 610
    end
613 611

  
614 612
    start {|http|
615
      assert_raises(EOFError) {
613
      assert_raises(IOError) {
616 614
        res = http.get('/')
617 615
      }
618 616
    }