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 +4 -4
- data/lib/handsoap/http/drivers/libuv_driver.rb +38 -0
- data/lib/httpi/adapter/libuv.rb +50 -0
- data/lib/uv-rays/http/parser.rb +11 -7
- data/lib/uv-rays/http/request.rb +12 -13
- data/lib/uv-rays/http_endpoint.rb +9 -5
- data/lib/uv-rays/version.rb +1 -1
- data/spec/http_endpoint_spec.rb +24 -0
- data/uv-rays.gemspec +2 -0
- metadata +38 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c507e6f1bbe2ce62f99bbf41b609e08bef817d67
|
4
|
+
data.tar.gz: 1bf6c856840ccfcd93e1ee1b9a83c15aaae391f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/uv-rays/http/parser.rb
CHANGED
@@ -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 <
|
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
|
84
|
+
@header = data
|
83
85
|
end
|
84
86
|
|
85
87
|
def on_header_value(parser, data)
|
86
88
|
case @header
|
87
|
-
when
|
89
|
+
when 'Set-Cookie'
|
88
90
|
@request.set_cookie(data)
|
89
91
|
|
90
|
-
when
|
92
|
+
when 'Connection'
|
91
93
|
# Overwrite the default
|
92
94
|
@close_connection = data == 'close'
|
93
95
|
|
94
|
-
when
|
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] =
|
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[
|
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
|
data/lib/uv-rays/http/request.rb
CHANGED
@@ -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}://#{
|
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'] ||=
|
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
|
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
|
-
|
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)
|
data/lib/uv-rays/version.rb
CHANGED
data/spec/http_endpoint_spec.rb
CHANGED
@@ -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.
|
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-
|
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
|