class IndieAuthDiscovery::URL
Canonicalization for IndieAuth client and user profile URLs.
Constants
- FARADAY_ERRORS
- PERMANENT_REDIRECTS
Attributes
canonical_url[R]
original_url[R]
redirects[R]
Public Class Methods
canonicalize(original_url)
click to toggle source
# File lib/indieauth_discovery/url.rb, line 20 def self.canonicalize(original_url) url = new(original_url) url.canonicalize url end
new(original_url)
click to toggle source
# File lib/indieauth_discovery/url.rb, line 14 def initialize(original_url) @original_url = original_url.to_s @canonical_url = original_url.to_s @redirects = [] end
Public Instance Methods
canonicalize()
click to toggle source
Canonicalizes and verifies the URL
.
@see indieauth.spec.indieweb.org/#user-profile-url @see indieauth.spec.indieweb.org/#client-identifier
# File lib/indieauth_discovery/url.rb, line 30 def canonicalize canonical = normalize_url(original_url) canonical, verify_response = verify_url(canonical) canonical = ensure_path(canonical) canonical = follow_redirects(canonical, verify_response) @canonical_url = canonical rescue URI::InvalidURIError, *FARADAY_ERRORS raise_invalid_url_error(original_url) end
to_s()
click to toggle source
Returns the canonical URL
as a string.
# File lib/indieauth_discovery/url.rb, line 42 def to_s @canonical_url end
to_uri()
click to toggle source
Returns the canonical URL
as a URI.
# File lib/indieauth_discovery/url.rb, line 47 def to_uri URI.parse(@canonical_url) end
Private Instance Methods
check_url?(uri)
click to toggle source
# File lib/indieauth_discovery/url.rb, line 82 def check_url?(uri) response = Faraday.head(uri) return false unless response.status < 400 response rescue *FARADAY_ERRORS nil end
ensure_path(uri)
click to toggle source
# File lib/indieauth_discovery/url.rb, line 91 def ensure_path(uri) return uri unless URI.parse(uri).path == '' "#{uri}/" end
follow_redirects(uri, response)
click to toggle source
@see indieauth.spec.indieweb.org/#redirect-examples
# File lib/indieauth_discovery/url.rb, line 98 def follow_redirects(uri, response) return uri unless [300, 301, 302, 303, 304, 307, 308].include?(response.status) redirector(uri).head redirects.each do |redirect| status = redirect[:status] break unless PERMANENT_REDIRECTS.include?(status) uri = redirect[:url] if PERMANENT_REDIRECTS.include?(status) end uri end
http_uri?(uri)
click to toggle source
# File lib/indieauth_discovery/url.rb, line 78 def http_uri?(uri) uri.is_a?(URI::HTTPS) || uri.is_a?(URI::HTTP) end
normalize_url(url)
click to toggle source
# File lib/indieauth_discovery/url.rb, line 57 def normalize_url(url) URI.parse(url).normalize end
raise_invalid_url_error(url)
click to toggle source
# File lib/indieauth_discovery/url.rb, line 124 def raise_invalid_url_error(url) raise InvalidURLError.new(:invalid_url, 'URL must begin with http:// or https://', url) end
redirect_callback(old_env, new_env)
click to toggle source
# File lib/indieauth_discovery/url.rb, line 120 def redirect_callback(old_env, new_env) redirects << { url: new_env.url.to_s, status: old_env.status } end
redirector(uri)
click to toggle source
# File lib/indieauth_discovery/url.rb, line 112 def redirector(uri) @redirector ||= Faraday.new(url: uri) do |faraday| faraday.use(FaradayMiddleware::FollowRedirects, callback: method(:redirect_callback)) faraday.adapter(Faraday.default_adapter) end end
verify_url(uri)
click to toggle source
@see indieauth.spec.indieweb.org/#url-canonicalization
# File lib/indieauth_discovery/url.rb, line 62 def verify_url(uri) if http_uri?(uri) && (last_response = check_url?(uri)) # Use the URL as-is if its already HTTP(S) and is available [uri.to_s, last_response] elsif (last_response = check_url?(URI.parse("https://#{uri}"))) # If no scheme was given (e.g. example.com), try HTTPS ["https://#{uri}", last_response] elsif (last_response = check_url?(URI.parse("http://#{uri}"))) # Try HTTP if HTTPS is not available ["http://#{uri}", last_response] else # The URL is considered invalid if none of the above work raise_invalid_url_error(uri) end end