diaspora/lib/hydra_wrapper.rb
Jonne Haß 2d98c57cf1 [ci skip] The real issue with GnuTLS is actually a flaw in OpenSSL
which accepts several server misconfigurations

OpenSSL is very liberal about the order and content of the supplied
cert chain. GnuTLS however is very crucial about it. So to support
GnuTLS we need to tell our community to fix their servers (joindiaspora.com
is broken too). You can check it with
gnutls-cli -V --x506cafile=/etc/ssl/ca-certificates.crt $domain
It will print the certs in the order received and say at the end
if it could be verifed. Note that not only the order is important but
also the content. Many example configurations, especially for Nginx,
include the root cert of the CA in the chain which is wrong.
Note from a GnuTLS maintainer: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%23573736#29

Revert "Fix federation with GnuTLS by passing the ca_file to Typhoeus"

This reverts commit 640a0181ab.
2012-01-29 00:08:28 +01:00

90 lines
2.7 KiB
Ruby

# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
require 'typhoeus'
require 'active_support/base64'
class HydraWrapper
OPTS = {:max_redirects => 3, :timeout => 25000, :method => :post,
:headers => {'Expect' => '',
'Transfer-Encoding' => ''}
}
attr_reader :failed_people, :user, :encoded_object_xml
attr_accessor :dispatcher_class, :people, :hydra
def initialize(user, people, encoded_object_xml, dispatcher_class)
@user = user
@failed_people = []
@hydra = Typhoeus::Hydra.new
@people = people
@dispatcher_class = dispatcher_class
@encoded_object_xml = encoded_object_xml
end
# Delegates run to the @hydra
def run
@hydra.run
end
# @return [Salmon]
def salmon
@salmon ||= @dispatcher_class.salmon(@user, Base64.decode64(@encoded_object_xml))
end
# Group people on their receiving_urls
# @return [Hash] People grouped by receive_url ([String] => [Array<Person>])
def grouped_people
@people.group_by do |person|
@dispatcher_class.receive_url_for(person)
end
end
# Inserts jobs for all @people
def enqueue_batch
grouped_people.each do |receive_url, people_for_receive_url|
if xml = salmon.xml_for(people_for_receive_url.first)
self.insert_job(receive_url, xml, people_for_receive_url)
end
end
end
# Prepares and inserts job into the @hydra queue
# @param url [String]
# @param xml [String]
# @params people [Array<Person>]
def insert_job(url, xml, people)
request = Typhoeus::Request.new(url, OPTS.merge(:params => {:xml => CGI::escape(xml)}))
prepare_request!(request, people)
@hydra.queue(request)
end
# @param request [Typhoeus::Request]
# @param person [Person]
def prepare_request!(request, people_for_receive_url)
request.on_complete do |response|
# Save the reference to the pod to the database if not already present
Pod.find_or_create_by_url(response.effective_url)
if redirecting_to_https?(response)
Person.url_batch_update(people_for_receive_url, response.headers_hash['Location'])
end
unless response.success?
Rails.logger.info("event=http_multi_fail sender_id=#{@user.id} url=#{response.effective_url} response_code='#{response.code}'")
@failed_people += people_for_receive_url.map{|i| i.id}
end
end
end
# @return [Boolean]
def redirecting_to_https?(response)
if response.code >= 300 && response.code < 400
response.headers_hash['Location'] == response.request.url.sub('http://', 'https://')
else
false
end
end
end