mirror of
https://github.com/mastodon/mastodon.git
synced 2025-05-12 04:31:11 +00:00

ActivityPub spec section 3.2 reads > The client MUST specify an Accept header with the > `application/ld+json; profile="https://www.w3.org/ns/activitystreams"` > media type in order to retrieve the activity. Currently Mastodon omits the profile in its dereferences (but not the fetch service) and only lists application/ld+json as one of several possible types. This breaks spec and allows spec-compliant implementations to refuse any such fetch requests. Resolve this by adding the required profile and while at it, make the only spec-compliant type the first listed choice in all relevant places and drop profile-less JSON-LD. Section 7 also specifies the same media type MUST be used in the Content-Type header of for POST requests, but here we can't specify alternatives, so for now keep the current type. Fixes a part of https://github.com/mastodon/mastodon/issues/22720
61 lines
1.4 KiB
Ruby
61 lines
1.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class ActivityPub::Dereferencer
|
|
include JsonLdHelper
|
|
|
|
def initialize(uri, permitted_origin: nil, signature_actor: nil)
|
|
@uri = uri
|
|
@permitted_origin = permitted_origin
|
|
@signature_actor = signature_actor
|
|
end
|
|
|
|
def object
|
|
@object ||= fetch_object!
|
|
end
|
|
|
|
private
|
|
|
|
def bear_cap?
|
|
@uri.start_with?('bear:')
|
|
end
|
|
|
|
def fetch_object!
|
|
if bear_cap?
|
|
fetch_with_token!
|
|
else
|
|
fetch_with_signature!
|
|
end
|
|
end
|
|
|
|
def fetch_with_token!
|
|
perform_request(bear_cap['u'], headers: { 'Authorization' => "Bearer #{bear_cap['t']}" })
|
|
end
|
|
|
|
def fetch_with_signature!
|
|
perform_request(@uri)
|
|
end
|
|
|
|
def bear_cap
|
|
@bear_cap ||= Addressable::URI.parse(@uri).query_values
|
|
end
|
|
|
|
def perform_request(uri, headers: nil)
|
|
return if non_matching_uri_hosts?(@permitted_origin, uri)
|
|
|
|
req = Request.new(:get, uri)
|
|
|
|
req.add_headers('Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams", application/activity+json')
|
|
req.add_headers(headers) if headers
|
|
req.on_behalf_of(@signature_actor) if @signature_actor
|
|
|
|
req.perform do |res|
|
|
if res.code == 200
|
|
json = body_to_json(res.body_with_limit)
|
|
json if json.present? && json['id'] == uri
|
|
else
|
|
raise Mastodon::UnexpectedResponseError, res unless response_successful?(res) || response_error_unsalvageable?(res)
|
|
end
|
|
end
|
|
end
|
|
end
|