2016-11-28 21:36:47 +09:00
# frozen_string_literal: true
class Pubsubhubbub :: DeliveryWorker
include Sidekiq :: Worker
include RoutingHelper
2017-01-05 11:28:21 +09:00
sidekiq_options queue : 'push' , retry : 3 , dead : false
sidekiq_retry_in do | count |
5 * ( count + 1 )
end
2016-11-29 10:07:14 +09:00
2016-11-28 21:36:47 +09:00
def perform ( subscription_id , payload )
subscription = Subscription . find ( subscription_id )
headers = { }
2017-04-25 09:47:31 +09:00
host = Addressable :: URI . parse ( subscription . callback_url ) . normalize . host
2017-04-07 12:56:56 +09:00
return if DomainBlock . blocked? ( host )
2016-11-28 21:36:47 +09: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-13 01:24:18 +09:00
headers [ 'X-Hub-Signature' ] = signature ( subscription . secret , payload ) if subscription . secret?
2016-11-28 21:36:47 +09:00
response = HTTP . timeout ( :per_operation , write : 50 , connect : 20 , read : 50 )
. headers ( headers )
. post ( subscription . callback_url , body : payload )
2017-04-05 09:32:18 +09: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 21:36:47 +09:00
raise " Delivery failed for #{ subscription . callback_url } : HTTP #{ response . code } " unless response . code > 199 && response . code < 300
2016-11-30 23:24:57 +09:00
subscription . touch ( :last_successful_delivery_at )
2016-11-28 21:36:47 +09:00
end
private
def signature ( secret , payload )
hmac = OpenSSL :: HMAC . hexdigest ( OpenSSL :: Digest . new ( 'sha1' ) , secret , payload )
" sha1= #{ hmac } "
end
end