uv-rays 2.1.3 → 2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5e3a19099c48894d72cc8564ebc6ba7064f0e29
4
- data.tar.gz: de7efbff60dcd1a46422a7f0ac5c6987c304f878
3
+ metadata.gz: c507e6f1bbe2ce62f99bbf41b609e08bef817d67
4
+ data.tar.gz: 1bf6c856840ccfcd93e1ee1b9a83c15aaae391f0
5
5
  SHA512:
6
- metadata.gz: b18f154b1a634972ac6a44d0e9bd0469449a11ffceeb1ba8576b23135b24573917cec7e2f9b585816ca5f0a3241b9041f9cf5b4075e83cb2419b5ecf67c06464
7
- data.tar.gz: ad62948fc3168d392e5e22cfa74da92689811947fcc632982b3706b34b44909cb6823f3a9fe6f00e73859b4cb643c9b9e6a4dd2e9e871e4d426089759fbe3cc5
6
+ metadata.gz: 63fe644aff1ded42bd47669e6eab04815d8869c78c5e6a84010dfd8c1ec32cc9e2fce46ac8aacdd58219a3c782da758c7899f366e267971c209c4305734ed9f1
7
+ data.tar.gz: 419e10addcc8a7354f163c8d00355930bed4f894a14669723b476921eb7da030f40081f50a0f236d41331bf08bee88b3cdd3d5bcf5c7cab84bf47b100694c0bd
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true, encoding: ASCII-8BIT
2
+
3
+ module Handsoap
4
+ module Http
5
+ module Drivers
6
+ class LibuvDriver < AbstractDriver
7
+ def self.load!
8
+ require 'uv-rays'
9
+ end
10
+
11
+ def send_http_request_async(request)
12
+ endp = ::UV::HttpEndpoint.new(request.url)
13
+
14
+ if request.username && request.password
15
+ request.headers['Authorization'] = [request.username, request.password]
16
+ end
17
+
18
+ req = endp.request(request.http_method, {
19
+ headers: request.headers,
20
+ body: request.body
21
+ })
22
+
23
+ deferred = ::Handsoap::Deferred.new
24
+ req.then do |resp|
25
+ # Downcase headers and convert values to arrays
26
+ headers = Hash[resp.map { |k, v| [k.to_s.downcase, Array(v)] }]
27
+ http_response = parse_http_part(headers, resp.body, resp.status)
28
+ deferred.trigger_callback http_response
29
+ end
30
+ req.catch do |err|
31
+ deferred.trigger_errback err
32
+ end
33
+ deferred
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,50 @@
1
+ require 'httpi'
2
+
3
+ module HTTPI; end
4
+ module HTTPI::Adapter; end
5
+ class HTTPI::Adapter::Libuv < HTTPI::Adapter::Base
6
+ register :libuv, deps: %w(uv-rays)
7
+
8
+ def initialize(request)
9
+ @request = request
10
+ @client = ::UV::HttpEndpoint.new request.url
11
+ end
12
+
13
+ attr_reader :client
14
+
15
+ def request(method)
16
+ @client.inactivity_timeout = @request.read_timeout if @request.read_timeout && @request.read_timeout > 0
17
+
18
+ req = {
19
+ path: @request.url,
20
+ headers: @request.headers,
21
+ body: @request.body
22
+ }
23
+
24
+ auth = @request.auth
25
+ type = auth.type
26
+ if auth.type
27
+ creds = auth.credentials
28
+
29
+ case auth.type
30
+ when :basic
31
+ req[:headers][:Authorization] = creds
32
+ when :digest
33
+ req[:digest] = {
34
+ user: creds[0],
35
+ password: creds[1]
36
+ }
37
+ when :ntlm
38
+ req[:ntlm] = {
39
+ username: creds[0],
40
+ password: creds[1],
41
+ domain: creds[2] || ''
42
+ }
43
+ end
44
+ end
45
+
46
+ # Use co-routines to make non-blocking requests
47
+ response = co @client.request(method, req)
48
+ ::HTTPI::Response.new(response.status, response, response.body)
49
+ end
50
+ end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_support/hash_with_indifferent_access'
4
+
3
5
  module UV
4
6
  module Http
5
- class Headers < Hash
7
+ class Headers < ::ActiveSupport::HashWithIndifferentAccess
6
8
  # The HTTP version returned
7
9
  attr_accessor :http_version
8
10
 
@@ -79,27 +81,29 @@ module UV
79
81
  end
80
82
 
81
83
  def on_header_field(parser, data)
82
- @header = data.to_sym
84
+ @header = data
83
85
  end
84
86
 
85
87
  def on_header_value(parser, data)
86
88
  case @header
87
- when :"Set-Cookie"
89
+ when 'Set-Cookie'
88
90
  @request.set_cookie(data)
89
91
 
90
- when :Connection
92
+ when 'Connection'
91
93
  # Overwrite the default
92
94
  @close_connection = data == 'close'
93
95
 
94
- when :"Transfer-Encoding"
96
+ when 'Transfer-Encoding'
95
97
  # If chunked we'll buffer streaming data for notification
96
98
  @chunked = data == 'chunked'
97
99
 
98
100
  end
99
101
 
102
+ # Duplicate headers we'll place into an array
100
103
  current = @headers[@header]
101
104
  if current
102
- @headers[@header] = "#{current}, #{data}"
105
+ arr = @headers[@header] = Array(current)
106
+ arr << data
103
107
  else
104
108
  @headers[@header] = data
105
109
  end
@@ -146,7 +150,7 @@ module UV
146
150
  def eof
147
151
  return if @request.nil?
148
152
 
149
- if @headers_complete && (@headers[:'Content-Length'].nil? || @request.method == :head)
153
+ if @headers_complete && (@headers['Content-Length'].nil? || @request.method == :head)
150
154
  on_message_complete(nil)
151
155
  else
152
156
  # Reject if this is a partial response
@@ -31,14 +31,21 @@ module UV
31
31
  def initialize(endpoint, options)
32
32
  super(endpoint.thread, endpoint.thread.defer)
33
33
 
34
- @path = options[:path]
35
- @method = options[:method]
36
-
37
34
  @host = endpoint.host
38
35
  @port = endpoint.port
36
+ @encoded_host = endpoint.encoded_host
37
+
38
+ path = options[:path]
39
+ if path.is_a?(::URI)
40
+ @path = path.to_s.split(@encoded_host)[1] || '/'
41
+ else
42
+ @path = path
43
+ end
44
+
45
+ @method = options[:method]
39
46
  @cookiejar = endpoint.cookiejar
40
47
  @middleware = endpoint.middleware
41
- @uri = "#{endpoint.scheme}://#{encode_host(@host, @port)}#{@path}"
48
+ @uri = "#{endpoint.scheme}://#{@encoded_host}#{@path}"
42
49
  endpoint = nil
43
50
 
44
51
  @options = options
@@ -179,14 +186,6 @@ module UV
179
186
  protected
180
187
 
181
188
 
182
- def encode_host(host, port)
183
- if port.nil? || port == 80 || port == 443
184
- host
185
- else
186
- host + ":#{port}"
187
- end
188
- end
189
-
190
189
  def build_request
191
190
  head = @options[:headers] ? munge_header_keys(@options[:headers]) : {}
192
191
 
@@ -203,7 +202,7 @@ module UV
203
202
  end
204
203
 
205
204
  # Set the Host header if it hasn't been specified already
206
- head['host'] ||= encode_host(@host, @port)
205
+ head['host'] ||= @encoded_host
207
206
 
208
207
  # Set the User-Agent if it hasn't been specified
209
208
  if !head.key?('user-agent')
@@ -94,9 +94,13 @@ module UV
94
94
  @tls_options = options[:tls_options] || {}
95
95
  @inactivity_timeout = options[:inactivity_timeout] || 10000
96
96
 
97
- uri = URI.parse host
97
+ uri = host.is_a?(::URI) ? host : ::URI.parse(host)
98
98
  @port = uri.port
99
99
  @host = uri.host
100
+
101
+ default_port = uri.port == uri.default_port
102
+ @encoded_host = default_port ? @host : "#{@host}:#{@port}"
103
+
100
104
  @scheme = uri.scheme
101
105
  @tls = @scheme == 'https'
102
106
  @cookiejar = CookieJar.new
@@ -104,9 +108,9 @@ module UV
104
108
  end
105
109
 
106
110
 
107
- attr_reader :inactivity_timeout, :thread
108
- attr_reader :tls_options, :port, :host, :tls, :scheme
109
- attr_reader :cookiejar, :middleware
111
+ attr_accessor :inactivity_timeout
112
+ attr_reader :tls_options, :port, :host, :tls, :scheme, :encoded_host
113
+ attr_reader :cookiejar, :middleware, :thread
110
114
 
111
115
 
112
116
  def get(options = {}); request(:get, options); end
@@ -120,7 +124,7 @@ module UV
120
124
 
121
125
  def request(method, options = {})
122
126
  options = @options.merge(options)
123
- options[:method] = method
127
+ options[:method] = method.to_sym
124
128
 
125
129
  # Setup the request with callbacks
126
130
  request = Http::Request.new(self, options)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module UV
4
- VERSION = '2.1.3'
4
+ VERSION = '2.2.0'
5
5
  end
@@ -218,6 +218,30 @@ describe UV::HttpEndpoint do
218
218
  expect(@response.body).to eq('y')
219
219
  end
220
220
 
221
+ it "should send a request then receive a response using httpi" do
222
+ require 'httpi/adapter/libuv'
223
+ HTTPI.adapter = :libuv
224
+
225
+ @reactor.run { |reactor|
226
+ tcp = UV.start_server '127.0.0.1', 3250, HttpServer
227
+
228
+ begin
229
+ request = HTTPI::Request.new("http://127.0.0.1:3250/whatwhat")
230
+ @response = HTTPI.get(request)
231
+ rescue => e
232
+ @general_failure << e
233
+ ensure
234
+ tcp.close
235
+ @reactor.stop
236
+ end
237
+ }
238
+
239
+ expect(@general_failure).to eq([])
240
+ expect(@response.headers["Content-type"]).to eq('text/html')
241
+ expect(@response.code).to eq(200)
242
+ expect(@response.raw_body).to eq('y')
243
+ end
244
+
221
245
  it 'should be garbage collected', mri_only: true do
222
246
  require 'weakref'
223
247
  require 'objspace'
data/uv-rays.gemspec CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |gem|
21
21
  gem.add_runtime_dependency 'parse-cron', '~> 0.1' # CRON calculations
22
22
  gem.add_runtime_dependency 'addressable', '~> 2.4' # URI parser
23
23
  gem.add_runtime_dependency 'http-parser', '~> 1.2' # HTTP tokeniser
24
+ gem.add_runtime_dependency 'activesupport', '>= 4', '< 6'
24
25
 
25
26
  # HTTP authentication helpers
26
27
  gem.add_runtime_dependency 'rubyntlm', '~> 0.6'
@@ -29,6 +30,7 @@ Gem::Specification.new do |gem|
29
30
  gem.add_development_dependency 'rspec', '~> 3.5'
30
31
  gem.add_development_dependency 'rake', '~> 11.2'
31
32
  gem.add_development_dependency 'yard', '~> 0.9'
33
+ gem.add_development_dependency 'httpi', '~> 2.4.2'
32
34
 
33
35
  gem.files = Dir["{lib}/**/*"] + %w(Rakefile uv-rays.gemspec README.md LICENSE)
34
36
  gem.test_files = Dir["spec/**/*"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uv-rays
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.3
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen von Takach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-05 00:00:00.000000000 Z
11
+ date: 2017-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: libuv
@@ -122,6 +122,26 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.2'
125
+ - !ruby/object:Gem::Dependency
126
+ name: activesupport
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '4'
132
+ - - "<"
133
+ - !ruby/object:Gem::Version
134
+ version: '6'
135
+ type: :runtime
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '4'
142
+ - - "<"
143
+ - !ruby/object:Gem::Version
144
+ version: '6'
125
145
  - !ruby/object:Gem::Dependency
126
146
  name: rubyntlm
127
147
  requirement: !ruby/object:Gem::Requirement
@@ -192,6 +212,20 @@ dependencies:
192
212
  - - "~>"
193
213
  - !ruby/object:Gem::Version
194
214
  version: '0.9'
215
+ - !ruby/object:Gem::Dependency
216
+ name: httpi
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - "~>"
220
+ - !ruby/object:Gem::Version
221
+ version: 2.4.2
222
+ type: :development
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - "~>"
227
+ - !ruby/object:Gem::Version
228
+ version: 2.4.2
195
229
  description: Opinionated abstractions for Libuv
196
230
  email:
197
231
  - steve@cotag.me
@@ -204,6 +238,8 @@ files:
204
238
  - README.md
205
239
  - Rakefile
206
240
  - lib/faraday/adapter/libuv.rb
241
+ - lib/handsoap/http/drivers/libuv_driver.rb
242
+ - lib/httpi/adapter/libuv.rb
207
243
  - lib/uv-rays.rb
208
244
  - lib/uv-rays/abstract_tokenizer.rb
209
245
  - lib/uv-rays/buffered_tokenizer.rb