async-http 0.17.1 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a529cc7156fef7700b2d40a03ae88512fe7ad34efcba524a17a23c5bc4bead5
4
- data.tar.gz: 06e805dcf6fb6dacf9f00317238026f1faa97c7dbe294f22111cf1e333d6c827
3
+ metadata.gz: 283dedfc7cd41922f947682aa3f542ccd5368497a6380602de87c6e38eadd4e0
4
+ data.tar.gz: cb1671a0bd33170eae0c826f081ccf5581135cc07724fd45cc9930186fc83d89
5
5
  SHA512:
6
- metadata.gz: 153939bf31fb232c81681feed848f0f6cf10656609f2755006297a8ff6bb93c7646aa3cfc5f489a680d2c29370fa4069d4de472a7e0860a3b7a932cf60a47c5a
7
- data.tar.gz: da73399d0615db7aaf78fc008e914819b6da85b79c8d25d521ef2d7c756895bdbca4506754344979493e14a53fd95cdb7bec34ce4d332951508ac8d9a711fa7f
6
+ metadata.gz: 01a9422366d59623c93e7a3e17969bfb8d66b2e6213a54f4ef14bbb81d9a23de7e90f8e16dde950630ee2053bf8f7533ea47fcd404cece57de51ee3027e872cb
7
+ data.tar.gz: c20d43c98c4febc062c3e94d0accb04df7a0dc8ddd08b2a83c45d1042b6229bb210f674288cca4f437d57f210255f0fd9ef720c8f2cfedd24c8886625a7193fb
@@ -30,10 +30,17 @@ module Async
30
30
  @stopped = false
31
31
  end
32
32
 
33
+ # Read all chunks until the stream is closed.
34
+ def close
35
+ BufferedBody.for(self)
36
+ end
37
+
38
+ # Have all chunks been read?
33
39
  def finished?
34
40
  @finished
35
41
  end
36
42
 
43
+ # Enumerate all chunks until finished.
37
44
  def each
38
45
  return to_enum unless block_given?
39
46
 
@@ -51,6 +58,7 @@ module Async
51
58
  @finished = true
52
59
  end
53
60
 
61
+ # Read the next available chunk.
54
62
  def read
55
63
  return if @finished
56
64
 
@@ -61,6 +69,7 @@ module Async
61
69
  return chunk
62
70
  end
63
71
 
72
+ # Read all remaining chunks into a single binary string.
64
73
  def join
65
74
  buffer = Async::IO::BinaryString.new
66
75
 
@@ -71,6 +80,7 @@ module Async
71
80
  return buffer
72
81
  end
73
82
 
83
+ # Write a single chunk to the body. Signal completion by calling `#finish`.
74
84
  def write(chunk)
75
85
  if @stopped
76
86
  raise @stopped
@@ -81,19 +91,30 @@ module Async
81
91
  @queue.enqueue(chunk)
82
92
  end
83
93
 
94
+ # Signal that output has finished.
84
95
  def finish
85
96
  @queue.enqueue(nil)
86
97
  end
87
98
  end
88
99
 
89
100
  class BufferedBody
90
- def initialize(body)
91
- @chunks = []
92
- @index = 0
101
+ def self.for(body)
102
+ chunks = []
93
103
 
94
104
  body.each do |chunk|
95
- @chunks << chunk
105
+ chunks << chunk
96
106
  end
107
+
108
+ self.new(chunks)
109
+ end
110
+
111
+ def initialize(chunks)
112
+ @chunks = chunks
113
+ @index = 0
114
+ end
115
+
116
+ def close
117
+ self
97
118
  end
98
119
 
99
120
  def each(&block)
@@ -135,11 +156,9 @@ module Async
135
156
  end
136
157
 
137
158
  def finish
138
- return if self.body.nil? or self.body.finished?
159
+ return if self.body.nil?
139
160
 
140
- unless self.body.is_a? BufferedBody
141
- self.body = BufferedBody.new(self.body)
142
- end
161
+ self.body = self.body.close
143
162
  end
144
163
  end
145
164
  end
@@ -150,6 +169,10 @@ module Async
150
169
  @finished = false
151
170
  end
152
171
 
172
+ def close
173
+ BufferedBody.for(self)
174
+ end
175
+
153
176
  def finished?
154
177
  @finished
155
178
  end
@@ -201,6 +224,10 @@ module Async
201
224
  @stream = stream
202
225
  end
203
226
 
227
+ def close
228
+ BufferedBody.for(self)
229
+ end
230
+
204
231
  def finished?
205
232
  @remaining == 0
206
233
  end
@@ -57,8 +57,8 @@ module Async
57
57
  VERBS = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE']
58
58
 
59
59
  VERBS.each do |verb|
60
- define_method(verb.downcase) do |*args, &block|
61
- self.request(verb, *args, &block)
60
+ define_method(verb.downcase) do |reference, *args, &block|
61
+ self.request(verb, reference.to_str, *args, &block)
62
62
  end
63
63
  end
64
64
 
@@ -67,7 +67,7 @@ module Async
67
67
  response = connection.send_request(@authority, *args)
68
68
 
69
69
  begin
70
- yield response if block_given?
70
+ return yield response if block_given?
71
71
  ensure
72
72
  # This forces the stream to complete reading.
73
73
  response.finish
@@ -0,0 +1,124 @@
1
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'zlib'
22
+
23
+ module Async
24
+ module HTTP
25
+ class DeflateBody
26
+ DEFLATE = -Zlib::MAX_WBITS
27
+ GZIP = Zlib::MAX_WBITS | 16
28
+
29
+ ENCODINGS = {
30
+ 'deflate' => DEFLATE,
31
+ 'gzip' => GZIP,
32
+ }
33
+
34
+ def self.for_request(headers, body, *args)
35
+ if content_encoding = headers['content-encoding']
36
+ if encoding = ENCODINGS[content_encoding]
37
+ return self.for(body, encoding, *args)
38
+ end
39
+ end
40
+
41
+ return body
42
+ end
43
+
44
+ def self.for(body, encoding = GZIP, level = Zlib::DEFAULT_COMPRESSION)
45
+ self.new(body, Zlib::Deflate.new(level, encoding))
46
+ end
47
+
48
+ def initialize(body, stream)
49
+ @body = body
50
+ @stream = stream
51
+ end
52
+
53
+ def each(&block)
54
+ return to_enum unless block_given?
55
+
56
+ while chunk = self.read
57
+ yield chunk
58
+ end
59
+ end
60
+
61
+ def read
62
+ return if @stream.finished?
63
+
64
+ if chunk = @body.read
65
+ return @stream.deflate(chunk, Zlib::SYNC_FLUSH)
66
+ else
67
+ chunk = @stream.finish
68
+
69
+ return chunk.empty? ? nil : chunk
70
+ end
71
+ end
72
+
73
+ def close
74
+ @body = @body.close
75
+
76
+ return self
77
+ end
78
+
79
+ def join
80
+ buffer = Async::IO::BinaryString.new
81
+
82
+ while chunk = self.read
83
+ buffer << chunk
84
+ end
85
+
86
+ return buffer
87
+ end
88
+
89
+ def finished?
90
+ @body.finished?
91
+ end
92
+ end
93
+
94
+ class InflateBody < DeflateBody
95
+ def self.for_response(response)
96
+ if content_encoding = response.headers['content-encoding']
97
+ if encoding = ENCODINGS[content_encoding]
98
+ return self.for(response.body, encoding)
99
+ end
100
+
101
+ raise ArgumentError.new("Unsupported content encoding: #{content_encoding.inspect}")
102
+ end
103
+
104
+ return response.body
105
+ end
106
+
107
+ def self.for(body, encoding = GZIP)
108
+ self.new(body, Zlib::Inflate.new(encoding))
109
+ end
110
+
111
+ def read
112
+ return if @stream.finished?
113
+
114
+ if chunk = @body.read
115
+ chunk = @stream.inflate(chunk)
116
+ else
117
+ chunk = @stream.finish
118
+ end
119
+
120
+ return chunk.empty? ? nil : chunk
121
+ end
122
+ end
123
+ end
124
+ end
@@ -35,6 +35,10 @@ module Async
35
35
  status >= 300 && status < 400
36
36
  end
37
37
 
38
+ def preserve_method?
39
+ status == 307 || status == 308
40
+ end
41
+
38
42
  def failure?
39
43
  status >= 400 && status < 600
40
44
  end
@@ -20,6 +20,6 @@
20
20
 
21
21
  module Async
22
22
  module HTTP
23
- VERSION = "0.17.1"
23
+ VERSION = "0.18.0"
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.1
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-12 00:00:00.000000000 Z
11
+ date: 2018-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -116,7 +116,6 @@ extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
118
  - ".gitignore"
119
- - ".gitmodules"
120
119
  - ".rspec"
121
120
  - ".travis.yml"
122
121
  - Gemfile
@@ -126,6 +125,7 @@ files:
126
125
  - lib/async/http.rb
127
126
  - lib/async/http/body.rb
128
127
  - lib/async/http/client.rb
128
+ - lib/async/http/deflate_body.rb
129
129
  - lib/async/http/pool.rb
130
130
  - lib/async/http/protocol.rb
131
131
  - lib/async/http/protocol/http1.rb
@@ -1,3 +0,0 @@
1
- [submodule "ext/http-parser"]
2
- path = ext/http-parser
3
- url = https://github.com/nodejs/http-parser