restify 1.9.0.rc1 → 1.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +119 -48
- data/README.md +10 -12
- data/lib/restify/adapter/em.rb +2 -2
- data/lib/restify/adapter/pooled_em.rb +5 -5
- data/lib/restify/adapter/typhoeus.rb +20 -11
- data/lib/restify/context.rb +2 -15
- data/lib/restify/error.rb +56 -0
- data/lib/restify/global.rb +2 -2
- data/lib/restify/link.rb +4 -4
- data/lib/restify/promise.rb +8 -0
- data/lib/restify/relation.rb +1 -0
- data/lib/restify/timeout.rb +1 -0
- data/lib/restify/version.rb +2 -2
- data/spec/restify/context_spec.rb +2 -2
- data/spec/restify/error_spec.rb +70 -0
- data/spec/restify/features/response_errors.rb +79 -0
- data/spec/restify/global_spec.rb +1 -1
- data/spec/restify/promise_spec.rb +7 -0
- data/spec/restify_spec.rb +0 -2
- data/spec/spec_helper.rb +10 -6
- metadata +21 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2b5dacc128de6cbfed604453544f51eaeffd16b9b6cb83f5353ecca66d24a8d
|
4
|
+
data.tar.gz: 5c3eba335362aea288f851327fa96262e5b464b9a747b092955241bb362e9c0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32569c3544a1ac6734b3c81c1e2b6a46ea7dba324c1f71f5e85bd1df93b8b73bb70114a7cec37dd8e38e561a821e674e8c437c78757d78df75e1e51b1a5a79f8
|
7
|
+
data.tar.gz: 6f03d156fcc20e0dfba3d7fda0a5c7851ff5d9342fbb9b50c4d90d1f43bf65e92f0ecabb714c4023ce4ca8cfb95b231abd7ea5d1e05339e839ea046b17f3d1fe
|
data/CHANGELOG.md
CHANGED
@@ -1,82 +1,153 @@
|
|
1
1
|
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
2
3
|
|
3
|
-
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
4
6
|
|
5
|
-
* Add HEAD request method (#16)
|
6
7
|
|
7
|
-
## 1.7.0
|
8
8
|
|
9
|
-
|
9
|
+
## Unreleased
|
10
|
+
---
|
10
11
|
|
11
|
-
|
12
|
+
### New
|
12
13
|
|
13
|
-
|
14
|
+
### Changes
|
14
15
|
|
15
|
-
|
16
|
+
### Fixes
|
16
17
|
|
17
|
-
|
18
|
-
* Add MessagePack processor enabled by default
|
18
|
+
### Breaks
|
19
19
|
|
20
|
-
## 1.4.4
|
21
20
|
|
22
|
-
|
23
|
-
|
21
|
+
## 1.13.0 - (2020-06-12)
|
22
|
+
---
|
24
23
|
|
25
|
-
|
24
|
+
### New
|
25
|
+
* typhoeus: Support setting per-request libcurl options on adapter
|
26
|
+
* typhoeus: Enable short TCP keepalive probes by default (5s/5s)
|
26
27
|
|
27
|
-
* Add advanced logging capabilities using logging gem
|
28
|
-
* Improve compatibility with webmocks returning `nil` as headers
|
29
28
|
|
30
|
-
## 1.
|
29
|
+
## 1.12.0 - (2020-04-01)
|
30
|
+
---
|
31
31
|
|
32
|
-
|
32
|
+
### Added
|
33
|
+
* Explicit exception class for HTTP status code 410 (Gone)
|
33
34
|
|
34
|
-
|
35
|
+
### Changed
|
35
36
|
|
36
|
-
|
37
|
-
*
|
37
|
+
### Fixed
|
38
|
+
* `GatewayError` exception classes introduced in v1.11.0 now properly inherit from `ServerError` (#30)
|
38
39
|
|
39
|
-
## 1.3.1
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
## 1.11.0 - (2019-07-11)
|
42
|
+
### Added
|
43
|
+
* Explicit exception classes for HTTP status codes 500, 502, 503, 504
|
43
44
|
|
44
|
-
## 1.
|
45
|
+
## 1.10.0 - 2018-12-11
|
46
|
+
### Changed
|
47
|
+
- Raise more specific error on a few status codes (#17)
|
48
|
+
- Complete promises with an empty list (but a list) of dependencies (#18)
|
45
49
|
|
46
|
-
|
47
|
-
|
50
|
+
## 1.9.0 - 2018-11-13
|
51
|
+
### Changed
|
52
|
+
- Do not raise error on 3XX responses but return responses
|
48
53
|
|
49
|
-
## 1.
|
54
|
+
## 1.8.0 - 2018-08-22
|
55
|
+
### Added
|
56
|
+
- Add HEAD request method (#16)
|
50
57
|
|
51
|
-
|
58
|
+
## 1.7.0 - 2018-08-15
|
59
|
+
### Added
|
60
|
+
- Introduce promise dependency timeouts (#15)
|
52
61
|
|
53
|
-
## 1.
|
62
|
+
## 1.6.0 - 2018-08-09
|
63
|
+
### Changed
|
64
|
+
- Specify headers on restify clients and individual requests (#14)
|
54
65
|
|
55
|
-
|
56
|
-
|
66
|
+
## 1.5.0 - 2018-07-31
|
67
|
+
### Added
|
68
|
+
- Add MessagePack processor enabled by default
|
57
69
|
|
58
|
-
|
70
|
+
### Changed
|
71
|
+
- Tune typhoeus adapter to be more race-condition resilent
|
59
72
|
|
60
|
-
|
61
|
-
|
73
|
+
## 1.4.4 - 2018-07-13
|
74
|
+
### Added
|
75
|
+
- Add `#request` to `NetworkError` to ease debugging
|
62
76
|
|
63
|
-
|
77
|
+
### Changed
|
78
|
+
- Fix race condition in typhoeus adapter
|
64
79
|
|
65
|
-
|
66
|
-
|
80
|
+
## 1.4.3 - 2017-11-15
|
81
|
+
### Added
|
82
|
+
- Add advanced logging capabilities using logging gem
|
67
83
|
|
68
|
-
|
84
|
+
### Changed
|
85
|
+
- Improve compatibility with webmocks returning `nil` as headers
|
69
86
|
|
70
|
-
|
71
|
-
|
72
|
-
|
87
|
+
## 1.4.1 - 2017-11-15
|
88
|
+
### Changed
|
89
|
+
- Fix possible deadlock issues
|
73
90
|
|
74
|
-
##
|
91
|
+
## 1.4.0 - 2017-11-10
|
92
|
+
### Added
|
93
|
+
- Add timeout option to requests (only supported by typhoeus adapter)
|
75
94
|
|
76
|
-
|
77
|
-
|
95
|
+
### Changed
|
96
|
+
- Fix possible concurrency issue with typhoeus adapter
|
97
|
+
|
98
|
+
## 1.3.1 - 2017-11-10
|
99
|
+
### Changed
|
100
|
+
- Improve typhoeus adapters initial request queuing
|
101
|
+
- Disable default pipelining
|
102
|
+
|
103
|
+
## 1.3.0 - 2017-11-08
|
104
|
+
### Changed
|
105
|
+
- Improve typhoeus adapter to better utilize concurrency
|
106
|
+
- Default to new typhoeus adapter
|
107
|
+
|
108
|
+
## 1.2.1 - 2017-10-30
|
109
|
+
### Changed
|
110
|
+
- Fix issue with Ruby 2.2 compatibility
|
111
|
+
|
112
|
+
## 1.2.0 - 2017-10-30
|
113
|
+
### Added
|
114
|
+
- Add experimental PooledEM adapter (#10)
|
115
|
+
|
116
|
+
### Changed
|
117
|
+
- Improve marshaling of resources
|
118
|
+
|
119
|
+
## 1.1.0 - 2017-05-12
|
120
|
+
### Added
|
121
|
+
- Add shortcuts for creating fulfilled / rejected promises (#6)
|
122
|
+
|
123
|
+
### Changed
|
124
|
+
- Return response body if no processor matches (#7)
|
125
|
+
|
126
|
+
## 1.0.0 - 2016-08-22
|
127
|
+
### Added
|
128
|
+
- Experimental cache API doing nothing for now
|
129
|
+
|
130
|
+
### Changed
|
131
|
+
- Use `~> 1.0` of `concurrent-ruby`
|
132
|
+
|
133
|
+
## 0.5.0 - 2016-04-04
|
134
|
+
### Added
|
135
|
+
- Add `sync` option to typhoeus adapter
|
136
|
+
- Add registry for storing entry points
|
137
|
+
|
138
|
+
### Changed
|
139
|
+
- Make eventmachine based adapter default
|
140
|
+
|
141
|
+
## 0.4.0 - 2016-02-24
|
142
|
+
### Added
|
143
|
+
- Add method to explicit access resource data
|
144
|
+
|
145
|
+
### Changed
|
146
|
+
- Use typhoeus as default adapter
|
147
|
+
- `Restify.new` returns relation now instead of resource
|
148
|
+
|
149
|
+
### Removed
|
150
|
+
- Drop obligation in favor of simple Concurrent::IVar based promise class.
|
78
151
|
Notable changes:
|
79
|
-
|
80
|
-
|
81
|
-
* Use typhoeus as default adapter
|
82
|
-
* `Restify.new` returns relation now instead of resource
|
152
|
+
- Returned object us of type `Restify::Promise` now.
|
153
|
+
- `value` will not raise exception but return `nil` in case of failure. Use `value!` for old behavior.
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Restify
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/jgraichen/restify.svg?branch=master)](https://travis-ci.org/jgraichen/restify)
|
4
|
+
[![Code Quality](https://codebeat.co/badges/18ffe6b7-8239-493a-b5b6-be329b9f275d)](https://codebeat.co/projects/github-com-jgraichen-restify-master)
|
4
5
|
|
5
6
|
Restify is an hypermedia REST client that does parallel, concurrent and keep-alive requests by default.
|
6
7
|
|
@@ -14,20 +15,17 @@ Restify is build upon the following libraries:
|
|
14
15
|
* [addressable](https://github.com/sporkmonger/addressable)
|
15
16
|
* [typhoeus](https://github.com/typhoeus/typhoeus)
|
16
17
|
|
17
|
-
It has optional HTTP adapters using:
|
18
|
-
|
19
|
-
* [em-http-request](https://github.com/igrigorik/em-http-request)
|
20
|
-
|
21
18
|
The HTTP adapters are mostly run in a background thread and may not survive mid-application forks.
|
22
19
|
|
23
|
-
|
20
|
+
Restify includes processors to parse responses and to extract links between resources. The following formats are can be parsed:
|
24
21
|
|
25
|
-
*
|
26
|
-
* MessagePack
|
22
|
+
* JSON
|
23
|
+
* MessagePack
|
27
24
|
|
28
|
-
|
25
|
+
Links are extracted from
|
29
26
|
|
30
|
-
|
27
|
+
* HTTP Link header
|
28
|
+
* Github-style relations in payloads
|
31
29
|
|
32
30
|
### Planned features
|
33
31
|
|
@@ -105,9 +103,9 @@ commit = repo.rel(:commits).get.value.first
|
|
105
103
|
And print it:
|
106
104
|
|
107
105
|
```ruby
|
108
|
-
puts "Last commit: #{commit[
|
109
|
-
puts "By #{commit[
|
110
|
-
puts "#{commit[
|
106
|
+
puts "Last commit: #{commit['sha']}"
|
107
|
+
puts "By #{commit['commit']['author']['name']} <#{commit['commit']['author']['email']}>"
|
108
|
+
puts "#{commit['commit']['message']}"
|
111
109
|
```
|
112
110
|
|
113
111
|
See commented example in main spec [`spec/restify_spec.rb`](https://github.com/jgraichen/restify/blob/master/spec/restify_spec.rb#L100) or in the `examples` directory.
|
data/lib/restify/adapter/em.rb
CHANGED
@@ -63,8 +63,8 @@ module Restify
|
|
63
63
|
query: request.uri.normalized_query,
|
64
64
|
body: request.body,
|
65
65
|
head: request.headers
|
66
|
-
rescue Exception =>
|
67
|
-
writer.reject
|
66
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
67
|
+
writer.reject e
|
68
68
|
requests.shift unless pipeline?
|
69
69
|
return
|
70
70
|
end
|
@@ -200,9 +200,9 @@ module Restify
|
|
200
200
|
@pool = Pool.new(**kwargs)
|
201
201
|
end
|
202
202
|
|
203
|
-
# rubocop:disable MethodLength
|
204
|
-
# rubocop:disable AbcSize
|
205
|
-
# rubocop:disable BlockLength
|
203
|
+
# rubocop:disable Metrics/MethodLength
|
204
|
+
# rubocop:disable Metrics/AbcSize
|
205
|
+
# rubocop:disable Metrics/BlockLength
|
206
206
|
def call_native(request, writer)
|
207
207
|
next_tick do
|
208
208
|
defer = @pool.get(request)
|
@@ -241,9 +241,9 @@ module Restify
|
|
241
241
|
@pool.remove(conn)
|
242
242
|
writer.reject(req.error)
|
243
243
|
end
|
244
|
-
rescue Exception =>
|
244
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
245
245
|
@pool.remove(conn)
|
246
|
-
writer.reject(
|
246
|
+
writer.reject(e)
|
247
247
|
end
|
248
248
|
end
|
249
249
|
end
|
@@ -16,19 +16,28 @@ module Restify
|
|
16
16
|
'Transfer-Encoding' => ''
|
17
17
|
}.freeze
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
DEFAULT_OPTIONS = {
|
20
|
+
followlocation: true,
|
21
|
+
tcp_keepalive: true,
|
22
|
+
tcp_keepidle: 5,
|
23
|
+
tcp_keepintvl: 5
|
24
|
+
}.freeze
|
25
|
+
|
26
|
+
def initialize(sync: false, options: {}, **kwargs)
|
27
|
+
@sync = sync
|
28
|
+
@hydra = ::Typhoeus::Hydra.new(**kwargs)
|
29
|
+
@mutex = Mutex.new
|
30
|
+
@signal = ConditionVariable.new
|
31
|
+
@thread = nil
|
32
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
24
33
|
end
|
25
34
|
|
26
35
|
def sync?
|
27
36
|
@sync
|
28
37
|
end
|
29
38
|
|
30
|
-
# rubocop:disable AbcSize
|
31
|
-
# rubocop:disable MethodLength
|
39
|
+
# rubocop:disable Metrics/AbcSize
|
40
|
+
# rubocop:disable Metrics/MethodLength
|
32
41
|
def call_native(request, writer)
|
33
42
|
req = convert(request, writer)
|
34
43
|
|
@@ -56,15 +65,15 @@ module Restify
|
|
56
65
|
|
57
66
|
private
|
58
67
|
|
59
|
-
# rubocop:disable AbcSize
|
60
|
-
# rubocop:disable MethodLength
|
68
|
+
# rubocop:disable Metrics/AbcSize
|
69
|
+
# rubocop:disable Metrics/MethodLength
|
61
70
|
def convert(request, writer)
|
62
71
|
::Typhoeus::Request.new(
|
63
72
|
request.uri,
|
73
|
+
**@options,
|
64
74
|
method: request.method,
|
65
75
|
headers: DEFAULT_HEADERS.merge(request.headers),
|
66
76
|
body: request.body,
|
67
|
-
followlocation: true,
|
68
77
|
timeout: request.timeout,
|
69
78
|
connecttimeout: request.timeout
|
70
79
|
).tap do |req|
|
@@ -123,7 +132,7 @@ module Restify
|
|
123
132
|
@hydra.queued_requests.any? || @hydra.multi.easy_handles.any?
|
124
133
|
end
|
125
134
|
|
126
|
-
# rubocop:disable MethodLength
|
135
|
+
# rubocop:disable Metrics/MethodLength
|
127
136
|
def _run
|
128
137
|
debug 'hydra:run'
|
129
138
|
@hydra.run while _ongoing?
|
data/lib/restify/context.rb
CHANGED
@@ -36,7 +36,7 @@ module Restify
|
|
36
36
|
|
37
37
|
def inherit(uri, **kwargs)
|
38
38
|
uri ||= self.uri
|
39
|
-
Context.new
|
39
|
+
Context.new(uri, **kwargs, **options)
|
40
40
|
end
|
41
41
|
|
42
42
|
def process(response)
|
@@ -62,7 +62,7 @@ module Restify
|
|
62
62
|
if !response.errored?
|
63
63
|
process response
|
64
64
|
else
|
65
|
-
|
65
|
+
raise ResponseError.from_code(response)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -101,18 +101,5 @@ module Restify
|
|
101
101
|
def default_headers
|
102
102
|
options.fetch(:headers, {})
|
103
103
|
end
|
104
|
-
|
105
|
-
class << self
|
106
|
-
def raise_response_error(response)
|
107
|
-
case response.code
|
108
|
-
when 400...500
|
109
|
-
raise ClientError.new(response)
|
110
|
-
when 500...600
|
111
|
-
raise ServerError.new(response)
|
112
|
-
else
|
113
|
-
raise "Unknown response code: #{response.code}"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
104
|
end
|
118
105
|
end
|
data/lib/restify/error.rb
CHANGED
@@ -20,6 +20,37 @@ module Restify
|
|
20
20
|
class ResponseError < StandardError
|
21
21
|
attr_reader :response
|
22
22
|
|
23
|
+
def self.from_code(response)
|
24
|
+
case response.code
|
25
|
+
when 400
|
26
|
+
BadRequest.new(response)
|
27
|
+
when 401
|
28
|
+
Unauthorized.new(response)
|
29
|
+
when 404
|
30
|
+
NotFound.new(response)
|
31
|
+
when 406
|
32
|
+
NotAcceptable.new(response)
|
33
|
+
when 410
|
34
|
+
Gone.new(response)
|
35
|
+
when 422
|
36
|
+
UnprocessableEntity.new(response)
|
37
|
+
when 400...500
|
38
|
+
ClientError.new(response)
|
39
|
+
when 500
|
40
|
+
InternalServerError.new(response)
|
41
|
+
when 502
|
42
|
+
BadGateway.new(response)
|
43
|
+
when 503
|
44
|
+
ServiceUnavailable.new(response)
|
45
|
+
when 504
|
46
|
+
GatewayTimeout.new(response)
|
47
|
+
when 500...600
|
48
|
+
ServerError.new(response)
|
49
|
+
else
|
50
|
+
raise "Unknown response code: #{response.code}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
23
54
|
def initialize(response)
|
24
55
|
@response = response
|
25
56
|
super "#{response.message} (#{response.code}) for `#{response.uri}':\n" \
|
@@ -65,4 +96,29 @@ module Restify
|
|
65
96
|
# A {ServerError} will be raised when a response has a
|
66
97
|
# 5XX status code.
|
67
98
|
class ServerError < ResponseError; end
|
99
|
+
|
100
|
+
# A {GatewayError} is the common base class for 502, 503 and 504
|
101
|
+
# response codes often used by load balancers when upstream servers are
|
102
|
+
# failing or not available.
|
103
|
+
#
|
104
|
+
# This can be used to catch "common" gateway responses.
|
105
|
+
class GatewayError < ServerError; end
|
106
|
+
|
107
|
+
###
|
108
|
+
# CONCRETE SUBCLASSES FOR TYPICAL STATUS CODES
|
109
|
+
#
|
110
|
+
# This makes it easy to rescue specific expected error types.
|
111
|
+
|
112
|
+
class BadRequest < ClientError; end
|
113
|
+
class Unauthorized < ClientError; end
|
114
|
+
class NotFound < ClientError; end
|
115
|
+
class NotAcceptable < ClientError; end
|
116
|
+
class Gone < ClientError; end
|
117
|
+
class UnprocessableEntity < ClientError; end
|
118
|
+
|
119
|
+
class InternalServerError < ServerError; end
|
120
|
+
|
121
|
+
class BadGateway < GatewayError; end
|
122
|
+
class ServiceUnavailable < GatewayError; end
|
123
|
+
class GatewayTimeout < GatewayError; end
|
68
124
|
end
|
data/lib/restify/global.rb
CHANGED
@@ -39,9 +39,9 @@ module Restify
|
|
39
39
|
|
40
40
|
def resolve_context(uri, **opts)
|
41
41
|
if uri.is_a? Symbol
|
42
|
-
Restify::Registry.fetch(uri).inherit(nil, opts)
|
42
|
+
Restify::Registry.fetch(uri).inherit(nil, **opts)
|
43
43
|
else
|
44
|
-
Context.new
|
44
|
+
Context.new(uri, **opts)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
data/lib/restify/link.rb
CHANGED
@@ -25,10 +25,10 @@ module Restify
|
|
25
25
|
end
|
26
26
|
|
27
27
|
class << self
|
28
|
-
REGEXP_URI = /<[^>]*>\s
|
29
|
-
REGEXP_PAR = /;\s*\w+\s*=\s*/i
|
30
|
-
REGEXP_QUT = /"[^"]*"\s
|
31
|
-
REGEXP_ARG = /\w+\s*/i
|
28
|
+
REGEXP_URI = /<[^>]*>\s*/.freeze
|
29
|
+
REGEXP_PAR = /;\s*\w+\s*=\s*/i.freeze
|
30
|
+
REGEXP_QUT = /"[^"]*"\s*/.freeze
|
31
|
+
REGEXP_ARG = /\w+\s*/i.freeze
|
32
32
|
|
33
33
|
def parse(string)
|
34
34
|
scanner = StringScanner.new(string.strip)
|
data/lib/restify/promise.rb
CHANGED
@@ -7,6 +7,13 @@ module Restify
|
|
7
7
|
@dependencies = dependencies.flatten
|
8
8
|
|
9
9
|
super(&nil)
|
10
|
+
|
11
|
+
# When dependencies were passed in, but none are left after flattening,
|
12
|
+
# then we don't have to wait for explicit dependencies or resolution
|
13
|
+
# through a writer.
|
14
|
+
if !@task && @dependencies.empty? && dependencies.any?
|
15
|
+
complete true, [], nil
|
16
|
+
end
|
10
17
|
end
|
11
18
|
|
12
19
|
def wait(timeout = nil)
|
@@ -16,6 +23,7 @@ module Restify
|
|
16
23
|
|
17
24
|
super
|
18
25
|
raise t if incomplete?
|
26
|
+
|
19
27
|
self
|
20
28
|
end
|
21
29
|
|
data/lib/restify/relation.rb
CHANGED
data/lib/restify/timeout.rb
CHANGED
data/lib/restify/version.rb
CHANGED
@@ -47,7 +47,7 @@ describe Restify::Context do
|
|
47
47
|
|
48
48
|
context 'YAML' do
|
49
49
|
let(:dump) { YAML.dump(context) }
|
50
|
-
let(:load) { YAML.load(dump) } # rubocop:disable YAMLLoad
|
50
|
+
let(:load) { YAML.load(dump) } # rubocop:disable Security/YAMLLoad
|
51
51
|
|
52
52
|
subject { load }
|
53
53
|
|
@@ -56,7 +56,7 @@ describe Restify::Context do
|
|
56
56
|
|
57
57
|
context 'Marshall' do
|
58
58
|
let(:dump) { Marshal.dump(context) }
|
59
|
-
let(:load) { Marshal.load(dump) } # rubocop:disable MarshalLoad
|
59
|
+
let(:load) { Marshal.load(dump) } # rubocop:disable Security/MarshalLoad
|
60
60
|
|
61
61
|
subject { load }
|
62
62
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Restify::ResponseError do
|
6
|
+
let(:response) { double 'response' }
|
7
|
+
let(:message) { 'Error' }
|
8
|
+
let(:uri) { 'http://localhost' }
|
9
|
+
|
10
|
+
before do
|
11
|
+
allow(response).to receive(:uri).and_return(uri)
|
12
|
+
allow(response).to receive(:code).and_return(code)
|
13
|
+
allow(response).to receive(:message).and_return(message)
|
14
|
+
allow(response).to receive(:decoded_body).and_return({})
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.from_code' do
|
18
|
+
subject(:err) { described_class.from_code(response) }
|
19
|
+
|
20
|
+
context 'with 400 Bad Request' do
|
21
|
+
let(:code) { 400 }
|
22
|
+
it { is_expected.to be_a ::Restify::BadRequest }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with 401 Unauthorized' do
|
26
|
+
let(:code) { 401 }
|
27
|
+
it { is_expected.to be_a ::Restify::Unauthorized }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with 404 Unauthorized' do
|
31
|
+
let(:code) { 404 }
|
32
|
+
it { is_expected.to be_a ::Restify::NotFound }
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with 406 Not Acceptable' do
|
36
|
+
let(:code) { 406 }
|
37
|
+
it { is_expected.to be_a ::Restify::NotAcceptable }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with 410 Gone' do
|
41
|
+
let(:code) { 410 }
|
42
|
+
it { is_expected.to be_a ::Restify::Gone }
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with 422 Unprocessable Entity' do
|
46
|
+
let(:code) { 422 }
|
47
|
+
it { is_expected.to be_a ::Restify::UnprocessableEntity }
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'with 500 Internal Server Error' do
|
51
|
+
let(:code) { 500 }
|
52
|
+
it { is_expected.to be_a ::Restify::InternalServerError }
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'with 502 Bad Gateway' do
|
56
|
+
let(:code) { 502 }
|
57
|
+
it { is_expected.to be_a ::Restify::BadGateway }
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'with 503 Service Unavailable' do
|
61
|
+
let(:code) { 503 }
|
62
|
+
it { is_expected.to be_a ::Restify::ServiceUnavailable }
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'with 504 Gateway Timeout' do
|
66
|
+
let(:code) { 504 }
|
67
|
+
it { is_expected.to be_a ::Restify::GatewayTimeout }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Restify do
|
6
|
+
let!(:request_stub) do
|
7
|
+
stub_request(:get, 'http://localhost/base')
|
8
|
+
.to_return do
|
9
|
+
<<-RESPONSE.gsub(/^ {8}/, '')
|
10
|
+
HTTP/1.1 #{http_status}
|
11
|
+
Content-Length: 333
|
12
|
+
Transfer-Encoding: chunked
|
13
|
+
Link: <http://localhost/other>; rel="neat"
|
14
|
+
RESPONSE
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:http_status) { '200 OK' }
|
19
|
+
|
20
|
+
describe 'Error handling' do
|
21
|
+
subject(:request) { Restify.new('http://localhost/base').get.value! }
|
22
|
+
|
23
|
+
context 'for 400 status codes' do
|
24
|
+
let(:http_status) { '400 Bad Request' }
|
25
|
+
|
26
|
+
it 'throws a BadRequest exception' do
|
27
|
+
expect { request }.to raise_error Restify::BadRequest
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'for 401 status codes' do
|
32
|
+
let(:http_status) { '401 Unauthorized' }
|
33
|
+
|
34
|
+
it 'throws an Unauthorized exception' do
|
35
|
+
expect { request }.to raise_error Restify::Unauthorized
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'for 404 status codes' do
|
40
|
+
let(:http_status) { '404 Not Found' }
|
41
|
+
|
42
|
+
it 'throws a ClientError exception' do
|
43
|
+
expect { request }.to raise_error Restify::NotFoundError
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'for 406 status codes' do
|
48
|
+
let(:http_status) { '406 Not Acceptable' }
|
49
|
+
|
50
|
+
it 'throws a NotAcceptable exception' do
|
51
|
+
expect { request }.to raise_error Restify::NotAcceptable
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'for 422 status codes' do
|
56
|
+
let(:http_status) { '422 Unprocessable Entity' }
|
57
|
+
|
58
|
+
it 'throws a UnprocessableEntity exception' do
|
59
|
+
expect { request }.to raise_error Restify::UnprocessableEntity
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'for any other 4xx status codes' do
|
64
|
+
let(:http_status) { '415 Unsupported Media Type' }
|
65
|
+
|
66
|
+
it 'throws a generic ClientError exception' do
|
67
|
+
expect { request }.to raise_error Restify::ClientError
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'for any 5xx status codes' do
|
72
|
+
let(:http_status) { '500 Internal Server Error' }
|
73
|
+
|
74
|
+
it 'throws a generic ServerError exception' do
|
75
|
+
expect { request }.to raise_error Restify::ServerError
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/spec/restify/global_spec.rb
CHANGED
@@ -26,7 +26,7 @@ describe Restify::Global do
|
|
26
26
|
let(:options) { {accept: 'application.vnd.github.v3+json'} }
|
27
27
|
let(:context) { Restify::Context.new uri, **options }
|
28
28
|
|
29
|
-
subject { global.new
|
29
|
+
subject { global.new(name, **options) }
|
30
30
|
|
31
31
|
it 'returns relation for stored registry item' do
|
32
32
|
Restify::Registry.store name, uri, options
|
@@ -163,6 +163,13 @@ describe Restify::Promise do
|
|
163
163
|
expect(subject).to eq 17
|
164
164
|
end
|
165
165
|
end
|
166
|
+
|
167
|
+
# Nobody does this explicitly, but it can happen when the array of
|
168
|
+
# dependencies is built dynamically.
|
169
|
+
context 'with an empty array of dependencies and without task' do
|
170
|
+
subject { described_class.new([]).value! }
|
171
|
+
it { is_expected.to eq [] }
|
172
|
+
end
|
166
173
|
end
|
167
174
|
|
168
175
|
describe '#wait' do
|
data/spec/restify_spec.rb
CHANGED
@@ -134,7 +134,6 @@ describe Restify do
|
|
134
134
|
# the result is here.
|
135
135
|
expect { create_user_promise.value! }.to \
|
136
136
|
raise_error(Restify::ClientError) do |e|
|
137
|
-
|
138
137
|
# Because we forgot to send a "name" the server complains
|
139
138
|
# with an error code that will lead to a raised error.
|
140
139
|
|
@@ -206,7 +205,6 @@ describe Restify do
|
|
206
205
|
|
207
206
|
expect { create_user_promise.value! }.to \
|
208
207
|
raise_error(Restify::ClientError) do |e|
|
209
|
-
|
210
208
|
expect(e.status).to eq :unprocessable_entity
|
211
209
|
expect(e.code).to eq 422
|
212
210
|
expect(e.errors).to eq 'name' => ["can't be blank"]
|
data/spec/spec_helper.rb
CHANGED
@@ -3,11 +3,14 @@
|
|
3
3
|
require 'rspec'
|
4
4
|
require 'webmock/rspec'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
require 'simplecov'
|
7
|
+
SimpleCov.start do
|
8
|
+
add_filter 'spec'
|
9
|
+
end
|
10
|
+
|
11
|
+
if ENV['CI']
|
12
|
+
require 'codecov'
|
13
|
+
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
11
14
|
end
|
12
15
|
|
13
16
|
require 'restify'
|
@@ -35,7 +38,7 @@ require 'webmock/rspec'
|
|
35
38
|
require 'rspec/collection_matchers'
|
36
39
|
require 'em-synchrony'
|
37
40
|
|
38
|
-
Dir[File.expand_path('spec/support/**/*.rb')].each {|f| require f }
|
41
|
+
Dir[File.expand_path('spec/support/**/*.rb')].sort.each {|f| require f }
|
39
42
|
|
40
43
|
RSpec.configure do |config|
|
41
44
|
config.order = 'random'
|
@@ -51,6 +54,7 @@ RSpec.configure do |config|
|
|
51
54
|
::Logging.logger.root.add_appenders ::Logging.appenders.stdout
|
52
55
|
end
|
53
56
|
|
57
|
+
config.warnings = true
|
54
58
|
config.after(:suite) do
|
55
59
|
EventMachine.stop if defined?(EventMachine) && EventMachine.reactor_running?
|
56
60
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Graichen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -56,16 +56,22 @@ dependencies:
|
|
56
56
|
name: hashie
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '3.3'
|
62
|
+
- - "<"
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '5.0'
|
62
65
|
type: :runtime
|
63
66
|
prerelease: false
|
64
67
|
version_requirements: !ruby/object:Gem::Requirement
|
65
68
|
requirements:
|
66
|
-
- - "
|
69
|
+
- - ">="
|
67
70
|
- !ruby/object:Gem::Version
|
68
71
|
version: '3.3'
|
72
|
+
- - "<"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '5.0'
|
69
75
|
- !ruby/object:Gem::Dependency
|
70
76
|
name: rack
|
71
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -140,16 +146,16 @@ dependencies:
|
|
140
146
|
name: bundler
|
141
147
|
requirement: !ruby/object:Gem::Requirement
|
142
148
|
requirements:
|
143
|
-
- - "
|
149
|
+
- - ">="
|
144
150
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
151
|
+
version: '0'
|
146
152
|
type: :development
|
147
153
|
prerelease: false
|
148
154
|
version_requirements: !ruby/object:Gem::Requirement
|
149
155
|
requirements:
|
150
|
-
- - "
|
156
|
+
- - ">="
|
151
157
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
158
|
+
version: '0'
|
153
159
|
description: An experimental hypermedia REST client that uses parallel, keep-alive
|
154
160
|
and pipelined requests by default.
|
155
161
|
email:
|
@@ -186,8 +192,10 @@ files:
|
|
186
192
|
- lib/restify/version.rb
|
187
193
|
- spec/restify/cache_spec.rb
|
188
194
|
- spec/restify/context_spec.rb
|
195
|
+
- spec/restify/error_spec.rb
|
189
196
|
- spec/restify/features/head_requests_spec.rb
|
190
197
|
- spec/restify/features/request_headers_spec.rb
|
198
|
+
- spec/restify/features/response_errors.rb
|
191
199
|
- spec/restify/global_spec.rb
|
192
200
|
- spec/restify/link_spec.rb
|
193
201
|
- spec/restify/processors/base_spec.rb
|
@@ -215,20 +223,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
215
223
|
version: '0'
|
216
224
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
217
225
|
requirements:
|
218
|
-
- - "
|
226
|
+
- - ">="
|
219
227
|
- !ruby/object:Gem::Version
|
220
|
-
version:
|
228
|
+
version: '0'
|
221
229
|
requirements: []
|
222
|
-
|
223
|
-
rubygems_version: 2.7.7
|
230
|
+
rubygems_version: 3.1.2
|
224
231
|
signing_key:
|
225
232
|
specification_version: 4
|
226
233
|
summary: An experimental hypermedia REST client.
|
227
234
|
test_files:
|
228
235
|
- spec/restify/cache_spec.rb
|
229
236
|
- spec/restify/context_spec.rb
|
237
|
+
- spec/restify/error_spec.rb
|
230
238
|
- spec/restify/features/head_requests_spec.rb
|
231
239
|
- spec/restify/features/request_headers_spec.rb
|
240
|
+
- spec/restify/features/response_errors.rb
|
232
241
|
- spec/restify/global_spec.rb
|
233
242
|
- spec/restify/link_spec.rb
|
234
243
|
- spec/restify/processors/base_spec.rb
|