Skip to content

Instantly share code, notes, and snippets.

@zernel
Created August 25, 2017 08:20
Show Gist options
  • Save zernel/0f10c71f5a9e044653c1a65c6c5ad697 to your computer and use it in GitHub Desktop.
Save zernel/0f10c71f5a9e044653c1a65c6c5ad697 to your computer and use it in GitHub Desktop.
smart_uri.rb
# Why do we need KudeURI? Because the URI.join method doing something stupid:
#
# URI.join('http://example.com/subpath', 'hello', '?token=secret')
# => “http://example.com/hello?token=secret”
#
# But what I expected is “http://example.com/subpath/hello?token=secret", the subpath is gone.
# By using SmartURI, you can handle the case above gracefully:
#
# SmartURI.join('http://example.com/subpath', 'hello', query: { token: secret })
# => "http://example.com/subpath/hello?token=secret"
require 'uri'
module SmartURI
SEPARATOR = '/'
def self.join(*paths, query: nil)
paths = paths.compact.reject(&:empty?)
last = paths.length - 1
url = paths.each_with_index.map { |path, index|
_expand(path, index, last)
}.join
if query.nil?
return url
elsif query.is_a? Hash
return url + "?#{URI.encode_www_form(query.to_a)}"
else
raise "Unexpected input type for query: #{query}, it should be a hash."
end
end
def self._expand(path, current, last)
if path.starts_with?(SEPARATOR) && current != 0
path = path[1..-1]
end
unless path.ends_with?(SEPARATOR) || current == last
path = [path, SEPARATOR]
end
path
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment