down 4.1.0 → 4.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '08443f7ebc7a853be6b2c24d0cff24795af18bdf'
4
- data.tar.gz: c723068fcc5675755bb90f51ab8eab1fe21a3cef
3
+ metadata.gz: 5e6bbd2b9b51b4b88834180552227abece0bed9a
4
+ data.tar.gz: 102d96a339e3a252af86a59d99dd992ad80a2bac
5
5
  SHA512:
6
- metadata.gz: 0b9b5ec3d60c3dc7d035bf79e29767d22e2de97b05e060fcc477da5ea3d9015b8f19c26b2414e94643268123fedaa427e2e3d69c47d614109874788315bc93dd
7
- data.tar.gz: e98698c9fb10d4163b3ec33eb63b1ef38cb62b069835620c01ed93d7994d38b99c3b55a3f5eace5fe628b1f9c1fb6d93a17ea1e6cae75bb3d119bb5a484a391a
6
+ metadata.gz: ae39c2f9a1e29a0d75af0ec43efcb02b9d5774a3aa3eb4c0ec1d73cd14552b7a405050e3c39b81857db97cda8355b744823bc375523f2a99a4966e5a5ac35767
7
+ data.tar.gz: a3f8183ed4fdd120cc35dfbb69231975c86411f23e3e17007b737edf7a8963735af807679eb8e704af3e58828f8901283094b3c23ed620e0e2f2468a66e79320
data/README.md CHANGED
@@ -17,6 +17,7 @@ Tempfile:
17
17
 
18
18
  ```rb
19
19
  require "down"
20
+
20
21
  tempfile = Down.download("http://example.com/nature.jpg")
21
22
  tempfile #=> #<Tempfile:/var/folders/k7/6zx6dx6x7ys3rv3srh0nyfj00000gn/T/20150925-55456-z7vxqz.jpg>
22
23
  ```
@@ -141,21 +142,26 @@ status was 4xx or 5xx.
141
142
 
142
143
  ### `Down::ChunkedIO`
143
144
 
144
- The `Down.open` method uses `Down::ChunkedIO` internally. However,
145
- `Down::ChunkedIO` is designed to be generic, it can wrap any kind of streaming.
145
+ The `Down.open` performs HTTP logic and returns an instance of
146
+ `Down::ChunkedIO`. However, `Down::ChunkedIO` is a generic class that can wrap
147
+ any kind of streaming. It accepts an `Enumerator` that yields chunks of
148
+ content, and provides IO-like interface over that enumerator, calling it
149
+ whenever more content is needed.
146
150
 
147
151
  ```rb
152
+ require "down/chunked_io"
153
+
148
154
  Down::ChunkedIO.new(...)
149
155
  ```
150
156
 
151
- * `:chunks` – an `Enumerator` which retrieves chunks
157
+ * `:chunks` – `Enumerator` that yields chunks of content
152
158
  * `:size` – size of the file if it's known (returned by `#size`)
153
159
  * `:on_close` – called when streaming finishes or IO is closed
154
160
  * `:data` - custom data that you want to store (returned by `#data`)
155
161
  * `:rewindable` - whether to cache retrieved data into a file (defaults to `true`)
156
162
  * `:encoding` - force content to be returned in specified encoding (defaults to `Encoding::BINARY`)
157
163
 
158
- Here is an example of wrapping streaming MongoDB files:
164
+ Here is an example of creating a streaming IO of a MongoDB GridFS file:
159
165
 
160
166
  ```rb
161
167
  require "down/chunked_io"
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  spec.add_development_dependency "minitest", "~> 5.8"
19
19
  spec.add_development_dependency "mocha"
20
- spec.add_development_dependency "http", "~> 2.1"
20
+ spec.add_development_dependency "http", "~> 3.0"
21
21
  spec.add_development_dependency "posix-spawn" unless RUBY_ENGINE == "jruby"
22
22
  spec.add_development_dependency "http_parser.rb"
23
23
  spec.add_development_dependency "docker-api"
@@ -59,9 +59,13 @@ module Down
59
59
  end
60
60
 
61
61
  def open(url, rewindable: true, **options, &block)
62
- response = get(url, **options, &block)
62
+ begin
63
+ response = get(url, **options, &block)
64
+ rescue => exception
65
+ request_error!(exception)
66
+ end
63
67
 
64
- response_error!(response) if !response.status.success?
68
+ response_error!(response) unless response.status.success?
65
69
 
66
70
  body_chunks = Enumerator.new do |yielder|
67
71
  begin
@@ -79,8 +83,6 @@ module Down
79
83
  on_close: (-> { response.connection.close } unless @client.persistent?),
80
84
  data: { status: response.code, headers: response.headers.to_h, response: response },
81
85
  )
82
- rescue => exception
83
- request_error!(exception)
84
86
  end
85
87
 
86
88
  private
@@ -112,24 +114,15 @@ module Down
112
114
 
113
115
  def request_error!(exception)
114
116
  case exception
115
- when HTTP::Request::UnsupportedSchemeError
117
+ when HTTP::Request::UnsupportedSchemeError, Addressable::URI::InvalidURIError
116
118
  raise Down::InvalidUrl, exception.message
117
- when Errno::ECONNREFUSED
118
- raise Down::ConnectionError, "connection was refused"
119
- when HTTP::ConnectionError,
120
- Errno::ECONNABORTED,
121
- Errno::ECONNRESET,
122
- Errno::EPIPE,
123
- Errno::EINVAL,
124
- Errno::EHOSTUNREACH
119
+ when HTTP::ConnectionError
125
120
  raise Down::ConnectionError, exception.message
126
- when SocketError
127
- raise Down::ConnectionError, "domain name could not be resolved"
128
121
  when HTTP::TimeoutError
129
122
  raise Down::TimeoutError, exception.message
130
123
  when HTTP::Redirector::TooManyRedirectsError
131
124
  raise Down::TooManyRedirects, exception.message
132
- when defined?(OpenSSL) && OpenSSL::SSL::SSLError
125
+ when OpenSSL::SSL::SSLError
133
126
  raise Down::SSLError, exception.message
134
127
  else
135
128
  raise exception
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  require "open-uri"
4
- require "net/http"
4
+ require "net/https"
5
5
 
6
6
  require "down/backend"
7
7
 
@@ -60,15 +60,18 @@ module Down
60
60
 
61
61
  begin
62
62
  uri = URI(uri)
63
+ raise Down::InvalidUrl, "URL scheme needs to be http or https" unless uri.is_a?(URI::HTTP)
64
+ rescue URI::InvalidURIError => exception
65
+ raise Down::InvalidUrl, exception.message
66
+ end
63
67
 
64
- fail Down::InvalidUrl, "URL scheme needs to be http or https" unless uri.is_a?(URI::HTTP)
65
-
66
- if uri.user || uri.password
67
- open_uri_options[:http_basic_authentication] ||= [uri.user, uri.password]
68
- uri.user = nil
69
- uri.password = nil
70
- end
68
+ if uri.user || uri.password
69
+ open_uri_options[:http_basic_authentication] ||= [uri.user, uri.password]
70
+ uri.user = nil
71
+ uri.password = nil
72
+ end
71
73
 
74
+ begin
72
75
  downloaded_file = uri.open(open_uri_options)
73
76
  rescue OpenURI::HTTPRedirect => exception
74
77
  if (tries -= 1) > 0
@@ -80,7 +83,7 @@ module Down
80
83
 
81
84
  retry
82
85
  else
83
- fail Down::TooManyRedirects, "too many redirects"
86
+ raise Down::TooManyRedirects, "too many redirects"
84
87
  end
85
88
  rescue OpenURI::HTTPError => exception
86
89
  code, message = exception.io.status
@@ -110,9 +113,13 @@ module Down
110
113
 
111
114
  def open(uri, options = {})
112
115
  options = @options.merge(options)
113
- uri = URI(uri)
114
116
 
115
- fail Down::InvalidUrl, "URL scheme needs to be http or https" unless uri.is_a?(URI::HTTP)
117
+ begin
118
+ uri = URI(uri)
119
+ raise Down::InvalidUrl, "URL scheme needs to be http or https" unless uri.is_a?(URI::HTTP)
120
+ rescue URI::InvalidURIError => exception
121
+ raise Down::InvalidUrl, exception.message
122
+ end
116
123
 
117
124
  http_class = Net::HTTP
118
125
 
@@ -125,7 +132,6 @@ module Down
125
132
 
126
133
  # taken from open-uri implementation
127
134
  if uri.is_a?(URI::HTTPS)
128
- require "net/https"
129
135
  http.use_ssl = true
130
136
  http.verify_mode = options[:ssl_verify_mode] || OpenSSL::SSL::VERIFY_PEER
131
137
  store = OpenSSL::X509::Store.new
@@ -157,7 +163,11 @@ module Down
157
163
  end
158
164
  end
159
165
 
160
- response = request.resume
166
+ begin
167
+ response = request.resume
168
+ rescue => exception
169
+ request_error!(exception)
170
+ end
161
171
 
162
172
  response_error!(response) unless (200..299).cover?(response.code.to_i)
163
173
 
@@ -184,8 +194,6 @@ module Down
184
194
  response: response,
185
195
  },
186
196
  )
187
- rescue => exception
188
- request_error!(exception)
189
197
  end
190
198
 
191
199
  private
@@ -219,24 +227,13 @@ module Down
219
227
 
220
228
  def request_error!(exception)
221
229
  case exception
222
- when URI::InvalidURIError
223
- raise Down::InvalidUrl, "URL was invalid"
224
- when Errno::ECONNREFUSED
225
- raise Down::ConnectionError, "connection was refused"
226
- when EOFError,
227
- IOError,
228
- Errno::ECONNABORTED,
229
- Errno::ECONNRESET,
230
- Errno::EPIPE,
231
- Errno::EINVAL,
232
- Errno::EHOSTUNREACH
230
+ when Errno::ETIMEDOUT, Net::OpenTimeout
231
+ raise Down::TimeoutError, "timed out waiting for connection to open"
232
+ when Net::ReadTimeout
233
+ raise Down::TimeoutError, "timed out while reading data"
234
+ when EOFError, IOError, SocketError, SystemCallError
233
235
  raise Down::ConnectionError, exception.message
234
- when SocketError
235
- raise Down::ConnectionError, "domain name could not be resolved"
236
- when Errno::ETIMEDOUT,
237
- Timeout::Error
238
- raise Down::TimeoutError, "request timed out"
239
- when defined?(OpenSSL) && OpenSSL::SSL::SSLError
236
+ when OpenSSL::SSL::SSLError
240
237
  raise Down::SSLError, exception.message
241
238
  else
242
239
  raise exception
@@ -1,5 +1,5 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Down
4
- VERSION = "4.1.0"
4
+ VERSION = "4.1.1"
5
5
  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: 4.1.0
4
+ version: 4.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-29 00:00:00.000000000 Z
11
+ date: 2017-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2.1'
47
+ version: '3.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '2.1'
54
+ version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: posix-spawn
57
57
  requirement: !ruby/object:Gem::Requirement