down 2.1.0 → 2.2.0

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.
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