http_streaming_client 0.8.5 → 0.8.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|