@@ -659,18 +659,39 @@ def finish
659659
660660 private
661661
662- def tcp_socket ( address , port )
663- TCPSocket . open address , port
662+ tcp_socket_parameters = TCPSocket . instance_method ( :initialize ) . parameters
663+ TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT = if tcp_socket_parameters != [ [ :rest ] ]
664+ tcp_socket_parameters . include? ( [ :key , :open_timeout ] )
665+ else
666+ # Use Socket.tcp to find out since there is no parameters information for TCPSocket#initialize
667+ # See discussion in https://github.com/ruby/net-http/pull/224
668+ Socket . method ( :tcp ) . parameters . include? ( [ :key , :open_timeout ] )
669+ end
670+ private_constant :TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
671+
672+ def tcp_socket ( conn_addr , conn_port )
673+ if TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
674+ TCPSocket . open ( conn_addr , conn_port , open_timeout : @open_timeout )
675+ else
676+ Timeout . timeout ( @open_timeout , Net ::OpenTimeout ) {
677+ TCPSocket . open ( conn_addr , conn_port )
678+ }
679+ end
664680 end
665681
666682 def do_start ( helo_domain , user , secret , authtype )
667683 raise IOError , 'SMTP session already started' if @started
668684 if user || secret || authtype
669685 check_auth_args authtype , user , secret
670686 end
671- s = Timeout . timeout ( @open_timeout , Net ::OpenTimeout ) do
672- tcp_socket ( @address , @port )
673- end
687+ s = begin
688+ tcp_socket ( @address , @port )
689+ rescue => e
690+ if ( defined? ( IO ::TimeoutError ) && e . is_a? ( IO ::TimeoutError ) ) || e . is_a? ( Errno ::ETIMEDOUT ) # for compatibility with previous versions
691+ e = Net ::OpenTimeout . new ( e )
692+ end
693+ raise e
694+ end
674695 logging "Connection opened: #{ @address } :#{ @port } "
675696 @socket = new_internet_message_io ( tls? ? tlsconnect ( s , @ssl_context_tls ) : s )
676697 check_response critical { recv_response ( ) }
0 commit comments