Sha256: 5dff77e25c063e5adf63b09c5758e1565ff888d56ccc07fac29f89b4f9e08476

Contents?: true

Size: 1.8 KB

Versions: 22

Compression:

Stored size: 1.8 KB

Contents

require 'uri'

require "openid/extras"

module OpenID

  module URINorm
    public
    def URINorm.urinorm(uri)
      uri = URI.parse(uri)

      raise URI::InvalidURIError.new('no scheme') unless uri.scheme
      uri.scheme = uri.scheme.downcase
      unless ['http','https'].member?(uri.scheme)
        raise URI::InvalidURIError.new('Not an HTTP or HTTPS URI')
      end

      raise URI::InvalidURIError.new('no host') unless uri.host
      uri.host = uri.host.downcase

      uri.path = remove_dot_segments(uri.path)
      uri.path = '/' if uri.path.length == 0

      uri = uri.normalize.to_s
      uri = uri.gsub(PERCENT_ESCAPE_RE) {
        sub = $&[1..2].to_i(16).chr
        reserved(sub) ? $&.upcase : sub
      }

      return uri
    end

    private
    RESERVED_RE = /[A-Za-z0-9._~-]/
    PERCENT_ESCAPE_RE = /%[0-9a-zA-Z]{2}/

    def URINorm.reserved(chr)
      not RESERVED_RE =~ chr
    end

    def URINorm.remove_dot_segments(path)
      result_segments = []

      while path.length > 0
        if path.starts_with?('../')
          path = path[3..-1]
        elsif path.starts_with?('./')
          path = path[2..-1]
        elsif path.starts_with?('/./')
          path = path[2..-1]
        elsif path == '/.'
          path = '/'
        elsif path.starts_with?('/../')
          path = path[3..-1]
          result_segments.pop if result_segments.length > 0
        elsif path == '/..'
          path = '/'
          result_segments.pop if result_segments.length > 0
        elsif path == '..' or path == '.'
          path = ''
        else
          i = 0
          i = 1 if path[0].chr == '/'
          i = path.index('/', i)
          i = path.length if i.nil?
          result_segments << path[0...i]
          path = path[i..-1]
        end
      end

      return result_segments.join('')
    end
  end

end

Version data entries

22 entries across 22 versions & 4 rubygems

Version Path
ruby-openid-2.6.0 lib/openid/urinorm.rb
pelle-ruby-openid-2.1.8 lib/openid/urinorm.rb
ruby-openid-2.5.0 lib/openid/urinorm.rb
ruby-openid-2.4.0 lib/openid/urinorm.rb
ruby-openid-2.3.0 lib/openid/urinorm.rb
ruby-openid-2.2.3 lib/openid/urinorm.rb
ruby-openid-2.2.2 lib/openid/urinorm.rb
ruby-openid-2.2.1 lib/openid/urinorm.rb
ruby-openid-2.2.0 lib/openid/urinorm.rb
entp-ruby-openid-2.2 lib/openid/urinorm.rb
nov-ruby-openid-2.1.9 lib/openid/urinorm.rb
ruby-openid-2.1.8 lib/openid/urinorm.rb
pelle-ruby-openid-2.1.9 lib/openid/urinorm.rb
ruby-openid-2.1.7 lib/openid/urinorm.rb
ruby-openid-2.0.1 lib/openid/urinorm.rb
ruby-openid-2.0.2 lib/openid/urinorm.rb
ruby-openid-2.0.3 lib/openid/urinorm.rb
ruby-openid-2.1.6 lib/openid/urinorm.rb
ruby-openid-2.1.5 lib/openid/urinorm.rb
ruby-openid-2.1.2 lib/openid/urinorm.rb