<commit_before>require "socket"
require "thread"

begin
  require "openssl"
rescue LoadError => le
  puts "Could not load OpenSSL"
end

require "bunny/exceptions"
require "bunny/socket"

module Bunny
  class Transport

    #
    # API
    #

    DEFAULT_CONNECTION_TIMEOUT = 5.0
    # same as in RabbitMQ Java client
    DEFAULT_TLS_PROTOCOL       = "SSLv3"


    attr_reader :session, :host, :port, :socket, :connect_timeout, :read_write_timeout, :disconnect_timeout

    def initialize(session, host, port, opts)
      @session = session
      @host    = host
      @port    = port
      @opts    = opts

      @tls_enabled           = tls_enabled?(opts)
      @tls_certificate_path  = tls_certificate_path_from(opts)
      @tls_key_path          = tls_key_path_from(opts)
      @tls_certificate       = opts[:tls_certificate] || opts[:ssl_cert_string]
      @tls_key               = opts[:tls_key]         || opts[:ssl_key_string]
      @tls_certificate_store = opts[:tls_certificate_store]
      @verify_peer           = opts[:verify_ssl] || opts[:verify_peer]

      @read_write_timeout = opts[:socket_timeout] || 1
      @read_write_timeout = nil if @read_write_timeout == 0
      @connect_timeout    = self.timeout_from(opts)
      @connect_timeout    = nil if @connect_timeout == 0
      @disconnect_timeout = @read_write_timeout || @connect_timeout

      initialize_socket
      connect
    end


    def hostname
      @host
    end

    def uses_tls?
      @tls_enabled
    end
    alias tls? uses_tls?

    def uses_ssl?
      @tls_enabled
    end
    alias ssl? uses_ssl?


    def connect
      if uses_ssl?
        @socket.connect
        @socket.post_connection_check(host) if uses_tls? && @verify_peer
      else
        # no-op
      end
    end


    # Writes data to the socket. If read/write timeout was specified, Bunny::ClientTimeout will be raised
    # if the operation times out.
    #
    # @raise [ClientTimeout]
    def write(data)
      begin
        raise Bunny::ConnectionError.new("No connection: socket is nil. ", @host, @port) if !@socket
        if @read_write_timeout
          Bunny::Timer.timeout(@read_write_timeout, Bunny::ClientTimeout) do
            if open?
              @socket.write(data)
              @socket.flush
            end
          end
        else
          if open?
            @socket.write(data)
            @socket.flush
          end
        end
      rescue Errno::EPIPE, Errno::EAGAIN, Bunny::ClientTimeout, Bunny::ConnectionError, IOError => e
        close

        @session.handle_network_failure(e)
      end
    end
    alias send_raw write

    # Writes data to the socket without timeout checks
    def write_without_timeout(data)
      begin
        raise Bunny::ConnectionError.new("No connection: socket is nil. ", @host, @port) if !@socket
        @socket.write(data)
      rescue Errno::EPIPE, Errno::EAGAIN, Bunny::ClientTimeout, Bunny::ConnectionError, IOError => e
        close

        @session.handle_network_failure(e)
      end
    end

    def close(reason = nil)
      @socket.close if @socket and not @socket.closed?
      @socket   = nil
    end

    def open?
      !@socket.nil? && !@socket.closed?
    end

    def closed?
      !open?
    end

    def flush
      @socket.flush if @socket
    end

    def read_fully(*args)
      @socket.read_fully(*args)<commit_msg>Respect autorecovery setting in Transport<commit_after>require "socket"
require "thread"

begin
  require "openssl"
rescue LoadError => le
  puts "Could not load OpenSSL"
end

require "bunny/exceptions"
require "bunny/socket"

module Bunny
  class Transport

    #
    # API
    #

    DEFAULT_CONNECTION_TIMEOUT = 5.0
    # same as in RabbitMQ Java client
    DEFAULT_TLS_PROTOCOL       = "SSLv3"


    attr_reader :session, :host, :port, :socket, :connect_timeout, :read_write_timeout, :disconnect_timeout

    def initialize(session, host, port, opts)
      @session        = session
      @session_thread = opts[:session_thread]
      @host    = host
      @port    = port
      @opts    = opts

      @tls_enabled           = tls_enabled?(opts)
      @tls_certificate_path  = tls_certificate_path_from(opts)
      @tls_key_path          = tls_key_path_from(opts)
      @tls_certificate       = opts[:tls_certificate] || opts[:ssl_cert_string]
      @tls_key               = opts[:tls_key]         || opts[:ssl_key_string]
      @tls_certificate_store = opts[:tls_certificate_store]
      @verify_peer           = opts[:verify_ssl] || opts[:verify_peer]

      @read_write_timeout = opts[:socket_timeout] || 3
      @read_write_timeout = nil if @read_write_timeout == 0
      @connect_timeout    = self.timeout_from(opts)
      @connect_timeout    = nil if @connect_timeout == 0
      @disconnect_timeout = @read_write_timeout || @connect_timeout

      initialize_socket
      connect
    end


    def hostname
      @host
    end

    def uses_tls?
      @tls_enabled
    end
    alias tls? uses_tls?

    def uses_ssl?
      @tls_enabled
    end
    alias ssl? uses_ssl?


    def connect
      if uses_ssl?
        @socket.connect
        @socket.post_connection_check(host) if uses_tls? && @verify_peer
      else
        # no-op
      end
    end


    # Writes data to the socket. If read/write timeout was specified, Bunny::ClientTimeout will be raised
    # if the operation times out.
    #
    # @raise [ClientTimeout]
    def write(data)
      begin
        if @read_write_timeout
          Bunny::Timer.timeout(@read_write_timeout, Bunny::ClientTimeout) do
            if open?
              @socket.write(data)
              @socket.flush
            end
          end
        else
          if open?
            @socket.write(data)
            @socket.flush
          end
        end
      rescue SystemCallError, Bunny::ClientTimeout, Bunny::ConnectionError, IOError => e
        close

        if @session.automatically_recover?
          @session.handle_network_failure(e)
        else
          @session_thread.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
        end
      end
    end
    alias send_raw write

    # Writes data to the socket without timeout checks
    def write_without_timeout(data)
      begin
        @socket.write(data)
      rescue SystemCallError, Bunny::ConnectionError, IOError => e
        close

        if @session.automatically_recover?
          @session.handle_network_failure(e)
        else
          @session_thread.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
        end
      end
    end

    def close(reason = nil)
      @socket.close unless @socket.closed?
    end

    def open?
      !@socket.closed?
    end

    def closed?
      !open?
    end

    def flush
      @socket.flush if @socket
    end

    def read_fully(*args)
      @socket.read_fully(*args)
{'fraction_non_alphanumeric': 0.08644314868804664, 'fraction_numerical': 0.001749271137026239, 'mean_word_length': 2.247042120208235, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5487134', 'n_tokens_mistral': 2120, 'n_tokens_neox': 2059, 'n_words': 504}