Merge remote-tracking branch 'tootsuite/master' into glitchsoc/master
This commit is contained in:
@@ -24,43 +24,44 @@ class FetchAtomService < BaseService
|
||||
|
||||
def process(url, terminal = false)
|
||||
@url = url
|
||||
perform_request
|
||||
process_response(terminal)
|
||||
perform_request { |response| process_response(response, terminal) }
|
||||
end
|
||||
|
||||
def perform_request
|
||||
def perform_request(&block)
|
||||
accept = 'text/html'
|
||||
accept = 'application/activity+json, application/ld+json, application/atom+xml, ' + accept unless @unsupported_activity
|
||||
|
||||
@response = Request.new(:get, @url)
|
||||
.add_headers('Accept' => accept)
|
||||
.perform
|
||||
Request.new(:get, @url).add_headers('Accept' => accept).perform(&block)
|
||||
end
|
||||
|
||||
def process_response(terminal = false)
|
||||
return nil if @response.code != 200
|
||||
def process_response(response, terminal = false)
|
||||
return nil if response.code != 200
|
||||
|
||||
if @response.mime_type == 'application/atom+xml'
|
||||
[@url, { prefetched_body: @response.to_s }, :ostatus]
|
||||
elsif ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].include?(@response.mime_type)
|
||||
json = body_to_json(@response.to_s)
|
||||
if response.mime_type == 'application/atom+xml'
|
||||
[@url, { prefetched_body: response.to_s }, :ostatus]
|
||||
elsif ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].include?(response.mime_type)
|
||||
json = body_to_json(response.to_s)
|
||||
if supported_context?(json) && json['type'] == 'Person' && json['inbox'].present?
|
||||
[json['id'], { prefetched_body: @response.to_s, id: true }, :activitypub]
|
||||
[json['id'], { prefetched_body: response.to_s, id: true }, :activitypub]
|
||||
elsif supported_context?(json) && json['type'] == 'Note'
|
||||
[json['id'], { prefetched_body: @response.to_s, id: true }, :activitypub]
|
||||
[json['id'], { prefetched_body: response.to_s, id: true }, :activitypub]
|
||||
else
|
||||
@unsupported_activity = true
|
||||
nil
|
||||
end
|
||||
elsif @response['Link'] && !terminal && link_header.find_link(%w(rel alternate))
|
||||
process_headers
|
||||
elsif @response.mime_type == 'text/html' && !terminal
|
||||
process_html
|
||||
elsif !terminal
|
||||
link_header = response['Link'] && parse_link_header(response)
|
||||
|
||||
if link_header&.find_link(%w(rel alternate))
|
||||
process_link_headers(link_header)
|
||||
elsif response.mime_type == 'text/html'
|
||||
process_html(response)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def process_html
|
||||
page = Nokogiri::HTML(@response.to_s)
|
||||
def process_html(response)
|
||||
page = Nokogiri::HTML(response.to_s)
|
||||
|
||||
json_link = page.xpath('//link[@rel="alternate"]').find { |link| ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].include?(link['type']) }
|
||||
atom_link = page.xpath('//link[@rel="alternate"]').find { |link| link['type'] == 'application/atom+xml' }
|
||||
@@ -71,7 +72,7 @@ class FetchAtomService < BaseService
|
||||
result
|
||||
end
|
||||
|
||||
def process_headers
|
||||
def process_link_headers(link_header)
|
||||
json_link = link_header.find_link(%w(rel alternate), %w(type application/activity+json)) || link_header.find_link(%w(rel alternate), ['type', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'])
|
||||
atom_link = link_header.find_link(%w(rel alternate), %w(type application/atom+xml))
|
||||
|
||||
@@ -81,7 +82,7 @@ class FetchAtomService < BaseService
|
||||
result
|
||||
end
|
||||
|
||||
def link_header
|
||||
@link_header ||= LinkHeader.parse(@response['Link'].is_a?(Array) ? @response['Link'].first : @response['Link'])
|
||||
def parse_link_header(response)
|
||||
LinkHeader.parse(response['Link'].is_a?(Array) ? response['Link'].first : response['Link'])
|
||||
end
|
||||
end
|
||||
|
@@ -36,15 +36,24 @@ class FetchLinkCardService < BaseService
|
||||
|
||||
def process_url
|
||||
@card ||= PreviewCard.new(url: @url)
|
||||
res = Request.new(:head, @url).perform
|
||||
|
||||
return if res.code != 405 && (res.code != 200 || res.mime_type != 'text/html')
|
||||
failed = Request.new(:head, @url).perform do |res|
|
||||
res.code != 405 && (res.code != 200 || res.mime_type != 'text/html')
|
||||
end
|
||||
|
||||
@response = Request.new(:get, @url).perform
|
||||
return if failed
|
||||
|
||||
return if @response.code != 200 || @response.mime_type != 'text/html'
|
||||
Request.new(:get, @url).perform do |res|
|
||||
if res.code == 200 && res.mime_type == 'text/html'
|
||||
@html = res.to_s
|
||||
@html_charset = res.charset
|
||||
else
|
||||
@html = nil
|
||||
@html_charset = nil
|
||||
end
|
||||
end
|
||||
|
||||
@html = @response.to_s
|
||||
return if @html.nil?
|
||||
|
||||
attempt_oembed || attempt_opengraph
|
||||
end
|
||||
@@ -118,7 +127,7 @@ class FetchLinkCardService < BaseService
|
||||
detector = CharlockHolmes::EncodingDetector.new
|
||||
detector.strip_tags = true
|
||||
|
||||
guess = detector.detect(@html, @response.charset)
|
||||
guess = detector.detect(@html, @html_charset)
|
||||
page = Nokogiri::HTML(@html, nil, guess&.fetch(:encoding, nil))
|
||||
|
||||
if meta_property(page, 'twitter:player')
|
||||
|
@@ -179,11 +179,10 @@ class ResolveAccountService < BaseService
|
||||
def atom_body
|
||||
return @atom_body if defined?(@atom_body)
|
||||
|
||||
response = Request.new(:get, atom_url).perform
|
||||
|
||||
raise Mastodon::UnexpectedResponseError, response unless response.code == 200
|
||||
|
||||
@atom_body = response.to_s
|
||||
@atom_body = Request.new(:get, atom_url).perform do |response|
|
||||
raise Mastodon::UnexpectedResponseError, response unless response.code == 200
|
||||
response.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def actor_json
|
||||
|
@@ -12,11 +12,9 @@ class SendInteractionService < BaseService
|
||||
|
||||
return if !target_account.ostatus? || block_notification?
|
||||
|
||||
delivery = build_request.perform
|
||||
|
||||
raise Mastodon::UnexpectedResponseError, delivery unless delivery.code > 199 && delivery.code < 300
|
||||
|
||||
delivery.connection&.close
|
||||
build_request.perform do |delivery|
|
||||
raise Mastodon::UnexpectedResponseError, delivery unless delivery.code > 199 && delivery.code < 300
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
@@ -6,21 +6,21 @@ class SubscribeService < BaseService
|
||||
|
||||
@account = account
|
||||
@account.secret = SecureRandom.hex
|
||||
@response = build_request.perform
|
||||
|
||||
if response_failed_permanently?
|
||||
# We're not allowed to subscribe. Fail and move on.
|
||||
@account.secret = ''
|
||||
@account.save!
|
||||
elsif response_successful?
|
||||
# The subscription will be confirmed asynchronously.
|
||||
@account.save!
|
||||
else
|
||||
# The response was either a 429 rate limit, or a 5xx error.
|
||||
# We need to retry at a later time. Fail loudly!
|
||||
raise Mastodon::UnexpectedResponseError, @response
|
||||
build_request.perform do |response|
|
||||
if response_failed_permanently? response
|
||||
# We're not allowed to subscribe. Fail and move on.
|
||||
@account.secret = ''
|
||||
@account.save!
|
||||
elsif response_successful? response
|
||||
# The subscription will be confirmed asynchronously.
|
||||
@account.save!
|
||||
else
|
||||
# The response was either a 429 rate limit, or a 5xx error.
|
||||
# We need to retry at a later time. Fail loudly!
|
||||
raise Mastodon::UnexpectedResponseError, response
|
||||
end
|
||||
end
|
||||
@response.connection&.close
|
||||
end
|
||||
|
||||
private
|
||||
@@ -47,12 +47,12 @@ class SubscribeService < BaseService
|
||||
end
|
||||
|
||||
# Any response in the 3xx or 4xx range, except for 429 (rate limit)
|
||||
def response_failed_permanently?
|
||||
(@response.status.redirect? || @response.status.client_error?) && !@response.status.too_many_requests?
|
||||
def response_failed_permanently?(response)
|
||||
(response.status.redirect? || response.status.client_error?) && !response.status.too_many_requests?
|
||||
end
|
||||
|
||||
# Any response in the 2xx range
|
||||
def response_successful?
|
||||
@response.status.success?
|
||||
def response_successful?(response)
|
||||
response.status.success?
|
||||
end
|
||||
end
|
||||
|
@@ -7,10 +7,9 @@ class UnsubscribeService < BaseService
|
||||
@account = account
|
||||
|
||||
begin
|
||||
@response = build_request.perform
|
||||
|
||||
Rails.logger.debug "PuSH unsubscribe for #{@account.acct} failed: #{@response.status}" unless @response.status.success?
|
||||
@response.connection&.close
|
||||
build_request.perform do |response|
|
||||
Rails.logger.debug "PuSH unsubscribe for #{@account.acct} failed: #{response.status}" unless response.status.success?
|
||||
end
|
||||
rescue HTTP::Error, OpenSSL::SSL::SSLError => e
|
||||
Rails.logger.debug "PuSH unsubscribe for #{@account.acct} failed: #{e}"
|
||||
end
|
||||
|
Reference in New Issue
Block a user