lib/link_rel_parser.rb
require "active_support"
require "active_support/core_ext/object/blank"
require "link_rel_parser/version"
require "metainspector"
require "uri"
module LinkRelParser
class << self
# Public: Parse out LINK headers with a REL value.
#
# url - URL to get HTTP HEAD Link (and effective/x-extended) rels.
#
# Examples
#
# LinkRelParser.parse("http://example.com")
# # =>
# {
# status: "200",
# type: "text/HTML",
# rels: { "pingback" => "http://www.example.com/xmlrpc.php", "indieauth" => "https://indieauth.com" }
# }
#
# Returns a hash of HTTP status code, content type, and LINKs with a REL value or an empty {}
def parse(url)
page = MetaInspector.new(url)
header_links = page.response.headers[:link]
# Convert X-Pingback to a Link header and have common code handle it
unless page.response.headers["x-pingback"].nil?
header_links << %Q{, <#{header_links['x-pingback']}>; rel="pingback"}
end
output = {
status: page.response.status,
type: page.response["content-type"],
rels: link_rels(header_links)
}
output[:rels].blank? ? {} : output
end
# Internal: Parse out the HTTP LINK headers with a REL value.
#
# headers - string to HTTP headers.
# base_url - optional base URL to resolve relative URLs (default: nil).
#
# Examples
#
# link_rels(headers)
# # => { "pingback" => "http://www.example.com/xmlrpc.php", "indieauth" => "https://indieauth.com" }
#
# Returns a hash of LINK name and REL value or an empty {}
def link_rels(headers, base_url: nil)
links = {}
unless headers.nil?
headers.split(", ").each do |link, index|
section = link.split(';')
url = section[0][/<(.*)>/,1]
# ignore link headers without rel
if section[1] =~ /rel=/
rel = section[1][/rel="*(.*)"*/,1].gsub(/"$/, "")
rel.split.each do |name|
unless base_url.blank?
uri = URI.parse(base_url)
path = url.gsub(%r{^/*}, "")
uri.path = "/" + path
url = uri.normalize
end
links[name] = url
end
end
end
end
links
end
end
end