down 3.1.0 → 3.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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/down/chunked_io.rb +70 -29
- data/lib/down/http.rb +9 -13
- data/lib/down/net_http.rb +13 -15
- data/lib/down/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 813656418d3c378ea8a8731355e5b46f830cbb9e
|
|
4
|
+
data.tar.gz: 73e7e5125c7b4a2912672f63512fc822bddb552d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f6a6427ffec868c38a689f0d992af7d6187234cfbdd9c63c94ebeb9192174880742eb58c2f7a7d4faed90c86b9a731a369dbadaa5fc37280cb8ef41b64dbeb90
|
|
7
|
+
data.tar.gz: 615d0c7c046727e07bc0e67b82906d7f5ca508fde7eb6b1f38b9ff6f3db787ab0eea4c055acc4584651a669aca38714a8a41f1320064e10c8ed0f559ebfce52f
|
data/README.md
CHANGED
data/lib/down/chunked_io.rb
CHANGED
|
@@ -7,38 +7,37 @@ module Down
|
|
|
7
7
|
class ChunkedIO
|
|
8
8
|
attr_accessor :size, :data, :encoding
|
|
9
9
|
|
|
10
|
-
def initialize(chunks:, size: nil, on_close:
|
|
11
|
-
@chunks
|
|
12
|
-
@size
|
|
13
|
-
@on_close
|
|
14
|
-
@data
|
|
15
|
-
@encoding
|
|
16
|
-
|
|
17
|
-
@buffer
|
|
18
|
-
@tempfile = Tempfile.new("down-chunked_io", binmode: true) if rewindable
|
|
10
|
+
def initialize(chunks:, size: nil, on_close: nil, data: {}, rewindable: true, encoding: nil)
|
|
11
|
+
@chunks = chunks
|
|
12
|
+
@size = size
|
|
13
|
+
@on_close = on_close
|
|
14
|
+
@data = data
|
|
15
|
+
@encoding = find_encoding(encoding || Encoding::BINARY)
|
|
16
|
+
@rewindable = rewindable
|
|
17
|
+
@buffer = nil
|
|
19
18
|
|
|
20
19
|
retrieve_chunk
|
|
21
20
|
end
|
|
22
21
|
|
|
23
22
|
def each_chunk
|
|
24
|
-
raise IOError, "closed stream" if
|
|
23
|
+
raise IOError, "closed stream" if closed?
|
|
25
24
|
|
|
26
25
|
return enum_for(__method__) if !block_given?
|
|
27
26
|
yield retrieve_chunk until chunks_depleted?
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
def read(length = nil, outbuf = nil)
|
|
31
|
-
raise IOError, "closed stream" if
|
|
30
|
+
raise IOError, "closed stream" if closed?
|
|
32
31
|
|
|
33
32
|
outbuf = outbuf.to_s.replace("").force_encoding(@encoding)
|
|
34
33
|
|
|
35
|
-
if
|
|
36
|
-
|
|
34
|
+
if cache && !cache.eof?
|
|
35
|
+
cache.read(length, outbuf)
|
|
37
36
|
outbuf.force_encoding(@encoding)
|
|
38
37
|
end
|
|
39
38
|
|
|
40
|
-
until outbuf.bytesize == length || chunks_depleted?
|
|
41
|
-
@buffer
|
|
39
|
+
until outbuf.bytesize == length || (@buffer.nil? && chunks_depleted?)
|
|
40
|
+
@buffer = retrieve_chunk if @buffer.nil?
|
|
42
41
|
|
|
43
42
|
buffered_data = if length && length - outbuf.bytesize < @buffer.bytesize
|
|
44
43
|
@buffer.byteslice(0, length - outbuf.bytesize)
|
|
@@ -46,45 +45,87 @@ module Down
|
|
|
46
45
|
@buffer
|
|
47
46
|
end
|
|
48
47
|
|
|
49
|
-
@tempfile.write(buffered_data) if @tempfile
|
|
50
|
-
|
|
51
48
|
outbuf << buffered_data
|
|
52
49
|
|
|
50
|
+
cache.write(buffered_data) if cache
|
|
51
|
+
|
|
53
52
|
if buffered_data.bytesize < @buffer.bytesize
|
|
54
|
-
@buffer
|
|
53
|
+
@buffer = @buffer.byteslice(buffered_data.bytesize..-1)
|
|
55
54
|
else
|
|
56
|
-
@buffer
|
|
55
|
+
@buffer = nil
|
|
57
56
|
end
|
|
58
57
|
end
|
|
59
58
|
|
|
60
|
-
outbuf unless
|
|
59
|
+
outbuf unless outbuf.empty? && length
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def readpartial(maxlen = nil, outbuf = nil)
|
|
63
|
+
raise IOError, "closed stream" if closed?
|
|
64
|
+
|
|
65
|
+
available_length = 0
|
|
66
|
+
available_length += cache.size - cache.pos if cache
|
|
67
|
+
available_length += @buffer.bytesize if @buffer
|
|
68
|
+
|
|
69
|
+
if available_length > 0
|
|
70
|
+
read([available_length, *maxlen].min, outbuf)
|
|
71
|
+
elsif !chunks_depleted?
|
|
72
|
+
read([@next_chunk.bytesize, *maxlen].min, outbuf)
|
|
73
|
+
else
|
|
74
|
+
outbuf.replace("").force_encoding(@encoding) if outbuf
|
|
75
|
+
raise EOFError, "end of file reached"
|
|
76
|
+
end
|
|
61
77
|
end
|
|
62
78
|
|
|
63
79
|
def eof?
|
|
64
|
-
raise IOError, "closed stream" if
|
|
80
|
+
raise IOError, "closed stream" if closed?
|
|
65
81
|
|
|
66
|
-
return false if
|
|
67
|
-
@buffer.
|
|
82
|
+
return false if cache && !cache.eof?
|
|
83
|
+
@buffer.nil? && chunks_depleted?
|
|
68
84
|
end
|
|
69
85
|
|
|
70
86
|
def rewind
|
|
71
|
-
raise IOError, "closed stream" if
|
|
72
|
-
raise IOError, "this Down::ChunkedIO is not rewindable" if
|
|
87
|
+
raise IOError, "closed stream" if closed?
|
|
88
|
+
raise IOError, "this Down::ChunkedIO is not rewindable" if cache.nil?
|
|
73
89
|
|
|
74
|
-
|
|
90
|
+
cache.rewind
|
|
75
91
|
end
|
|
76
92
|
|
|
77
93
|
def close
|
|
78
94
|
return if @closed
|
|
79
95
|
|
|
80
96
|
chunks_fiber.resume(:terminate) if chunks_fiber.alive?
|
|
81
|
-
@buffer
|
|
82
|
-
|
|
97
|
+
@buffer = nil
|
|
98
|
+
cache.close! if cache
|
|
83
99
|
@closed = true
|
|
84
100
|
end
|
|
85
101
|
|
|
102
|
+
def closed?
|
|
103
|
+
!!@closed
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def rewindable?
|
|
107
|
+
@rewindable
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def inspect
|
|
111
|
+
string = String.new
|
|
112
|
+
string << "#<Down::ChunkedIO"
|
|
113
|
+
string << " chunks=#{@chunks.inspect}"
|
|
114
|
+
string << " size=#{size.inspect}"
|
|
115
|
+
string << " encoding=#{encoding.inspect}"
|
|
116
|
+
string << " data=#{data.inspect}"
|
|
117
|
+
string << " on_close=#{@on_close.inspect}"
|
|
118
|
+
string << " rewindable=#{@rewindable.inspect}"
|
|
119
|
+
string << " (closed)" if closed?
|
|
120
|
+
string << ">"
|
|
121
|
+
end
|
|
122
|
+
|
|
86
123
|
private
|
|
87
124
|
|
|
125
|
+
def cache
|
|
126
|
+
@cache ||= Tempfile.new("down-chunked_io", binmode: true) if @rewindable
|
|
127
|
+
end
|
|
128
|
+
|
|
88
129
|
def retrieve_chunk
|
|
89
130
|
chunk = @next_chunk
|
|
90
131
|
@next_chunk = chunks_fiber.resume
|
|
@@ -103,7 +144,7 @@ module Down
|
|
|
103
144
|
break if action == :terminate
|
|
104
145
|
end
|
|
105
146
|
ensure
|
|
106
|
-
@on_close.call
|
|
147
|
+
@on_close.call if @on_close
|
|
107
148
|
end
|
|
108
149
|
end
|
|
109
150
|
end
|
data/lib/down/http.rb
CHANGED
|
@@ -62,9 +62,7 @@ module Down
|
|
|
62
62
|
io.close if io
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
def open(url, **options, &block)
|
|
66
|
-
rewindable = options.delete(:rewindable)
|
|
67
|
-
|
|
65
|
+
def open(url, rewindable: true, **options, &block)
|
|
68
66
|
begin
|
|
69
67
|
response = get(url, **options, &block)
|
|
70
68
|
response_error!(response) if !response.status.success?
|
|
@@ -72,16 +70,14 @@ module Down
|
|
|
72
70
|
request_error!(exception)
|
|
73
71
|
end
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
chunks:
|
|
77
|
-
size:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
Down::ChunkedIO.new(down_options)
|
|
73
|
+
Down::ChunkedIO.new(
|
|
74
|
+
chunks: response.body.enum_for(:each),
|
|
75
|
+
size: response.content_length,
|
|
76
|
+
encoding: response.content_type.charset,
|
|
77
|
+
rewindable: rewindable,
|
|
78
|
+
on_close: (-> { response.connection.close } unless client.persistent?),
|
|
79
|
+
data: { status: response.code, headers: response.headers.to_h, response: response },
|
|
80
|
+
)
|
|
85
81
|
end
|
|
86
82
|
|
|
87
83
|
def get(url, **options, &block)
|
data/lib/down/net_http.rb
CHANGED
|
@@ -180,23 +180,21 @@ module Down
|
|
|
180
180
|
request_error!(exception)
|
|
181
181
|
end
|
|
182
182
|
|
|
183
|
-
|
|
184
|
-
chunks:
|
|
185
|
-
size:
|
|
186
|
-
|
|
183
|
+
Down::ChunkedIO.new(
|
|
184
|
+
chunks: response.enum_for(:read_body),
|
|
185
|
+
size: response["Content-Length"] && response["Content-Length"].to_i,
|
|
186
|
+
encoding: response.type_params["charset"],
|
|
187
|
+
rewindable: options.fetch(:rewindable, true),
|
|
188
|
+
on_close: -> { request.resume }, # close HTTP connnection
|
|
187
189
|
data: {
|
|
188
|
-
status:
|
|
189
|
-
headers:
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
190
|
+
status: response.code.to_i,
|
|
191
|
+
headers: response.each_header.inject({}) { |headers, (downcased_name, value)|
|
|
192
|
+
name = downcased_name.split("-").map(&:capitalize).join("-")
|
|
193
|
+
headers.merge!(name => value)
|
|
194
|
+
},
|
|
193
195
|
response: response,
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
down_params[:rewindable] = options[:rewindable] if options.key?(:rewindable)
|
|
197
|
-
down_params[:encoding] = response.type_params["charset"] if response.type_params["charset"]
|
|
198
|
-
|
|
199
|
-
Down::ChunkedIO.new(down_params)
|
|
196
|
+
},
|
|
197
|
+
)
|
|
200
198
|
end
|
|
201
199
|
|
|
202
200
|
def copy_to_tempfile(basename, io)
|
data/lib/down/version.rb
CHANGED
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: 3.
|
|
4
|
+
version: 3.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: 2017-06-
|
|
11
|
+
date: 2017-06-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|