class URI class InvalidURIError < StandardError; end def self.parse(str) x = /^([a-z]+):\/\/([a-z0-9-.]+)(:([0-9]+))?(\/([^?]*))?(\?(.*))?$/.match(str) raise InvalidURIError unless x scheme, host, _, port, path, _, _, query = x.captures self.new(scheme:, host:, port:, path:, query:) end def self.decode_www_form(query) query.split('&').map{ k, v = it.split('=', 2) v = v.gsub(/%[0-9A-F][0-9A-F]/i){it[1,2].to_i(16).chr} [k, v] } end def self.encode_www_form(ary) ary.map{|k,v| "#{k}=#{v}"}.join('&') end attr_accessor :scheme, :host, :port, :path, :query def initialize(scheme: nil, host: nil, port: nil, path: nil, query: nil) @scheme = scheme @host = host @port = port @path = path.to_s @query = query end def to_s s = "#{scheme}://#{host}" s += ":#{port}" if port s += "/" s += path.sub(/^\/+/, '') s += "?#{query}" if query s end end