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
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        socks = []
 | 
				
			||||||
 | 
					        addr_by_socket = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        addresses.each do |address|
 | 
					        addresses.each do |address|
 | 
				
			||||||
          begin
 | 
					          begin
 | 
				
			||||||
            check_private_address(address)
 | 
					            check_private_address(address)
 | 
				
			||||||
| 
						 | 
					@ -200,30 +203,45 @@ class Request
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
 | 
					            sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            begin
 | 
					            sock.connect_nonblock(sockaddr)
 | 
				
			||||||
              sock.connect_nonblock(sockaddr)
 | 
					 | 
				
			||||||
            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"
 | 
					 | 
				
			||||||
              end
 | 
					 | 
				
			||||||
            end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # If that hasn't raised an exception, we somehow managed to connect
 | 
				
			||||||
 | 
					            # immediately, close pending sockets and return immediately
 | 
				
			||||||
 | 
					            socks.each(&:close)
 | 
				
			||||||
            return sock
 | 
					            return sock
 | 
				
			||||||
 | 
					          rescue IO::WaitWritable
 | 
				
			||||||
 | 
					            socks << sock
 | 
				
			||||||
 | 
					            addr_by_socket[sock] = sockaddr
 | 
				
			||||||
          rescue => e
 | 
					          rescue => e
 | 
				
			||||||
            outer_e = e
 | 
					            outer_e = e
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if outer_e
 | 
					        if outer_e
 | 
				
			||||||
          raise outer_e
 | 
					          raise outer_e
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue