http_streaming_client 0.8.5 → 0.8.6
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 +0 -4
- data/lib/http_streaming_client/client.rb +15 -5
- data/lib/http_streaming_client/decoders/gzip.rb +67 -20
- data/lib/http_streaming_client/errors.rb +2 -0
- data/lib/http_streaming_client/version.rb +1 -1
- data/spec/client_spec.rb +10 -2
- 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: 607b852759a7216b85fa6d820d2bc70a2d50b475
|
4
|
+
data.tar.gz: 49b554701c78b290e3b7e337a1b8fbcc12f0f726
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1d07b0e483dc0e81d83800d05d6170d28f00dad305f6e6f3644ffe96b9bac00ff203a7bd34fadf697245b10520cdb1e303b79442dc0bd6bd3a477bb52b99f63
|
7
|
+
data.tar.gz: a26cf37f5791d4701ca0f0bf74cdedb009fb1a6d1ee58934f15dfad8a12ffb8c3755a3854c95b496fc2ca22bae69c70e8a04d40c7ada2efd54f41c5ead6ca2d2
|
data/README.md
CHANGED
@@ -43,10 +43,6 @@ Or install it yourself as:
|
|
43
43
|
|
44
44
|
$ gem install http_streaming_client
|
45
45
|
|
46
|
-
## Version
|
47
|
-
|
48
|
-
Current release version: 0.8.1 (see <a href="https://github.com/adobe-research/http_streaming_client/releases">RELEASES</a>)
|
49
|
-
|
50
46
|
## Logging
|
51
47
|
|
52
48
|
HTTP protocol trace logging is available as :debug level logging. The gem supports configurable logging to both STDOUT and a log file, and includes a Railtie to use Rails.logger when the gem is included in a Rails application.
|
@@ -97,6 +97,7 @@ module HttpStreamingClient
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def request(method, uri, opts = {}, &block)
|
100
|
+
|
100
101
|
logger.debug("Client::request:#{method}:#{uri}:#{opts}")
|
101
102
|
|
102
103
|
if uri.is_a?(String)
|
@@ -166,6 +167,15 @@ module HttpStreamingClient
|
|
166
167
|
|
167
168
|
logger.debug "response headers:#{response_head[:headers]}"
|
168
169
|
|
170
|
+
if response_head[:code] == 301 then
|
171
|
+
location = response_head[:headers]["Location"]
|
172
|
+
raise InvalidRedirect, "Unable to find Location header for HTTP 301 response" if location.nil?
|
173
|
+
logger.debug "Received HTTP 301 redirect to #{location}, following..."
|
174
|
+
socket.close if !socket.nil? and !socket.closed?
|
175
|
+
opts.delete(:socket)
|
176
|
+
return request(method, location, opts, &block)
|
177
|
+
end
|
178
|
+
|
169
179
|
content_length = response_head[:headers]["Content-Length"].to_i
|
170
180
|
logger.debug "content-length: #{content_length}"
|
171
181
|
|
@@ -200,11 +210,11 @@ module HttpStreamingClient
|
|
200
210
|
logger.debug "response compression detected"
|
201
211
|
if block_given? then
|
202
212
|
decoder = HttpStreamingClient::Decoders::GZip.new { |line|
|
203
|
-
logger.debug "read #{line.size} uncompressed bytes"
|
213
|
+
logger.debug "read #{line.size} uncompressed bytes, decoder queue bytes:#{decoder.size}"
|
204
214
|
block.call(line) unless @interrupted }
|
205
215
|
else
|
206
216
|
decoder = HttpStreamingClient::Decoders::GZip.new { |line|
|
207
|
-
logger.debug "read #{line.size} uncompressed bytes, #{response.size} bytes total"
|
217
|
+
logger.debug "read #{line.size} uncompressed bytes, #{response.size} bytes total, decoder queue bytes:#{decoder.size}"
|
208
218
|
response << line unless @interrupted }
|
209
219
|
end
|
210
220
|
end
|
@@ -237,7 +247,7 @@ module HttpStreamingClient
|
|
237
247
|
return if @interrupted
|
238
248
|
|
239
249
|
if response_compression then
|
240
|
-
|
250
|
+
decoder << partial
|
241
251
|
else
|
242
252
|
if block_given? then
|
243
253
|
yield partial
|
@@ -274,11 +284,11 @@ module HttpStreamingClient
|
|
274
284
|
|
275
285
|
if block_given? then
|
276
286
|
decoder = HttpStreamingClient::Decoders::GZip.new { |line|
|
277
|
-
logger.debug "read #{line.size} uncompressed bytes"
|
287
|
+
logger.debug "read #{line.size} uncompressed bytes, decoder queue bytes:#{decoder.size}"
|
278
288
|
block.call(line) unless @interrupted }
|
279
289
|
else
|
280
290
|
decoder = HttpStreamingClient::Decoders::GZip.new { |line|
|
281
|
-
logger.debug "read #{line.size} uncompressed bytes, #{response.size} bytes total"
|
291
|
+
logger.debug "read #{line.size} uncompressed bytes, #{response.size} bytes total, decoder queue bytes:#{decoder.size}"
|
282
292
|
response << line unless @interrupted }
|
283
293
|
end
|
284
294
|
|
@@ -44,10 +44,41 @@ module HttpStreamingClient
|
|
44
44
|
@packet_callback = packet_callback
|
45
45
|
end
|
46
46
|
|
47
|
+
def nonblock_readline(io)
|
48
|
+
@line_buffer ||= ""
|
49
|
+
ch = nil
|
50
|
+
begin
|
51
|
+
while ch = io.getc
|
52
|
+
@line_buffer += ch
|
53
|
+
if ch == "\n" then
|
54
|
+
result = @line_buffer
|
55
|
+
@line_buffer = ""
|
56
|
+
return result
|
57
|
+
end
|
58
|
+
end
|
59
|
+
rescue Zlib::GzipFile::Error
|
60
|
+
# this is raised on EOF by ZLib, return nil to indicate EOF and leave partial line in the buffer
|
61
|
+
return nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
47
65
|
def <<(compressed_packet)
|
48
66
|
return unless compressed_packet && compressed_packet.size > 0
|
49
|
-
|
50
|
-
|
67
|
+
@buf ||= GZipBufferIO.new
|
68
|
+
@buf << compressed_packet
|
69
|
+
|
70
|
+
# pass at least 2k bytes to GzipReader to avoid zlib EOF
|
71
|
+
if @buf.size > 2048 then
|
72
|
+
|
73
|
+
@gzip ||= Zlib::GzipReader.new @buf
|
74
|
+
|
75
|
+
while true do
|
76
|
+
decompressed_packet = nonblock_readline(@gzip)
|
77
|
+
#logger.debug "decompressed_packet:#{decompressed_packet}"
|
78
|
+
break if decompressed_packet.nil?
|
79
|
+
process_decompressed_packet(decompressed_packet)
|
80
|
+
end
|
81
|
+
end
|
51
82
|
end
|
52
83
|
|
53
84
|
def close
|
@@ -55,26 +86,25 @@ module HttpStreamingClient
|
|
55
86
|
decompressed_packet = ""
|
56
87
|
begin
|
57
88
|
@gzip ||= Zlib::GzipReader.new @buf
|
58
|
-
|
89
|
+
|
90
|
+
while true do
|
91
|
+
decompressed_packet = nonblock_readline(@gzip)
|
92
|
+
#logger.debug "decompressed_packet:#{decompressed_packet}"
|
93
|
+
break if decompressed_packet.nil?
|
94
|
+
process_decompressed_packet(decompressed_packet)
|
95
|
+
end
|
96
|
+
|
59
97
|
rescue Zlib::Error
|
60
98
|
raise DecoderError
|
61
99
|
end
|
62
|
-
process_decompressed_packet(decompressed_packet)
|
63
100
|
end
|
64
101
|
|
65
|
-
|
66
|
-
|
67
|
-
def decompress(compressed_packet)
|
68
|
-
@buf ||= GZipBufferIO.new
|
69
|
-
@buf << compressed_packet
|
70
|
-
|
71
|
-
# pass at least 2k bytes to GzipReader to avoid zlib EOF
|
72
|
-
if @buf.size > 2048
|
73
|
-
@gzip ||= Zlib::GzipReader.new @buf
|
74
|
-
@gzip.readline
|
75
|
-
end
|
102
|
+
def size
|
103
|
+
@buf.size
|
76
104
|
end
|
77
105
|
|
106
|
+
protected
|
107
|
+
|
78
108
|
class GZipBufferIO
|
79
109
|
|
80
110
|
def logger
|
@@ -92,21 +122,38 @@ module HttpStreamingClient
|
|
92
122
|
|
93
123
|
# called by GzipReader
|
94
124
|
def readpartial(length=nil, buffer=nil)
|
95
|
-
logger.debug "GZipBufferIO:
|
125
|
+
logger.debug "GZipBufferIO:readpartial:length:#{length}:@packet_stream:#{@packet_stream.nil? ? 'nil' : 'not null'}"
|
96
126
|
buffer ||= ""
|
97
|
-
|
127
|
+
|
128
|
+
raise EOFError "" if @packet_stream.size == 0
|
129
|
+
|
130
|
+
length ||= @packet_stream.size # read all if a fraction is specified
|
131
|
+
length = [ length, @packet_stream.size ].min # read length or @packet_stream.size, whichever is smaller
|
132
|
+
|
133
|
+
#logger.debug "GZipBufferIO:readpartial:before:psize:#{@packet_stream.size}:bsize:#{buffer.size}:length:#{length}"
|
134
|
+
|
98
135
|
buffer << @packet_stream[0..(length-1)]
|
99
|
-
|
136
|
+
|
137
|
+
if length == @packet_stream.size then
|
138
|
+
@packet_stream = ""
|
139
|
+
else
|
140
|
+
@packet_stream = @packet_stream[length..-1]
|
141
|
+
end
|
142
|
+
|
143
|
+
#logger.debug "GZipBufferIO:readpartial:after:psize:#{@packet_stream.size}:bsize:#{buffer.size}"
|
100
144
|
buffer
|
101
145
|
end
|
102
|
-
|
146
|
+
|
103
147
|
# called by GzipReader
|
104
148
|
def read(length=nil, buffer=nil)
|
149
|
+
logger.debug "read:length:#{length}"
|
150
|
+
return nil if @packet_stream.size == 0
|
105
151
|
readpartial(length, buffer)
|
106
152
|
end
|
107
153
|
|
108
154
|
# called by GzipReader
|
109
155
|
def size
|
156
|
+
logger.debug "size():#{@packet_stream.size}"
|
110
157
|
@packet_stream.size
|
111
158
|
end
|
112
159
|
end
|
@@ -116,7 +163,7 @@ module HttpStreamingClient
|
|
116
163
|
def process_decompressed_packet(decompressed_packet)
|
117
164
|
logger.debug "GZipBufferIO:process_decompressed_packet:size:#{decompressed_packet.nil? ? "nil" : decompressed_packet.size}"
|
118
165
|
if decompressed_packet && decompressed_packet.size > 0
|
119
|
-
@packet_callback.call(decompressed_packet)
|
166
|
+
@packet_callback.call(decompressed_packet) unless @packet_callback.nil?
|
120
167
|
end
|
121
168
|
end
|
122
169
|
|
data/spec/client_spec.rb
CHANGED
@@ -9,9 +9,17 @@ describe HttpStreamingClient do
|
|
9
9
|
it { should_not be_nil}
|
10
10
|
end
|
11
11
|
|
12
|
-
describe "client instance get test" do
|
12
|
+
describe "client instance get test, no chunked transfer encosing and GZIP compression" do
|
13
13
|
client = HttpStreamingClient::Client.new
|
14
|
-
response = client.get "http://
|
14
|
+
response = client.get "http://screamradius.com/"
|
15
|
+
logger.debug "response: #{response}"
|
16
|
+
subject { response }
|
17
|
+
it { should_not be_nil}
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "client instance get test, test 301 redirect" do
|
21
|
+
client = HttpStreamingClient::Client.new(compression: true)
|
22
|
+
response = client.get("https://www.ebay.com/")
|
15
23
|
logger.debug "response: #{response}"
|
16
24
|
subject { response }
|
17
25
|
it { should_not be_nil}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http_streaming_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Tompkins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|