* Add dependency on idn-ruby to speed up URI normalization * Use normalized_host instead of normalize.host when applicable When we are only interested in the normalized host, calling normalized_host avoids normalizing the other components of the URI as well as creating a new object
		
			
				
	
	
		
			84 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| class Pubsubhubbub::DeliveryWorker
 | |
|   include Sidekiq::Worker
 | |
|   include RoutingHelper
 | |
| 
 | |
|   sidekiq_options queue: 'push', retry: 3, dead: false
 | |
| 
 | |
|   sidekiq_retry_in do |count|
 | |
|     5 * (count + 1)
 | |
|   end
 | |
| 
 | |
|   attr_reader :subscription, :payload
 | |
| 
 | |
|   def perform(subscription_id, payload)
 | |
|     @subscription = Subscription.find(subscription_id)
 | |
|     @payload = payload
 | |
|     process_delivery unless blocked_domain?
 | |
|   end
 | |
| 
 | |
|   private
 | |
| 
 | |
|   def process_delivery
 | |
|     payload_delivery
 | |
| 
 | |
|     raise "Delivery failed for #{subscription.callback_url}: HTTP #{payload_delivery.code}" unless response_successful?
 | |
| 
 | |
|     subscription.touch(:last_successful_delivery_at)
 | |
|   end
 | |
| 
 | |
|   def payload_delivery
 | |
|     @_payload_delivery ||= callback_post_payload
 | |
|   end
 | |
| 
 | |
|   def callback_post_payload
 | |
|     request = Request.new(:post, subscription.callback_url, body: payload)
 | |
|     request.add_headers(headers)
 | |
|     request.perform
 | |
|   end
 | |
| 
 | |
|   def blocked_domain?
 | |
|     DomainBlock.blocked?(host)
 | |
|   end
 | |
| 
 | |
|   def host
 | |
|     Addressable::URI.parse(subscription.callback_url).normalized_host
 | |
|   end
 | |
| 
 | |
|   def headers
 | |
|     {
 | |
|       'Content-Type' => 'application/atom+xml',
 | |
|       'Link' => link_header,
 | |
|     }.merge(signature_headers.to_h)
 | |
|   end
 | |
| 
 | |
|   def link_header
 | |
|     LinkHeader.new([hub_link_header, self_link_header]).to_s
 | |
|   end
 | |
| 
 | |
|   def hub_link_header
 | |
|     [api_push_url, [%w(rel hub)]]
 | |
|   end
 | |
| 
 | |
|   def self_link_header
 | |
|     [account_url(subscription.account, format: :atom), [%w(rel self)]]
 | |
|   end
 | |
| 
 | |
|   def signature_headers
 | |
|     { 'X-Hub-Signature' => payload_signature } if subscription.secret?
 | |
|   end
 | |
| 
 | |
|   def payload_signature
 | |
|     "sha1=#{hmac_payload_digest}"
 | |
|   end
 | |
| 
 | |
|   def hmac_payload_digest
 | |
|     OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), subscription.secret, payload)
 | |
|   end
 | |
| 
 | |
|   def response_successful?
 | |
|     payload_delivery.code > 199 && payload_delivery.code < 300
 | |
|   end
 | |
| end
 |