<commit_before>require 'hmac-sha2'

module Rack
  class UrlAuth
    class Signer
      attr_reader :secret

      def initialize(secret)
        @secret = secret
      end

      def sign(message)
        HMAC::SHA256.hexdigest secret, message
      end

      def verify(message, signature)
        actual   = Digest::SHA1.hexdigest sign(message)
        expected = Digest::SHA1.hexdigest signature
        actual == expected
      end

      def sign_url(url, method)
        purl  = URI.parse url
        query = Rack::Utils.parse_query purl.query
        query.merge! 'signature' => sign(method.to_s.downcase + url)

        build_url purl, query
      end

      def verify_url(url, method)
        purl      = URI.parse url
        query     = Rack::Utils.parse_query(purl.query)
        signature = query.delete('signature').to_s

        verify method.to_s.downcase + build_url(purl, query), signature
      end

      private
      def build_url(purl, query)
        query    = Rack::Utils.build_query(query)

        unless purl.scheme
          raise(ArgumentError, 'URI protocol must be provided')
        end

        url_ary = [purl.scheme, '://', purl.host]
        url_ary.push( ':', purl.port ) unless [80, 443].include?(purl.port)
        url_ary.push( purl.path )
        url_ary.push( '?', query ) unless query.empty?
        url_ary.join
      end
    end
  end
end
<commit_msg>don't append : after host if port for parsed url is nil<commit_after>require 'hmac-sha2'

module Rack
  class UrlAuth
    class Signer
      attr_reader :secret

      def initialize(secret)
        @secret = secret
      end

      def sign(message)
        HMAC::SHA256.hexdigest secret, message
      end

      def verify(message, signature)
        actual   = Digest::SHA1.hexdigest sign(message)
        expected = Digest::SHA1.hexdigest signature
        actual == expected
      end

      def sign_url(url, method)
        purl  = URI.parse url
        query = Rack::Utils.parse_query purl.query
        query.merge! 'signature' => sign(method.to_s.downcase + url)

        build_url purl, query
      end

      def verify_url(url, method)
        purl      = URI.parse url
        query     = Rack::Utils.parse_query(purl.query)
        signature = query.delete('signature').to_s

        verify method.to_s.downcase + build_url(purl, query), signature
      end

      private
      def build_url(purl, query)
        query    = Rack::Utils.build_query(query)

        unless purl.scheme
          raise(ArgumentError, 'URI protocol must be provided')
        end

        url_ary = [purl.scheme, '://', purl.host]
        url_ary.push( ':', purl.port ) unless [80, 443, nil].include?(purl.port)
        url_ary.push( purl.path )
        url_ary.push( '?', query ) unless query.empty?
        url_ary.join
      end
    end
  end
end

{'fraction_non_alphanumeric': 0.09736379613356766, 'fraction_numerical': 0.00773286467486819, 'mean_word_length': 2.103598691384951, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '4982161', 'n_tokens_mistral': 912, 'n_tokens_neox': 872, 'n_words': 211}