Making content-type checking less strict (allow text/xml)

This commit is contained in:
Eugen Rochko 2016-10-12 20:58:17 +02:00
parent 3fae9826cf
commit 73a44507c6
7 changed files with 40 additions and 25 deletions

View File

@ -1,7 +1,7 @@
PATH PATH
remote: . remote: .
specs: specs:
goldfinger (1.0.5) goldfinger (1.1.0)
addressable (~> 2.4) addressable (~> 2.4)
http (~> 2.0) http (~> 2.0)
nokogiri (~> 1.6) nokogiri (~> 1.6)
@ -25,16 +25,14 @@ GEM
http-cookie (~> 1.0) http-cookie (~> 1.0)
http-form_data (~> 1.0.1) http-form_data (~> 1.0.1)
http_parser.rb (~> 0.6.0) http_parser.rb (~> 0.6.0)
http-cookie (1.0.2) http-cookie (1.0.3)
domain_name (~> 0.5) domain_name (~> 0.5)
http-form_data (1.0.1) http-form_data (1.0.1)
http_parser.rb (0.6.0) http_parser.rb (0.6.0)
method_source (0.8.2) method_source (0.8.2)
mini_portile2 (2.1.0) mini_portile2 (2.1.0)
nokogiri (1.6.8) nokogiri (1.6.8.1)
mini_portile2 (~> 2.1.0) mini_portile2 (~> 2.1.0)
pkg-config (~> 1.1.7)
pkg-config (1.1.7)
pry (0.10.4) pry (0.10.4)
coderay (~> 1.1.0) coderay (~> 1.1.0)
method_source (~> 0.8.1) method_source (~> 0.8.1)

View File

@ -1,6 +1,6 @@
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = 'goldfinger' s.name = 'goldfinger'
s.version = '1.0.5' s.version = '1.1.0'
s.platform = Gem::Platform::RUBY s.platform = Gem::Platform::RUBY
s.required_ruby_version = '>= 2.0.0' s.required_ruby_version = '>= 2.0.0'
s.date = '2016-02-17' s.date = '2016-02-17'

View File

@ -13,7 +13,7 @@ module Goldfinger
ssl = true ssl = true
begin begin
_, template = perform_get(url(ssl)) template = perform_get(url(ssl))
rescue HTTP::Error rescue HTTP::Error
if ssl if ssl
ssl = false ssl = false
@ -23,11 +23,13 @@ module Goldfinger
end end
end end
headers, body = perform_get(url_from_template(template)) raise Goldfinger::NotFoundError, "No host-meta on the server" if template.code != 200
raise Goldfinger::Error, "Invalid response mime type: #{headers.get(HTTP::Headers::CONTENT_TYPE).first}" unless ['application/jrd+json', 'application/xrd+xml'].include?(headers.get(HTTP::Headers::CONTENT_TYPE).first) response = perform_get(url_from_template(template.body))
Goldfinger::Result.new(headers, body) raise Goldfinger::NotFoundError, "No such user on the server" if response.code != 200
Goldfinger::Result.new(response)
rescue HTTP::Error rescue HTTP::Error
raise Goldfinger::NotFoundError raise Goldfinger::NotFoundError
rescue OpenSSL::SSL::SSLError rescue OpenSSL::SSL::SSLError
@ -48,7 +50,7 @@ module Goldfinger
links.first.attribute('template').value.gsub('{uri}', @uri) links.first.attribute('template').value.gsub('{uri}', @uri)
rescue Nokogiri::XML::XPath::SyntaxError rescue Nokogiri::XML::XPath::SyntaxError
raise Goldfinger::Error, 'Bad XML' raise Goldfinger::Error, "Bad XML: #{template}"
end end
def domain def domain

View File

@ -10,14 +10,13 @@ module Goldfinger
end end
def perform def perform
response = http_client.request(@request_method, @uri.to_s, @options) http_client.request(@request_method, @uri.to_s, @options)
[response.headers, response.body]
end end
private private
def http_client def http_client
HTTP.timeout(:per_operation, write: 60, connect: 20, read: 60) HTTP.timeout(:per_operation, write: 60, connect: 20, read: 60).follow
end end
end end
end end

View File

@ -1,8 +1,16 @@
module Goldfinger module Goldfinger
class Result class Result
def initialize(headers, body) MIME_TYPES = [
@mime_type = headers.get(HTTP::Headers::CONTENT_TYPE).first 'application/jrd+json',
@body = body 'application/json',
'application/xrd+xml',
'application/xml',
'text/xml'
].freeze
def initialize(response)
@mime_type = response.mime_type
@body = response.body
@subject = nil @subject = nil
@aliases = [] @aliases = []
@links = {} @links = {}
@ -62,8 +70,10 @@ module Goldfinger
case @mime_type case @mime_type
when 'application/jrd+json', 'application/json' when 'application/jrd+json', 'application/json'
parse_json parse_json
when 'application/xrd+xml' when 'application/xrd+xml', 'application/xml', 'text/xml'
parse_xml parse_xml
else
raise Goldfinger::Error, "Invalid response mime type: #{@mime_type}"
end end
end end

View File

@ -6,8 +6,8 @@ describe Goldfinger::Request do
subject { Goldfinger::Request.new(:get, 'http://example.com').perform } subject { Goldfinger::Request.new(:get, 'http://example.com').perform }
it 'returns the body' do it 'returns a http response' do
expect(subject.last.to_s).to eql 'OK' expect(subject).to be_a HTTP::Response
end end
end end
end end

View File

@ -1,6 +1,6 @@
describe Goldfinger::Result do describe Goldfinger::Result do
shared_examples 'a working finger result' do shared_examples 'a working finger result' do
subject { Goldfinger::Result.new(headers, body) } subject { Goldfinger::Result.new(response) }
describe '#links' do describe '#links' do
it 'returns a non-empty array' do it 'returns a non-empty array' do
@ -59,15 +59,21 @@ describe Goldfinger::Result do
end end
context 'when the input mime type is application/xrd+xml' do context 'when the input mime type is application/xrd+xml' do
let(:headers) { h = HTTP::Headers.new; h.set(HTTP::Headers::CONTENT_TYPE, 'application/xrd+xml'); h } before do
let(:body) { File.read(fixture_path('quitter.no_.well-known_webfinger.xml')) } stub_request(:get, 'https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no').to_return(body: fixture('quitter.no_.well-known_webfinger.xml'), headers: { content_type: 'application/xrd+xml' })
end
let(:response) { HTTP.get('https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no') }
it_behaves_like 'a working finger result' it_behaves_like 'a working finger result'
end end
context 'when the input mime type is application/jrd+json' do context 'when the input mime type is application/jrd+json' do
let(:headers) { h = HTTP::Headers.new; h.set(HTTP::Headers::CONTENT_TYPE, 'application/jrd+json'); h } before do
let(:body) { File.read(fixture_path('quitter.no_.well-known_webfinger.json')) } stub_request(:get, 'https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no').to_return(body: fixture('quitter.no_.well-known_webfinger.json'), headers: { content_type: 'application/jrd+json' })
end
let(:response) { HTTP.get('https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no') }
it_behaves_like 'a working finger result' it_behaves_like 'a working finger result'
end end