feed_parser 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
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