feed_parser 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/feed_parser.rb +1 -1
- data/lib/feed_parser/feed.rb +25 -11
- data/spec/feed_parser_spec.rb +23 -3
- metadata +3 -3
data/lib/feed_parser.rb
CHANGED
data/lib/feed_parser/feed.rb
CHANGED
@@ -3,17 +3,7 @@ class FeedParser
|
|
3
3
|
attr_reader :type
|
4
4
|
|
5
5
|
def initialize(feed_url)
|
6
|
-
|
7
|
-
|
8
|
-
connection_options = {"User-Agent" => FeedParser::USER_AGENT}
|
9
|
-
connection_options[:http_basic_authentication] = parsed_url[:basic_auth] if parsed_url[:basic_auth]
|
10
|
-
|
11
|
-
raw_feed = if parsed_url[:protocol]
|
12
|
-
open(parsed_url[:url], connection_options)
|
13
|
-
else
|
14
|
-
open(parsed_url[:url])
|
15
|
-
end
|
16
|
-
|
6
|
+
raw_feed = open_or_follow_redirect(feed_url)
|
17
7
|
@feed = Nokogiri::XML(raw_feed)
|
18
8
|
@feed.remove_namespaces!
|
19
9
|
@type = (@feed.search('rss')[0] && :rss || :atom)
|
@@ -53,6 +43,30 @@ class FeedParser
|
|
53
43
|
end
|
54
44
|
|
55
45
|
private
|
46
|
+
|
47
|
+
# Some feeds
|
48
|
+
def open_or_follow_redirect(feed_url)
|
49
|
+
parsed_url = parse_url(feed_url)
|
50
|
+
|
51
|
+
connection_options = {"User-Agent" => FeedParser::USER_AGENT}
|
52
|
+
connection_options[:http_basic_authentication] = parsed_url[:basic_auth] if parsed_url[:basic_auth]
|
53
|
+
|
54
|
+
connection_options[:redirect] = true if RUBY_VERSION >= '1.9'
|
55
|
+
|
56
|
+
if parsed_url[:protocol]
|
57
|
+
open(parsed_url[:url], connection_options)
|
58
|
+
else
|
59
|
+
open(parsed_url[:url])
|
60
|
+
end
|
61
|
+
rescue RuntimeError => ex
|
62
|
+
redirect_url = ex.to_s.split(" ").last
|
63
|
+
if URI.split(feed_url).first == "http" && URI.split(redirect_url).first == "https"
|
64
|
+
open_or_follow_redirect(redirect_url)
|
65
|
+
else
|
66
|
+
raise ex
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
56
70
|
def parse_url(feed_url)
|
57
71
|
protocol, auth, *the_rest = URI.split(feed_url)
|
58
72
|
# insert a question mark in the beginning of query part of the uri
|
data/spec/feed_parser_spec.rb
CHANGED
@@ -12,20 +12,40 @@ describe FeedParser do
|
|
12
12
|
File.read(File.join(File.dirname(__FILE__), 'fixtures', 'nodeta.rss.xml'))
|
13
13
|
end
|
14
14
|
|
15
|
+
def http_connection_options
|
16
|
+
opts = {"User-Agent" => FeedParser::USER_AGENT}
|
17
|
+
opts[:redirect] = true if RUBY_VERSION >= '1.9'
|
18
|
+
opts
|
19
|
+
end
|
20
|
+
|
15
21
|
it "should fetch a feed by url" do
|
16
|
-
FeedParser::Feed.any_instance.should_receive(:open).with("http://blog.example.com/feed/",
|
22
|
+
FeedParser::Feed.any_instance.should_receive(:open).with("http://blog.example.com/feed/", http_connection_options).and_return(feed_xml)
|
17
23
|
FeedParser::Feed.new("http://blog.example.com/feed/")
|
18
24
|
end
|
19
25
|
|
20
26
|
it "should fetch a feed using basic auth if auth embedded to the url" do
|
21
|
-
FeedParser::Feed.any_instance.should_receive(:open).with("http://blog.example.com/feed/",
|
27
|
+
FeedParser::Feed.any_instance.should_receive(:open).with("http://blog.example.com/feed/", http_connection_options.merge(:http_basic_authentication => ["user", "pass"])).and_return(feed_xml)
|
22
28
|
FeedParser::Feed.new("http://user:pass@blog.example.com/feed/")
|
23
29
|
end
|
24
30
|
|
25
31
|
it "should fetch a feed with only a user name embedded to the url" do
|
26
|
-
FeedParser::Feed.any_instance.should_receive(:open).with("http://blog.example.com/feed/",
|
32
|
+
FeedParser::Feed.any_instance.should_receive(:open).with("http://blog.example.com/feed/", http_connection_options.merge(:http_basic_authentication => ["user"])).and_return(feed_xml)
|
27
33
|
FeedParser::Feed.new("http://user@blog.example.com/feed/")
|
28
34
|
end
|
35
|
+
|
36
|
+
it "should follow redirect based on the exception message" do
|
37
|
+
FeedParser::Feed.any_instance.should_receive(:open).with("http://example.com/feed", http_connection_options).and_raise(RuntimeError.new("redirection forbidden: http://example.com/feed -> https://example.com/feed"))
|
38
|
+
FeedParser::Feed.any_instance.should_receive(:open).with("https://example.com/feed", http_connection_options).and_return(feed_xml)
|
39
|
+
FeedParser::Feed.new("http://example.com/feed")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should not follow redirect from secure connection to non-secure one" do
|
43
|
+
FeedParser::Feed.any_instance.should_receive(:open).with("https://example.com/feed", http_connection_options).and_raise(RuntimeError.new("redirection forbidden: https://example.com/feed -> http://example.com/feed"))
|
44
|
+
FeedParser::Feed.any_instance.should_not_receive(:open).with("http://example.com/feed", http_connection_options)
|
45
|
+
lambda {
|
46
|
+
FeedParser::Feed.new("https://example.com/feed")
|
47
|
+
}.should raise_error(RuntimeError, "redirection forbidden: https://example.com/feed -> http://example.com/feed")
|
48
|
+
end
|
29
49
|
end
|
30
50
|
|
31
51
|
describe "#parse" do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: feed_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 4
|
10
|
+
version: 0.2.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Arttu Tervo
|