Attempt to concurrently connect to remote IP addresses (#11757)
* Attempt to concurrently connect to remote IP addresses
* Reduce code length to please CodeClimate 🤷
			
			
This commit is contained in:
		
							parent
							
								
									529856a608
								
							
						
					
					
						commit
						1653b58777
					
				
					 1 changed files with 35 additions and 17 deletions
				
			
		| 
						 | 
				
			
			@ -191,6 +191,9 @@ class Request
 | 
			
		|||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        socks = []
 | 
			
		||||
        addr_by_socket = {}
 | 
			
		||||
 | 
			
		||||
        addresses.each do |address|
 | 
			
		||||
          begin
 | 
			
		||||
            check_private_address(address)
 | 
			
		||||
| 
						 | 
				
			
			@ -200,27 +203,42 @@ class Request
 | 
			
		|||
 | 
			
		||||
            sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
 | 
			
		||||
 | 
			
		||||
            begin
 | 
			
		||||
            sock.connect_nonblock(sockaddr)
 | 
			
		||||
 | 
			
		||||
            # If that hasn't raised an exception, we somehow managed to connect
 | 
			
		||||
            # immediately, close pending sockets and return immediately
 | 
			
		||||
            socks.each(&:close)
 | 
			
		||||
            return sock
 | 
			
		||||
          rescue IO::WaitWritable
 | 
			
		||||
              if IO.select(nil, [sock], nil, Request::TIMEOUT[:connect])
 | 
			
		||||
                begin
 | 
			
		||||
                  sock.connect_nonblock(sockaddr)
 | 
			
		||||
                rescue Errno::EISCONN
 | 
			
		||||
                  # Yippee!
 | 
			
		||||
                rescue
 | 
			
		||||
                  sock.close
 | 
			
		||||
                  raise
 | 
			
		||||
                end
 | 
			
		||||
              else
 | 
			
		||||
                sock.close
 | 
			
		||||
                raise HTTP::TimeoutError, "Connect timed out after #{Request::TIMEOUT[:connect]} seconds"
 | 
			
		||||
            socks << sock
 | 
			
		||||
            addr_by_socket[sock] = sockaddr
 | 
			
		||||
          rescue => e
 | 
			
		||||
            outer_e = e
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
            return sock
 | 
			
		||||
        until socks.empty?
 | 
			
		||||
          _, available_socks, = IO.select(nil, socks, nil, Request::TIMEOUT[:connect])
 | 
			
		||||
 | 
			
		||||
          if available_socks.nil?
 | 
			
		||||
            socks.each(&:close)
 | 
			
		||||
            raise HTTP::TimeoutError, "Connect timed out after #{Request::TIMEOUT[:connect]} seconds"
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          available_socks.each do |sock|
 | 
			
		||||
            socks.delete(sock)
 | 
			
		||||
 | 
			
		||||
            begin
 | 
			
		||||
              sock.connect_nonblock(addr_by_socket[sock])
 | 
			
		||||
            rescue Errno::EISCONN
 | 
			
		||||
            rescue => e
 | 
			
		||||
              sock.close
 | 
			
		||||
              outer_e = e
 | 
			
		||||
              next
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
            socks.each(&:close)
 | 
			
		||||
            return sock
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue