roar 1.0.2 → 1.1.1
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 +5 -5
- data/.github/ISSUE_TEMPLATE.md +20 -0
- data/.travis.yml +16 -11
- data/CHANGES.markdown +86 -57
- data/CONTRIBUTING.md +31 -0
- data/Gemfile +7 -4
- data/LICENSE +1 -1
- data/README.markdown +133 -255
- data/Rakefile +3 -1
- data/examples/example.rb +0 -0
- data/examples/example_server.rb +0 -0
- data/lib/roar/client.rb +8 -3
- data/lib/roar/decorator.rb +2 -2
- data/lib/roar/http_verbs.rb +0 -16
- data/lib/roar/hypermedia.rb +30 -56
- data/lib/roar/json/collection.rb +10 -2
- data/lib/roar/json/hal.rb +74 -83
- data/lib/roar/json.rb +5 -5
- data/lib/roar/version.rb +1 -1
- data/lib/roar/xml.rb +1 -1
- data/lib/roar.rb +3 -3
- data/roar.gemspec +7 -5
- data/test/client_test.rb +1 -1
- data/test/coercion_feature_test.rb +7 -2
- data/test/decorator_test.rb +17 -7
- data/test/hal_json_test.rb +101 -94
- data/test/hypermedia_feature_test.rb +13 -31
- data/test/hypermedia_test.rb +26 -92
- data/test/{decorator_client_test.rb → integration/decorator_client_test.rb} +5 -4
- data/test/{faraday_http_transport_test.rb → integration/faraday_http_transport_test.rb} +1 -0
- data/test/{http_verbs_test.rb → integration/http_verbs_test.rb} +3 -2
- data/test/integration/json_collection_test.rb +35 -0
- data/test/{net_http_transport_test.rb → integration/net_http_transport_test.rb} +1 -0
- data/test/integration/runner.rb +2 -3
- data/test/integration/server.rb +6 -0
- data/test/json_representer_test.rb +2 -29
- data/test/lonely_test.rb +1 -2
- data/test/ssl_client_certs_test.rb +1 -1
- data/test/test_helper.rb +21 -3
- data/test/xml_representer_test.rb +6 -5
- metadata +21 -37
- data/gemfiles/Gemfile.representable-1.7 +0 -6
- data/gemfiles/Gemfile.representable-1.8 +0 -6
- data/gemfiles/Gemfile.representable-2.0 +0 -5
- data/gemfiles/Gemfile.representable-2.1 +0 -5
- data/gemfiles/Gemfile.representable-head +0 -6
- data/lib/roar/json/collection_json.rb +0 -208
- data/lib/roar/json/json_api.rb +0 -233
- data/test/collection_json_test.rb +0 -132
- data/test/hal_links_test.rb +0 -31
- data/test/json_api_test.rb +0 -451
- data/test/lib/runner.rb +0 -134
data/test/json_api_test.rb
DELETED
@@ -1,451 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'roar/json/json_api'
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
require "representable/version"
|
6
|
-
if Gem::Version.new(Representable::VERSION) >= Gem::Version.new("2.1.4") # TODO: remove check once we bump representable dependency.
|
7
|
-
class JSONAPITest < MiniTest::Spec
|
8
|
-
let(:song) {
|
9
|
-
s = OpenStruct.new(
|
10
|
-
bla: "halo",
|
11
|
-
id: "1",
|
12
|
-
title: 'Computadores Fazem Arte',
|
13
|
-
album: OpenStruct.new(id: 9, title: "Hackers"),
|
14
|
-
:album_id => "9",
|
15
|
-
:musician_ids => ["1","2"],
|
16
|
-
:composer_id => "10",
|
17
|
-
:listener_ids => ["8"],
|
18
|
-
musicians: [OpenStruct.new(id: 1, name: "Eddie Van Halen"), OpenStruct.new(id: 2, name: "Greg Howe")]
|
19
|
-
)
|
20
|
-
|
21
|
-
}
|
22
|
-
|
23
|
-
# minimal resource, singular
|
24
|
-
module MinimalSingular
|
25
|
-
include Roar::JSON::JSONAPI
|
26
|
-
type :songs
|
27
|
-
|
28
|
-
property :id
|
29
|
-
end
|
30
|
-
|
31
|
-
class MinimalSingularDecorator < Roar::Decorator
|
32
|
-
include Roar::JSON::JSONAPI
|
33
|
-
type :songs
|
34
|
-
|
35
|
-
property :id
|
36
|
-
end
|
37
|
-
|
38
|
-
[MinimalSingular, MinimalSingularDecorator].each do |representer|
|
39
|
-
describe "minimal singular with #{representer}" do
|
40
|
-
subject { representer.prepare(song) }
|
41
|
-
|
42
|
-
it { subject.to_json.must_equal "{\"songs\":{\"id\":\"1\"}}" }
|
43
|
-
it { subject.from_json("{\"songs\":{\"id\":\"2\"}}").id.must_equal "2" }
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
module Singular
|
48
|
-
include Roar::JSON::JSONAPI
|
49
|
-
type :songs
|
50
|
-
|
51
|
-
property :id
|
52
|
-
property :title, if: lambda { |args| args[:omit_title] != true }
|
53
|
-
|
54
|
-
# local per-model "id" links
|
55
|
-
links do
|
56
|
-
property :album_id, :as => :album
|
57
|
-
collection :musician_ids, :as => :musicians
|
58
|
-
end
|
59
|
-
has_one :composer
|
60
|
-
has_many :listeners
|
61
|
-
|
62
|
-
|
63
|
-
# global document links.
|
64
|
-
link "songs.album" do
|
65
|
-
{
|
66
|
-
type: "album",
|
67
|
-
href: "http://example.com/albums/{songs.album}"
|
68
|
-
}
|
69
|
-
end
|
70
|
-
|
71
|
-
compound do
|
72
|
-
property :album do
|
73
|
-
property :title
|
74
|
-
end
|
75
|
-
|
76
|
-
collection :musicians do
|
77
|
-
property :name
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
class SingularDecorator < Roar::Decorator
|
83
|
-
include Roar::JSON::JSONAPI
|
84
|
-
type :songs
|
85
|
-
|
86
|
-
property :id
|
87
|
-
property :title, if: lambda { |args| args[:omit_title] != true }
|
88
|
-
|
89
|
-
# NOTE: it is important to call has_one, then links, then has_many to assert that they all write
|
90
|
-
#to the same _links property and do NOT override things.
|
91
|
-
has_one :composer
|
92
|
-
# local per-model "id" links
|
93
|
-
links do
|
94
|
-
property :album_id, :as => :album
|
95
|
-
collection :musician_ids, :as => :musicians
|
96
|
-
end
|
97
|
-
has_many :listeners
|
98
|
-
|
99
|
-
|
100
|
-
# global document links.
|
101
|
-
link "songs.album" do
|
102
|
-
{
|
103
|
-
type: "album",
|
104
|
-
href: "http://example.com/albums/{songs.album}"
|
105
|
-
}
|
106
|
-
end
|
107
|
-
|
108
|
-
compound do
|
109
|
-
property :album do
|
110
|
-
property :title
|
111
|
-
end
|
112
|
-
|
113
|
-
collection :musicians do
|
114
|
-
property :name
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
[Singular, SingularDecorator].each do |representer|
|
120
|
-
describe "singular with #{representer}" do
|
121
|
-
subject { song.extend(Singular) }
|
122
|
-
|
123
|
-
let (:document) do
|
124
|
-
{
|
125
|
-
"songs" => {
|
126
|
-
"id" => "1",
|
127
|
-
"title" => "Computadores Fazem Arte",
|
128
|
-
"links" => {
|
129
|
-
"album" => "9",
|
130
|
-
"musicians" => [ "1", "2" ],
|
131
|
-
"composer"=>"10",
|
132
|
-
"listeners"=>["8"]
|
133
|
-
}
|
134
|
-
},
|
135
|
-
"links" => {
|
136
|
-
"songs.album"=> {
|
137
|
-
"href"=>"http://example.com/albums/{songs.album}", "type"=>"album"
|
138
|
-
}
|
139
|
-
},
|
140
|
-
"linked" => {
|
141
|
-
"album"=> [{"title"=>"Hackers"}],
|
142
|
-
"musicians"=> [
|
143
|
-
{"name"=>"Eddie Van Halen"},
|
144
|
-
{"name"=>"Greg Howe"}
|
145
|
-
]
|
146
|
-
}
|
147
|
-
}
|
148
|
-
end
|
149
|
-
|
150
|
-
# to_hash
|
151
|
-
it do
|
152
|
-
subject.to_hash.must_equal document
|
153
|
-
end
|
154
|
-
|
155
|
-
# to_hash(options)
|
156
|
-
it do
|
157
|
-
subject.to_hash(omit_title: true)['songs'].wont_include('title')
|
158
|
-
end
|
159
|
-
|
160
|
-
# #to_json
|
161
|
-
it do
|
162
|
-
subject.to_json.must_equal JSON.generate(document)
|
163
|
-
end
|
164
|
-
|
165
|
-
# #from_json
|
166
|
-
it do
|
167
|
-
song = OpenStruct.new.extend(Singular)
|
168
|
-
song.from_json(
|
169
|
-
JSON.generate(
|
170
|
-
{
|
171
|
-
"songs" => {
|
172
|
-
"id" => "1",
|
173
|
-
"title" => "Computadores Fazem Arte",
|
174
|
-
"links" => {
|
175
|
-
"album" => "9",
|
176
|
-
"musicians" => [ "1", "2" ],
|
177
|
-
"composer"=>"10",
|
178
|
-
"listeners"=>["8"]
|
179
|
-
}
|
180
|
-
},
|
181
|
-
"links" => {
|
182
|
-
"songs.album"=> {
|
183
|
-
"href"=>"http://example.com/albums/{songs.album}", "type"=>"album"
|
184
|
-
}
|
185
|
-
}
|
186
|
-
}
|
187
|
-
)
|
188
|
-
)
|
189
|
-
|
190
|
-
song.id.must_equal "1"
|
191
|
-
song.title.must_equal "Computadores Fazem Arte"
|
192
|
-
song.album_id.must_equal "9"
|
193
|
-
song.musician_ids.must_equal ["1", "2"]
|
194
|
-
song.composer_id.must_equal "10"
|
195
|
-
song.listener_ids.must_equal ["8"]
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
|
201
|
-
# collection with links
|
202
|
-
[Singular, SingularDecorator].each do |representer|
|
203
|
-
describe "collection with links and compound with #{representer}" do
|
204
|
-
subject { representer.for_collection.prepare([song, song]) }
|
205
|
-
|
206
|
-
let (:document) do
|
207
|
-
{
|
208
|
-
"songs" => [
|
209
|
-
{
|
210
|
-
"id" => "1",
|
211
|
-
"title" => "Computadores Fazem Arte",
|
212
|
-
"links" => {
|
213
|
-
"composer"=>"10",
|
214
|
-
"album" => "9",
|
215
|
-
"musicians" => [ "1", "2" ],
|
216
|
-
"listeners"=>["8"]
|
217
|
-
}
|
218
|
-
}, {
|
219
|
-
"id" => "1",
|
220
|
-
"title" => "Computadores Fazem Arte",
|
221
|
-
"links" => {
|
222
|
-
"composer"=>"10",
|
223
|
-
"album" => "9",
|
224
|
-
"musicians" => [ "1", "2" ],
|
225
|
-
"listeners"=>["8"]
|
226
|
-
}
|
227
|
-
}
|
228
|
-
],
|
229
|
-
"links" => {
|
230
|
-
"songs.album" => {
|
231
|
-
"href" => "http://example.com/albums/{songs.album}",
|
232
|
-
"type" => "album" # DISCUSS: does that have to be albums ?
|
233
|
-
},
|
234
|
-
},
|
235
|
-
"linked"=>{
|
236
|
-
"album" =>[{"title"=>"Hackers"}], # only once!
|
237
|
-
"musicians"=>[{"name"=>"Eddie Van Halen"}, {"name"=>"Greg Howe"}]
|
238
|
-
}
|
239
|
-
}
|
240
|
-
end
|
241
|
-
|
242
|
-
# to_hash
|
243
|
-
it do
|
244
|
-
subject.to_hash.must_equal document
|
245
|
-
end
|
246
|
-
|
247
|
-
# to_hash(options)
|
248
|
-
it do
|
249
|
-
subject.to_hash(omit_title: true)['songs'].each do |song|
|
250
|
-
song.wont_include('title')
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
# #to_json
|
255
|
-
it { subject.to_json.must_match /linked/ } # hash ordering changes, and i don't care why.
|
256
|
-
end
|
257
|
-
|
258
|
-
|
259
|
-
# from_json
|
260
|
-
it do
|
261
|
-
song1, song2 = Singular.for_collection.prepare([OpenStruct.new, OpenStruct.new]).from_json(
|
262
|
-
JSON.generate(
|
263
|
-
{
|
264
|
-
"songs" => [
|
265
|
-
{
|
266
|
-
"id" => "1",
|
267
|
-
"title" => "Computadores Fazem Arte",
|
268
|
-
"links" => {
|
269
|
-
"album" => "9",
|
270
|
-
"musicians" => [ "1", "2" ],
|
271
|
-
"composer"=>"10",
|
272
|
-
"listeners"=>["8"]
|
273
|
-
},
|
274
|
-
},
|
275
|
-
{
|
276
|
-
"id" => "2",
|
277
|
-
"title" => "Talking To Remind Me",
|
278
|
-
"links" => {
|
279
|
-
"album" => "1",
|
280
|
-
"musicians" => [ "3", "4" ],
|
281
|
-
"composer"=>"2",
|
282
|
-
"listeners"=>["6"]
|
283
|
-
}
|
284
|
-
},
|
285
|
-
],
|
286
|
-
"links" => {
|
287
|
-
"songs.album"=> {
|
288
|
-
"href"=>"http://example.com/albums/{songs.album}", "type"=>"album"
|
289
|
-
}
|
290
|
-
}
|
291
|
-
}
|
292
|
-
)
|
293
|
-
)
|
294
|
-
|
295
|
-
song1.id.must_equal "1"
|
296
|
-
song1.title.must_equal "Computadores Fazem Arte"
|
297
|
-
song1.album_id.must_equal "9"
|
298
|
-
song1.musician_ids.must_equal ["1", "2"]
|
299
|
-
song1.composer_id.must_equal "10"
|
300
|
-
song1.listener_ids.must_equal ["8"]
|
301
|
-
|
302
|
-
song2.id.must_equal "2"
|
303
|
-
song2.title.must_equal "Talking To Remind Me"
|
304
|
-
song2.album_id.must_equal "1"
|
305
|
-
song2.musician_ids.must_equal ["3", "4"]
|
306
|
-
song2.composer_id.must_equal "2"
|
307
|
-
song2.listener_ids.must_equal ["6"]
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
|
312
|
-
class CollectionWithoutCompound < self
|
313
|
-
module Representer
|
314
|
-
include Roar::JSON::JSONAPI
|
315
|
-
type :songs
|
316
|
-
|
317
|
-
property :id
|
318
|
-
property :title
|
319
|
-
|
320
|
-
# local per-model "id" links
|
321
|
-
links do
|
322
|
-
property :album_id, :as => :album
|
323
|
-
collection :musician_ids, :as => :musicians
|
324
|
-
end
|
325
|
-
has_one :composer
|
326
|
-
has_many :listeners
|
327
|
-
|
328
|
-
|
329
|
-
# global document links.
|
330
|
-
link "songs.album" do
|
331
|
-
{
|
332
|
-
type: "album",
|
333
|
-
href: "http://example.com/albums/{songs.album}"
|
334
|
-
}
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
subject { [song, song].extend(Singular.for_collection) }
|
339
|
-
|
340
|
-
# to_json
|
341
|
-
it do
|
342
|
-
subject.extend(Representer.for_collection).to_hash.must_equal(
|
343
|
-
{
|
344
|
-
"songs"=>[{"id"=>"1", "title"=>"Computadores Fazem Arte", "links"=>{"album"=>"9", "musicians"=>["1", "2"], "composer"=>"10", "listeners"=>["8"]}}, {"id"=>"1", "title"=>"Computadores Fazem Arte", "links"=>{"album"=>"9", "musicians"=>["1", "2"], "composer"=>"10", "listeners"=>["8"]}}],
|
345
|
-
"links"=>{"songs.album"=>{"href"=>"http://example.com/albums/{songs.album}", "type"=>"album"}
|
346
|
-
}
|
347
|
-
}
|
348
|
-
)
|
349
|
-
end
|
350
|
-
end
|
351
|
-
|
352
|
-
class CompoundCollectionUsingExtend < self
|
353
|
-
module SongRepresenter
|
354
|
-
include Roar::JSON::JSONAPI
|
355
|
-
|
356
|
-
type :songs
|
357
|
-
property :id
|
358
|
-
property :title
|
359
|
-
end
|
360
|
-
|
361
|
-
module AlbumRepresenter
|
362
|
-
include Roar::JSON::JSONAPI
|
363
|
-
|
364
|
-
type :albums
|
365
|
-
property :id
|
366
|
-
compound do
|
367
|
-
collection :songs, extend: SongRepresenter
|
368
|
-
end
|
369
|
-
end
|
370
|
-
|
371
|
-
let(:songs) do
|
372
|
-
struct = Struct.new(:id, :title)
|
373
|
-
[struct.new(1, 'Stand Up'), struct.new(2, 'Audition Mantra')]
|
374
|
-
end
|
375
|
-
|
376
|
-
let(:album) { Struct.new(:id, :songs).new(1, songs) }
|
377
|
-
|
378
|
-
subject { album.extend(AlbumRepresenter) }
|
379
|
-
|
380
|
-
# to_hash
|
381
|
-
it do
|
382
|
-
subject.to_hash.must_equal({
|
383
|
-
'albums' => { 'id' => 1 },
|
384
|
-
'linked' => {
|
385
|
-
'songs' => [
|
386
|
-
{'id' => 1, 'title' => 'Stand Up'},
|
387
|
-
{'id' => 2, 'title' => 'Audition Mantra'}
|
388
|
-
]
|
389
|
-
}
|
390
|
-
})
|
391
|
-
end
|
392
|
-
end
|
393
|
-
|
394
|
-
class ExplicitMeta < self
|
395
|
-
module Representer
|
396
|
-
include Roar::JSON::JSONAPI
|
397
|
-
|
398
|
-
type :songs
|
399
|
-
property :id
|
400
|
-
|
401
|
-
meta do
|
402
|
-
property :page
|
403
|
-
end
|
404
|
-
end
|
405
|
-
|
406
|
-
module Page
|
407
|
-
def page
|
408
|
-
2
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
let (:song) { Struct.new(:id).new(1) }
|
413
|
-
|
414
|
-
subject { [song, song].extend(Representer.for_collection).extend(Page) }
|
415
|
-
|
416
|
-
# to_json
|
417
|
-
it do
|
418
|
-
subject.to_hash.must_equal(
|
419
|
-
{
|
420
|
-
"songs"=>[{"id"=>1}, {"id"=>1}],
|
421
|
-
"meta" =>{"page"=>2}
|
422
|
-
}
|
423
|
-
)
|
424
|
-
end
|
425
|
-
end
|
426
|
-
|
427
|
-
|
428
|
-
class ImplicitMeta < self
|
429
|
-
module Representer
|
430
|
-
include Roar::JSON::JSONAPI
|
431
|
-
|
432
|
-
type :songs
|
433
|
-
property :id
|
434
|
-
end
|
435
|
-
|
436
|
-
let (:song) { Struct.new(:id).new(1) }
|
437
|
-
|
438
|
-
subject { [song, song].extend(Representer.for_collection) }
|
439
|
-
|
440
|
-
# to_json
|
441
|
-
it do
|
442
|
-
subject.to_hash("meta" => {"page" => 2}).must_equal(
|
443
|
-
{
|
444
|
-
"songs"=>[{"id"=>1}, {"id"=>1}],
|
445
|
-
"meta" =>{"page"=>2}
|
446
|
-
}
|
447
|
-
)
|
448
|
-
end
|
449
|
-
end
|
450
|
-
end
|
451
|
-
end
|
data/test/lib/runner.rb
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
require 'open-uri'
|
2
|
-
require 'net/http'
|
3
|
-
require 'timeout'
|
4
|
-
|
5
|
-
# Helps you spinning up and shutting down your own sinatra app. This is especially helpful for running
|
6
|
-
# real network tests against a sinatra backend.
|
7
|
-
#
|
8
|
-
# The backend server could look like the following (in test/server.rb).
|
9
|
-
#
|
10
|
-
# require "sinatra"
|
11
|
-
#
|
12
|
-
# get "/" do
|
13
|
-
# "Cheers from test server"
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
# get "/ping" do
|
17
|
-
# "1"
|
18
|
-
# end
|
19
|
-
#
|
20
|
-
# Note that you need to implement a ping action for internal use.
|
21
|
-
#
|
22
|
-
# Next, you need to write your runner.
|
23
|
-
#
|
24
|
-
# require 'sinatra/runner'
|
25
|
-
#
|
26
|
-
# class Runner < Sinatra::Runner
|
27
|
-
# def app_file
|
28
|
-
# File.expand_path("../server.rb", __FILE__)
|
29
|
-
# end
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
# Override Runner#app_file, #command, #port, #protocol and #ping_path for customization.
|
33
|
-
#
|
34
|
-
# Whereever you need this test backend, here's how you manage it. The following example assumes you
|
35
|
-
# have a test in your app that needs to be run against your test backend.
|
36
|
-
#
|
37
|
-
# runner = ServerRunner.new
|
38
|
-
# runner.run
|
39
|
-
#
|
40
|
-
# # ..tests against localhost:4567 here..
|
41
|
-
#
|
42
|
-
# runner.kill
|
43
|
-
#
|
44
|
-
# For an example, check https://github.com/apotonick/roar/blob/master/test/test_helper.rb
|
45
|
-
module Sinatra
|
46
|
-
class Runner
|
47
|
-
def app_file
|
48
|
-
File.expand_path("../server.rb", __FILE__)
|
49
|
-
end
|
50
|
-
|
51
|
-
def run
|
52
|
-
#puts command
|
53
|
-
@pipe = start
|
54
|
-
@started = Time.now
|
55
|
-
warn "#{server} up and running on port #{port}" if ping
|
56
|
-
end
|
57
|
-
|
58
|
-
def kill
|
59
|
-
return unless pipe
|
60
|
-
Process.kill("KILL", pipe.pid)
|
61
|
-
rescue NotImplementedError
|
62
|
-
system "kill -9 #{pipe.pid}"
|
63
|
-
rescue Errno::ESRCH
|
64
|
-
end
|
65
|
-
|
66
|
-
def get(url)
|
67
|
-
Timeout.timeout(1) { get_url("#{protocol}://127.0.0.1:#{port}#{url}") }
|
68
|
-
end
|
69
|
-
|
70
|
-
def log
|
71
|
-
@log ||= ""
|
72
|
-
loop { @log << pipe.read_nonblock(1) }
|
73
|
-
rescue Exception
|
74
|
-
@log
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
attr_accessor :pipe
|
79
|
-
|
80
|
-
def start
|
81
|
-
IO.popen(command)
|
82
|
-
end
|
83
|
-
|
84
|
-
def command # to be overwritten
|
85
|
-
"bundle exec ruby #{app_file} -p #{port} -e production"
|
86
|
-
end
|
87
|
-
|
88
|
-
def ping(timeout=30)
|
89
|
-
loop do
|
90
|
-
return if alive?
|
91
|
-
if Time.now - @started > timeout
|
92
|
-
$stderr.puts command, log
|
93
|
-
fail "timeout"
|
94
|
-
else
|
95
|
-
sleep 0.1
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def alive?
|
101
|
-
3.times { get(ping_path) }
|
102
|
-
true
|
103
|
-
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, EOFError, SystemCallError, OpenURI::HTTPError, Timeout::Error
|
104
|
-
false
|
105
|
-
end
|
106
|
-
|
107
|
-
def ping_path # to be overwritten
|
108
|
-
'/ping'
|
109
|
-
end
|
110
|
-
|
111
|
-
def port # to be overwritten
|
112
|
-
4567
|
113
|
-
end
|
114
|
-
|
115
|
-
def protocol
|
116
|
-
"http"
|
117
|
-
end
|
118
|
-
|
119
|
-
def get_url(url)
|
120
|
-
uri = URI.parse(url)
|
121
|
-
|
122
|
-
return uri.read unless protocol == "https"
|
123
|
-
get_https_url(uri)
|
124
|
-
end
|
125
|
-
|
126
|
-
def get_https_url(uri)
|
127
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
128
|
-
http.use_ssl = true
|
129
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
130
|
-
request = Net::HTTP::Get.new(uri.request_uri)
|
131
|
-
http.request(request).body
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|