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 CHANGED
@@ -3,7 +3,7 @@ require 'nokogiri'
3
3
 
4
4
  class FeedParser
5
5
 
6
- VERSION = "0.2.3"
6
+ VERSION = "0.2.4"
7
7
 
8
8
  USER_AGENT = "Ruby / FeedParser gem"
9
9
 
@@ -3,17 +3,7 @@ class FeedParser
3
3
  attr_reader :type
4
4
 
5
5
  def initialize(feed_url)
6
- parsed_url = parse_url(feed_url)
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
@@ -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/", "User-Agent" => FeedParser::USER_AGENT).and_return(feed_xml)
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/", "User-Agent" => FeedParser::USER_AGENT, :http_basic_authentication => ["user", "pass"]).and_return(feed_xml)
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/", "User-Agent" => FeedParser::USER_AGENT, :http_basic_authentication => ["user"]).and_return(feed_xml)
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: 17
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 3
10
- version: 0.2.3
9
+ - 4
10
+ version: 0.2.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Arttu Tervo