<commit_before>unless Excon.mocking?

  module Excon
    class Connection

      def initialize(url)
        @uri = URI.parse(url)
      end

      def request(params)
        begin
          params[:path] ||= ''
          unless params[:path][0..0] == '/'
            params[:path] = "/#{params[:path]}"
          end
          if params[:query] && !params[:query].empty?
            params[:path] << "?#{params[:query]}"
          end
          request = "#{params[:method]} #{params[:path]} HTTP/1.1\r\n"
          params[:headers] ||= {}
          params[:headers]['Host'] = params[:host] || @uri.host
          if params[:body] && !params[:headers]['Content-Length']
            params[:headers]['Content-Length'] = params[:body].length
          end
          for key, value in params[:headers]
            request << "#{key}: #{value}\r\n"
          end
          request << "\r\n"
          connection.write(request)

          if params[:body]
            if params[:body].is_a?(String)
              connection.write(params[:body])
            else
              while chunk = params[:body].read(CHUNK_SIZE)
                connection.write(chunk)
              end
            end
          end

          response = Excon::Response.new
          response.status = connection.readline[9..11].to_i
          while true
            data = connection.readline.chop!
            unless data.empty?
              key, value = data.split(': ')
              response.headers[key] = value
            else
              break
            end
          end

          unless params[:method] == 'HEAD'
            block = if !params[:block] || (params[:expects] && ![*params[:expects]].include?(response.status))
              response.body = ''
              lambda { |chunk| response.body << chunk }
            else
              params[:block]
            end

            if response.headers['Content-Length']
              remaining = response.headers['Content-Length'].to_i
              while remaining > 0
                block.call(connection.read([CHUNK_SIZE, remaining].min))
                remaining -= CHUNK_SIZE
              end
            elsif response.headers['Transfer-Encoding'] == 'chunked'
              while true
                chunk_size = connection.readline.chop!.to_i(16)
                chunk = connection.read(chunk_size + 2).chop! # 2 == "/r/n".length
                if chunk_size > 0
                  block.call(chunk)
                else
                  break
                end
              end
            elsif response.headers['Connection'] == 'close'
              block.call(connection.read)
              Thread.current[:_excon_connection] = nil
            end
          end
        rescue => connection_error
          Thread.current[:_excon_connection] = nil
          raise(connection_error)
        end

        if params[:expects] && ![*params[:expects]].include?(response.status)
          Thread.current[:_excon_connection] = nil
          raise(Excon::Errors.status_error(params, response))
        else
          response
        end

      rescue => request_error
        if params[:idempotent] &&
            (!request_error.is_a?(Excon::Errors::Error) || response.status != 404)
          retries_remaining ||= 4
          retries_remaining -= 1
          if retries_remaining > 0
            retry
          end
        else
          raise(request_error)
        end
      end

      private

      def connection
        if !Thread.current[:_excon_connection] || Thread.current[:_excon_connection].closed?
          Thread.current[:_excon_connection] = establish_connection
        end
        Thread.current[:_excon_connection]
      end

      def establish_connection<commit_msg>one connection per uri per thread rather than just one connection per thread<commit_after>unless Excon.mocking?

  module Excon
    class Connection

      def initialize(url)
        @uri = URI.parse(url)
        Thread.current[:_excon_connections] ||= {}
      end

      def request(params)
        begin
          params[:path] ||= ''
          unless params[:path][0..0] == '/'
            params[:path] = "/#{params[:path]}"
          end
          if params[:query] && !params[:query].empty?
            params[:path] << "?#{params[:query]}"
          end
          request = "#{params[:method]} #{params[:path]} HTTP/1.1\r\n"
          params[:headers] ||= {}
          params[:headers]['Host'] = params[:host] || @uri.host
          if params[:body] && !params[:headers]['Content-Length']
            params[:headers]['Content-Length'] = params[:body].length
          end
          for key, value in params[:headers]
            request << "#{key}: #{value}\r\n"
          end
          request << "\r\n"
          connection.write(request)

          if params[:body]
            if params[:body].is_a?(String)
              connection.write(params[:body])
            else
              while chunk = params[:body].read(CHUNK_SIZE)
                connection.write(chunk)
              end
            end
          end

          response = Excon::Response.new
          response.status = connection.readline[9..11].to_i
          while true
            data = connection.readline.chop!
            unless data.empty?
              key, value = data.split(': ')
              response.headers[key] = value
            else
              break
            end
          end

          unless params[:method] == 'HEAD'
            block = if !params[:block] || (params[:expects] && ![*params[:expects]].include?(response.status))
              response.body = ''
              lambda { |chunk| response.body << chunk }
            else
              params[:block]
            end

            if response.headers['Content-Length']
              remaining = response.headers['Content-Length'].to_i
              while remaining > 0
                block.call(connection.read([CHUNK_SIZE, remaining].min))
                remaining -= CHUNK_SIZE
              end
            elsif response.headers['Transfer-Encoding'] == 'chunked'
              while true
                chunk_size = connection.readline.chop!.to_i(16)
                chunk = connection.read(chunk_size + 2).chop! # 2 == "/r/n".length
                if chunk_size > 0
                  block.call(chunk)
                else
                  break
                end
              end
            elsif response.headers['Connection'] == 'close'
              block.call(connection.read)
              Thread.current[:_excon_connections][@uri.to_s] = nil
            end
          end
        rescue => connection_error
          Thread.current[:_excon_connections][@uri.to_s] = nil
          raise(connection_error)
        end

        if params[:expects] && ![*params[:expects]].include?(response.status)
          Thread.current[:_excon_connections][@uri.to_s] = nil
          raise(Excon::Errors.status_error(params, response))
        else
          response
        end

      rescue => request_error
        if params[:idempotent] &&
            (!request_error.is_a?(Excon::Errors::Error) || response.status != 404)
          retries_remaining ||= 4
          retries_remaining -= 1
          if retries_remaining > 0
            retry
          end
        else
          raise(request_error)
        end
      end

      private

      def connection
        if !Thread.current[:_excon_connections][@uri.to_s] || Thread.current[:_excon_connections][@uri.to_s].closed?
          Thread.current[:_excon_connections][@uri.to_s] = establish_connection
        end
        Thread.current[:_excon_connections][@uri.to_s]
      end

      def establish_connection
{'fraction_non_alphanumeric': 0.11987012987012988, 'fraction_numerical': 0.0049350649350649355, 'mean_word_length': 1.6158288043478262, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 13, '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': '6165173', 'n_tokens_mistral': 2067, 'n_tokens_neox': 1999, 'n_words': 390}