down 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -1
  3. data/down.gemspec +1 -1
  4. data/lib/down.rb +34 -25
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 932ad54eb266b7cc369a8afa2b71eb6a8d70e289
4
- data.tar.gz: 1976c429007e474fa59221ad90d82da674a875e3
3
+ metadata.gz: 2a8a682287353edfab10f1e5f6850b7e0dc2266f
4
+ data.tar.gz: a2ad18a8a32409594fb3918fa5e4dff851872d18
5
5
  SHA512:
6
- metadata.gz: ff49b59cd8b661135b58070a9079b7989d4ba90ee9727888d050df55e75ab820e0f498b1454470a3696f0bf7abfc31f9ce0bd145cdb93a3e0bf739e29514fe74
7
- data.tar.gz: 6a158be107f0cc7eecfcecb582e4481c03a255706f4184adcda34bde57ce19715b9ac11c4a09fbc3ec53b9197398c03be30e165e6d04ba1be90a937696eccff8
6
+ metadata.gz: f50514a9c905dab165f460e114be9bee93815306394fcaf6a4be4e530979e97114b772293f1e38dcc0fc9f9f10c0b2d79cecf854143c0c1b0f13ebb9c8a91c1b
7
+ data.tar.gz: 55ee7597729abb451f06a579c4978a882b958023c737232a4858b8f6d0fd1d6dc794874dd8b80ab56e33e79afd612fe69f4f21842b602b26e9580737f3422073
data/README.md CHANGED
@@ -67,6 +67,18 @@ terminates the download very early, as soon as it gets the `Content-Length`
67
67
  header. And if the `Content-Length` header is missing, Down will terminate the
68
68
  download as soon as it receives a chunk which surpasses the maximum size.
69
69
 
70
+ ### Redirects
71
+
72
+ By default open-uri's redirects are turned off, since open-uri doesn't have a
73
+ way to limit maximum number of redirects. Instead Down itself implements
74
+ following redirects, by default allowing maximum of 2 redirects.
75
+
76
+ ```rb
77
+ Down.download("http://example.com/image.jpg") # 2 redirects allowed
78
+ Down.download("http://example.com/image.jpg", max_redirects: 5) # 5 redirects allowed
79
+ Down.download("http://example.com/image.jpg", max_redirects: 0) # 0 redirects allowed
80
+ ```
81
+
70
82
  ### Download errors
71
83
 
72
84
  There are a lot of ways in which a download can fail:
@@ -75,7 +87,6 @@ There are a lot of ways in which a download can fail:
75
87
  * URL is a little bit invalid, e.g. "http:/example.com" (`Errno::ECONNREFUSED`)
76
88
  * Domain wasn't not found (`SocketError`)
77
89
  * Domain was found, but status is 4xx or 5xx (`OpenURI::HTTPError`)
78
- * Request went into a redirect loop (`RuntimeError`)
79
90
  * Request timeout out (`Timeout::Error`)
80
91
 
81
92
  Down unifies all of these errors into one `Down::NotFound` error (because this
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "down"
3
- spec.version = "2.1.0"
3
+ spec.version = "2.2.0"
4
4
  spec.authors = ["Janko Marohnić"]
5
5
  spec.email = ["janko.marohnic@gmail.com"]
6
6
 
@@ -11,33 +11,44 @@ module Down
11
11
  module_function
12
12
 
13
13
  def download(url, options = {})
14
- uri = URI.parse(url)
15
-
16
14
  warn "Passing :timeout option to `Down.download` is deprecated and will be removed in Down 3. You should use open-uri's :open_timeout and/or :read_timeout." if options.key?(:timeout)
17
15
  warn "Passing :progress option to `Down.download` is deprecated and will be removed in Down 3. You should use open-uri's :progress_proc." if options.key?(:progress)
18
16
 
19
17
  max_size = options.delete(:max_size)
18
+ max_redirects = options.delete(:max_redirects) || 2
20
19
  progress_proc = options.delete(:progress_proc) || options.delete(:progress)
21
20
  content_length_proc = options.delete(:content_length_proc)
22
21
  timeout = options.delete(:timeout)
23
22
 
24
- downloaded_file = uri.open({
25
- "User-Agent" => "Down/1.0.0",
26
- content_length_proc: proc { |size|
27
- if size && max_size && size > max_size
28
- raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
29
- end
30
- content_length_proc.call(size) if content_length_proc
31
- },
32
- progress_proc: proc { |current_size|
33
- if max_size && current_size > max_size
34
- raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
35
- end
36
- progress_proc.call(current_size) if progress_proc
37
- },
38
- read_timeout: timeout,
39
- redirect: false,
40
- }.merge(options))
23
+ requests_left = max_redirects + 1
24
+
25
+ begin
26
+ uri = URI.parse(url)
27
+ downloaded_file = uri.open({
28
+ "User-Agent" => "Down/1.0.0",
29
+ content_length_proc: proc { |size|
30
+ if size && max_size && size > max_size
31
+ raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
32
+ end
33
+ content_length_proc.call(size) if content_length_proc
34
+ },
35
+ progress_proc: proc { |current_size|
36
+ if max_size && current_size > max_size
37
+ raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
38
+ end
39
+ progress_proc.call(current_size) if progress_proc
40
+ },
41
+ read_timeout: timeout,
42
+ redirect: false,
43
+ }.merge(options))
44
+ rescue OpenURI::HTTPRedirect => error
45
+ url = error.uri.to_s
46
+ retry if (requests_left -= 1) > 0
47
+ raise Down::NotFound, "too many redirects"
48
+ rescue => error
49
+ raise if error.is_a?(Down::Error)
50
+ raise Down::NotFound, "file not found"
51
+ end
41
52
 
42
53
  # open-uri will return a StringIO instead of a Tempfile if the filesize is
43
54
  # less than 10 KB, so if it happens we convert it back to Tempfile. We want
@@ -50,10 +61,6 @@ module Down
50
61
 
51
62
  downloaded_file.extend DownloadedFile
52
63
  downloaded_file
53
-
54
- rescue => error
55
- raise if error.is_a?(Down::Error)
56
- raise Down::NotFound, "file not found"
57
64
  end
58
65
 
59
66
  def stream(url, options = {})
@@ -100,8 +107,10 @@ module Down
100
107
  module DownloadedFile
101
108
  def original_filename
102
109
  path = base_uri.path
103
- path = CGI.unescape(path)
104
- File.basename(path) unless path.empty? || path == "/"
110
+ unless path.empty? || path == "/"
111
+ filename = path.split("/").last
112
+ CGI.unescape(filename)
113
+ end
105
114
  end
106
115
  end
107
116
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: down
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-12 00:00:00.000000000 Z
11
+ date: 2016-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake