2016-11-28 13:36:47 +01:00
# frozen_string_literal: true
class Pubsubhubbub :: DeliveryWorker
include Sidekiq :: Worker
include RoutingHelper
2017-01-05 03:28:21 +01:00
sidekiq_options queue : 'push' , retry : 3 , dead : false
sidekiq_retry_in do | count |
5 * ( count + 1 )
end
2016-11-29 02:07:14 +01:00
2016-11-28 13:36:47 +01:00
def perform ( subscription_id , payload )
subscription = Subscription . find ( subscription_id )
headers = { }
2017-04-25 02:47:31 +02:00
host = Addressable :: URI . parse ( subscription . callback_url ) . normalize . host
2017-04-07 05:56:56 +02:00
return if DomainBlock . blocked? ( host )
2016-11-28 13:36:47 +01:00
headers [ 'User-Agent' ] = 'Mastodon/PubSubHubbub'
headers [ 'Link' ] = LinkHeader . new ( [ [ api_push_url , [ %w( rel hub ) ] ] , [ account_url ( subscription . account , format : :atom ) , [ %w( rel self ) ] ] ] ) . to_s
2017-04-12 18:24:18 +02:00
headers [ 'X-Hub-Signature' ] = signature ( subscription . secret , payload ) if subscription . secret?
2016-11-28 13:36:47 +01:00
response = HTTP . timeout ( :per_operation , write : 50 , connect : 20 , read : 50 )
. headers ( headers )
. post ( subscription . callback_url , body : payload )
2017-04-05 02:32:18 +02:00
return subscription . destroy! if response . code > 299 && response . code < 500 && response . code != 429 # HTTP 4xx means error is not temporary, except for 429 (throttling)
2016-11-28 13:36:47 +01:00
raise " Delivery failed for #{ subscription . callback_url } : HTTP #{ response . code } " unless response . code > 199 && response . code < 300
2016-11-30 15:24:57 +01:00
subscription . touch ( :last_successful_delivery_at )
2016-11-28 13:36:47 +01:00
end
private
def signature ( secret , payload )
hmac = OpenSSL :: HMAC . hexdigest ( OpenSSL :: Digest . new ( 'sha1' ) , secret , payload )
" sha1= #{ hmac } "
end
end