async-rest 0.1.0 → 0.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/async/rest.rb +1 -1
- data/lib/async/rest/json_body.rb +49 -0
- data/lib/async/rest/reference.rb +16 -18
- data/lib/async/rest/resource.rb +40 -27
- data/lib/async/rest/version.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce0c7cbe77ef56cba58f5cd57ad1486a9cf9040d70fea765c6300f51e5590ddb
|
4
|
+
data.tar.gz: 167cf326a9f2195cc0482bd7223cfa62a0ea9bdabce42a20076801bbc72ff9ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6cc434bcd3df1f0c4659e189e2d710650bad4a4a954f483173228d6678fda02d97f95391f1c29bcd3b5610ac318464213570d3febb0a0eb560a58028a9ed0b3a
|
7
|
+
data.tar.gz: e231949363b899e5cc5d7739c8a7dcab667e46fd2a4bea91f766cb7c1683d9c27379049e565b4f7016fa5b0149aa92250f96bcf25b792e976e7a2af2ab6dcc50
|
data/lib/async/rest.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright,
|
1
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -0,0 +1,49 @@
|
|
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 'json'
|
22
|
+
|
23
|
+
module Async
|
24
|
+
module REST
|
25
|
+
class JSONBody
|
26
|
+
def initialize(body)
|
27
|
+
@body = body
|
28
|
+
end
|
29
|
+
|
30
|
+
def close
|
31
|
+
@body = @body.close
|
32
|
+
|
33
|
+
return self
|
34
|
+
end
|
35
|
+
|
36
|
+
def join
|
37
|
+
JSON.parse(@body.join, symbolize_names: true)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.dump(payload)
|
41
|
+
JSON.dump(payload)
|
42
|
+
end
|
43
|
+
|
44
|
+
def finished?
|
45
|
+
@body.finished?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/async/rest/reference.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright,
|
1
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -52,10 +52,10 @@ module Async
|
|
52
52
|
def append(buffer)
|
53
53
|
if @query_string
|
54
54
|
buffer << escape_path(@path) << '?' << query_string
|
55
|
-
buffer << '&' <<
|
55
|
+
buffer << '&' << encode(@parameters) if @parameters
|
56
56
|
else
|
57
57
|
buffer << escape_path(@path)
|
58
|
-
buffer << '?' <<
|
58
|
+
buffer << '?' << encode(@parameters) if @parameters
|
59
59
|
end
|
60
60
|
|
61
61
|
if @fragment
|
@@ -97,16 +97,6 @@ module Async
|
|
97
97
|
|
98
98
|
private
|
99
99
|
|
100
|
-
# According to https://tools.ietf.org/html/rfc3986#section-3.3, we escape non-pchar.
|
101
|
-
NON_PCHAR = /([^a-zA-Z0-9_\-\.~!$&'()*+,;=:@\/]+)/.freeze
|
102
|
-
|
103
|
-
def escape_path(path)
|
104
|
-
encoding = path.encoding
|
105
|
-
path.b.gsub(NON_PCHAR) do |m|
|
106
|
-
'%' + m.unpack('H2' * m.bytesize).join('%').upcase
|
107
|
-
end.force_encoding(encoding)
|
108
|
-
end
|
109
|
-
|
110
100
|
# Escapes a generic string, using percent encoding.
|
111
101
|
def escape(string)
|
112
102
|
encoding = string.encoding
|
@@ -115,19 +105,27 @@ module Async
|
|
115
105
|
end.force_encoding(encoding)
|
116
106
|
end
|
117
107
|
|
118
|
-
|
119
|
-
|
108
|
+
# According to https://tools.ietf.org/html/rfc3986#section-3.3, we escape non-pchar.
|
109
|
+
NON_PCHAR = /([^a-zA-Z0-9_\-\.~!$&'()*+,;=:@\/]+)/.freeze
|
110
|
+
|
111
|
+
# Escapes a path
|
112
|
+
def escape_path(path)
|
113
|
+
encoding = path.encoding
|
114
|
+
path.b.gsub(NON_PCHAR) do |m|
|
115
|
+
'%' + m.unpack('H2' * m.bytesize).join('%').upcase
|
116
|
+
end.force_encoding(encoding)
|
120
117
|
end
|
121
118
|
|
122
|
-
|
119
|
+
# Encodes a hash or array into a query string
|
120
|
+
def encode(value, prefix = nil)
|
123
121
|
case value
|
124
122
|
when Array
|
125
123
|
value.map { |v|
|
126
|
-
|
124
|
+
encode(v, "#{prefix}[]")
|
127
125
|
}.join("&")
|
128
126
|
when Hash
|
129
127
|
value.map { |k, v|
|
130
|
-
|
128
|
+
encode(v, prefix ? "#{prefix}[#{escape(k.to_s)}]" : escape(k.to_s))
|
131
129
|
}.reject(&:empty?).join('&')
|
132
130
|
when nil
|
133
131
|
prefix
|
data/lib/async/rest/resource.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright,
|
1
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -19,45 +19,52 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require_relative 'reference'
|
22
|
+
require_relative 'json_body'
|
22
23
|
|
23
24
|
require 'async/http/client'
|
24
|
-
require '
|
25
|
+
require 'async/http/url_endpoint'
|
25
26
|
|
26
27
|
module Async
|
27
28
|
module REST
|
28
|
-
class
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
class Resource
|
30
|
+
DEFAULT_HEADERS = {
|
31
|
+
'accept-encoding' => 'gzip',
|
32
|
+
'accept' => 'application/json;q=0.9, */*;q=0.8'
|
33
|
+
}
|
32
34
|
|
33
|
-
def
|
34
|
-
@
|
35
|
+
def initialize(client, reference = Reference.parse, headers = DEFAULT_HEADERS, max_redirects: 10)
|
36
|
+
@client = client
|
37
|
+
@reference = reference
|
38
|
+
@headers = headers
|
35
39
|
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
def join
|
40
|
-
JSON.parse(@body.join, symbolize_names: true)
|
40
|
+
@max_redirects = max_redirects
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
44
|
-
|
43
|
+
def close
|
44
|
+
@client.close
|
45
45
|
end
|
46
46
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
class Resource
|
53
|
-
def initialize(client, reference = Reference.parse, headers = {}, max_redirects: 10)
|
54
|
-
@client = client
|
55
|
-
@reference = reference
|
56
|
-
@headers = headers
|
47
|
+
def self.for(url, headers = {}, **options)
|
48
|
+
endpoint = HTTP::URLEndpoint.parse(url)
|
49
|
+
client = HTTP::Client.new(endpoint)
|
57
50
|
|
58
|
-
|
51
|
+
resource = self.new(client, Reference.parse(endpoint.url.request_uri), headers)
|
52
|
+
|
53
|
+
return resource unless block_given?
|
54
|
+
|
55
|
+
begin
|
56
|
+
yield resource
|
57
|
+
ensure
|
58
|
+
resource.close
|
59
|
+
end
|
59
60
|
end
|
60
61
|
|
62
|
+
attr :client
|
63
|
+
attr :reference
|
64
|
+
attr :headers
|
65
|
+
|
66
|
+
attr :max_redirects
|
67
|
+
|
61
68
|
def [] path
|
62
69
|
self.class.new(@client, @reference.nest(path), @headers, max_redirects: @max_redirects)
|
63
70
|
end
|
@@ -85,6 +92,8 @@ module Async
|
|
85
92
|
end
|
86
93
|
|
87
94
|
def process_response(response)
|
95
|
+
response.body = HTTP::InflateBody.for_response(response)
|
96
|
+
|
88
97
|
content_type = response.headers['content-type']
|
89
98
|
|
90
99
|
if wrapper = wrapper_for(content_type)
|
@@ -98,7 +107,11 @@ module Async
|
|
98
107
|
define_method(verb.downcase) do |payload = nil, **parameters, &block|
|
99
108
|
reference = @reference.dup(nil, parameters)
|
100
109
|
|
101
|
-
|
110
|
+
if body = prepare_body(payload)
|
111
|
+
body = HTTP::DeflateBody.for_request(@headers, body)
|
112
|
+
end
|
113
|
+
|
114
|
+
response = self.request(verb, reference.to_str, @headers, body) do |response|
|
102
115
|
process_response(response)
|
103
116
|
end
|
104
117
|
|
data/lib/async/rest/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright,
|
1
|
+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -20,6 +20,6 @@
|
|
20
20
|
|
21
21
|
module Async
|
22
22
|
module REST
|
23
|
-
VERSION = "0.
|
23
|
+
VERSION = "0.2.0"
|
24
24
|
end
|
25
25
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-rest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.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-
|
11
|
+
date: 2018-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async-http
|
@@ -95,6 +95,7 @@ files:
|
|
95
95
|
- Rakefile
|
96
96
|
- async-rest.gemspec
|
97
97
|
- lib/async/rest.rb
|
98
|
+
- lib/async/rest/json_body.rb
|
98
99
|
- lib/async/rest/reference.rb
|
99
100
|
- lib/async/rest/resource.rb
|
100
101
|
- lib/async/rest/version.rb
|