web_fetch 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +132 -52
- data/config/locales/en.yml +4 -0
- data/doc/examples/blocking_requests.rb +33 -0
- data/doc/examples/non_blocking_requests.rb +34 -0
- data/doc/examples/use_uid_for_request.rb +28 -0
- data/docker/Dockerfile +3 -0
- data/lib/web_fetch/client.rb +47 -17
- data/lib/web_fetch/concerns/client_http.rb +25 -0
- data/lib/web_fetch/errors.rb +15 -0
- data/lib/web_fetch/event_machine_helpers.rb +26 -13
- data/lib/web_fetch/http_helpers.rb +22 -10
- data/lib/web_fetch/promise.rb +75 -0
- data/lib/web_fetch/request.rb +64 -0
- data/lib/web_fetch/resources.rb +7 -3
- data/lib/web_fetch/result.rb +31 -0
- data/lib/web_fetch/retriever.rb +17 -4
- data/lib/web_fetch/router.rb +22 -10
- data/lib/web_fetch/server.rb +22 -15
- data/lib/web_fetch/storage.rb +9 -4
- data/lib/web_fetch/version.rb +1 -1
- data/lib/web_fetch.rb +5 -0
- data/spec/client_spec.rb +52 -3
- data/spec/promise_spec.rb +119 -0
- data/spec/request_spec.rb +73 -0
- data/spec/resources_spec.rb +17 -1
- data/spec/result_spec.rb +27 -0
- data/spec/retriever_spec.rb +11 -8
- data/spec/router_spec.rb +6 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/storage_spec.rb +6 -3
- data/swagger.yaml +42 -6
- data/web_fetch.gemspec +1 -0
- metadata +27 -2
- data/doc/client_example.rb +0 -19
data/spec/resources_spec.rb
CHANGED
@@ -24,7 +24,7 @@ describe WebFetch::Resources do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
describe 'retrieve' do
|
27
|
+
describe '.retrieve' do
|
28
28
|
it 'gives 404 not found when unrecognised uid requested' do
|
29
29
|
result = described_class.retrieve(server, uid: '123')
|
30
30
|
expect(result[:status]).to eql 404
|
@@ -39,4 +39,20 @@ describe WebFetch::Resources do
|
|
39
39
|
expect(error).to eql I18n.t(:hash_not_found)
|
40
40
|
end
|
41
41
|
end
|
42
|
+
|
43
|
+
describe '.find' do
|
44
|
+
it 'gives 404 not found when unrecognised uid requested' do
|
45
|
+
result = described_class.find(server, uid: '123')
|
46
|
+
expect(result[:status]).to eql 404
|
47
|
+
error = result[:payload][:error]
|
48
|
+
expect(error).to eql I18n.t(:uid_not_found)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'gives 404 not found when unrecognised hash requested' do
|
52
|
+
result = described_class.find(server, hash: 'abc')
|
53
|
+
expect(result[:status]).to eql 404
|
54
|
+
error = result[:payload][:error]
|
55
|
+
expect(error).to eql I18n.t(:hash_not_found)
|
56
|
+
end
|
57
|
+
end
|
42
58
|
end
|
data/spec/result_spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe WebFetch::Result do
|
4
|
+
let(:result) do
|
5
|
+
described_class.new(
|
6
|
+
body: 'abc123',
|
7
|
+
headers: { 'Foo' => 'Bar' },
|
8
|
+
status: 200,
|
9
|
+
pending: false,
|
10
|
+
success: false,
|
11
|
+
error: 'foo error happened',
|
12
|
+
uid: 'uid123'
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
subject { result }
|
17
|
+
|
18
|
+
it { is_expected.to be_a described_class }
|
19
|
+
its(:body) { is_expected.to eql 'abc123' }
|
20
|
+
its(:headers) { are_expected.to eql('Foo' => 'Bar') }
|
21
|
+
its(:status) { is_expected.to eql 200 }
|
22
|
+
its(:pending?) { is_expected.to be false }
|
23
|
+
its(:complete?) { is_expected.to be true }
|
24
|
+
its(:success?) { is_expected.to be false }
|
25
|
+
its(:error) { is_expected.to eql 'foo error happened' }
|
26
|
+
its(:uid) { is_expected.to eql 'uid123' }
|
27
|
+
end
|
data/spec/retriever_spec.rb
CHANGED
@@ -5,31 +5,34 @@ describe WebFetch::Retriever do
|
|
5
5
|
let(:valid_params) { { uid: 'abc123' } }
|
6
6
|
|
7
7
|
it 'is initialisable with params' do
|
8
|
-
expect(described_class.new(server, valid_params))
|
8
|
+
expect(described_class.new(server, valid_params, {}))
|
9
|
+
.to be_a described_class
|
9
10
|
end
|
10
11
|
|
11
12
|
describe 'validation' do
|
12
13
|
context 'valid' do
|
13
14
|
it 'is valid when `uid` given' do
|
14
|
-
retriever = described_class.new(server, uid: 'abc123')
|
15
|
+
retriever = described_class.new(server, { uid: 'abc123' }, {})
|
15
16
|
expect(retriever.valid?).to be true
|
16
17
|
end
|
17
18
|
|
18
19
|
it 'is valid when `hash` given' do
|
19
|
-
retriever = described_class.new(server, hash: 'def456')
|
20
|
+
retriever = described_class.new(server, { hash: 'def456' }, {})
|
20
21
|
expect(retriever.valid?).to be true
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
25
|
context 'invalid' do
|
25
26
|
it 'is invalid if both `hash` and `uid` given' do
|
26
|
-
retriever = described_class.new(
|
27
|
+
retriever = described_class.new(
|
28
|
+
server, { hash: 'def456', uid: 'abc123' }, {}
|
29
|
+
)
|
27
30
|
expect(retriever.valid?).to be false
|
28
31
|
expect(retriever.errors).to include I18n.t(:hash_or_uid_but_not_both)
|
29
32
|
end
|
30
33
|
|
31
34
|
it 'is invalid if neither `hash` nor `uid` given' do
|
32
|
-
retriever = described_class.new(server, {})
|
35
|
+
retriever = described_class.new(server, {}, {})
|
33
36
|
expect(retriever.valid?).to be false
|
34
37
|
expect(retriever.errors).to include I18n.t(:missing_hash_and_uid)
|
35
38
|
end
|
@@ -38,12 +41,12 @@ describe WebFetch::Retriever do
|
|
38
41
|
|
39
42
|
describe '#find' do
|
40
43
|
it 'returns `nil` when given uid has not been requested' do
|
41
|
-
retriever = described_class.new(server, uid: 'nope')
|
44
|
+
retriever = described_class.new(server, { uid: 'nope' }, {})
|
42
45
|
expect(retriever.find).to be_nil
|
43
46
|
end
|
44
47
|
|
45
48
|
it 'returns `nil` when given hash has not been requested' do
|
46
|
-
retriever = described_class.new(server, hash: 'also nope')
|
49
|
+
retriever = described_class.new(server, { hash: 'also nope' }, {})
|
47
50
|
expect(retriever.find).to be_nil
|
48
51
|
end
|
49
52
|
|
@@ -61,7 +64,7 @@ describe WebFetch::Retriever do
|
|
61
64
|
expect(server).to receive(:storage)
|
62
65
|
.and_return(uid => { body: 'fake body' })
|
63
66
|
|
64
|
-
retriever = described_class.new(server, uid: uid)
|
67
|
+
retriever = described_class.new(server, { uid: uid }, {})
|
65
68
|
expect(retriever.find[:body]).to eql 'fake body'
|
66
69
|
end
|
67
70
|
end
|
data/spec/router_spec.rb
CHANGED
@@ -20,7 +20,12 @@ describe WebFetch::Router do
|
|
20
20
|
|
21
21
|
it 'provides a route to GET /retrieve' do
|
22
22
|
expect(WebFetch::Resources).to receive(:retrieve).and_return('hello')
|
23
|
-
expect(router.route('/retrieve', method: 'GET')).to eql 'hello'
|
23
|
+
expect(router.route('/retrieve/123', method: 'GET')).to eql 'hello'
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'provides a route to GET /find' do
|
27
|
+
expect(WebFetch::Resources).to receive(:find).and_return('hello')
|
28
|
+
expect(router.route('/find/123', method: 'GET')).to eql 'hello'
|
24
29
|
end
|
25
30
|
|
26
31
|
it 'decodes `json` parameter and merges into request params' do
|
data/spec/spec_helper.rb
CHANGED
data/spec/storage_spec.rb
CHANGED
@@ -14,11 +14,14 @@ describe WebFetch::Storage do
|
|
14
14
|
described_class.store(:key, :value)
|
15
15
|
expect(described_class.fetch(:key)).to eql :value
|
16
16
|
end
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
+
describe '.delete' do
|
20
|
+
it 'deletes stored values' do
|
19
21
|
described_class.store(:key, :value)
|
20
|
-
described_class.fetch(:key)
|
21
|
-
|
22
|
+
expect(described_class.fetch(:key)).to eql :value
|
23
|
+
described_class.delete(:key)
|
24
|
+
expect(described_class.fetch(:key)).to eql nil
|
22
25
|
end
|
23
26
|
end
|
24
27
|
end
|
data/swagger.yaml
CHANGED
@@ -22,7 +22,7 @@ paths:
|
|
22
22
|
application:
|
23
23
|
type: string
|
24
24
|
description: WebFetch
|
25
|
-
|
25
|
+
|
26
26
|
/gather:
|
27
27
|
post:
|
28
28
|
summary: Initiate fetching one or more HTTP entities.
|
@@ -42,11 +42,11 @@ paths:
|
|
42
42
|
description: An array of objects providing job IDs and original parameters.
|
43
43
|
schema:
|
44
44
|
$ref: '#/definitions/GatherResponse'
|
45
|
-
|
45
|
+
|
46
46
|
|
47
47
|
/retrieve/{id}:
|
48
48
|
get:
|
49
|
-
summary: Retrieve a gathered HTTP entity.
|
49
|
+
summary: Retrieve a gathered HTTP entity (blocking).
|
50
50
|
description: |
|
51
51
|
Receives a unique identifier and returns the previously requested HTTP entity. This action will block until the entity has been successfully downloaded.
|
52
52
|
parameters:
|
@@ -62,7 +62,26 @@ paths:
|
|
62
62
|
type: object
|
63
63
|
items:
|
64
64
|
$ref: '#/definitions/Retrieved'
|
65
|
-
|
65
|
+
|
66
|
+
/find/{id}:
|
67
|
+
get:
|
68
|
+
summary: Retrieve a gathered HTTP entity (non-blocking).
|
69
|
+
description: |
|
70
|
+
Receives a unique identifier and returns the previously requested HTTP entity. This action will return immediately and provide a pending status if the entity has not finished downloading.
|
71
|
+
parameters:
|
72
|
+
- name: id
|
73
|
+
in: path
|
74
|
+
type: string
|
75
|
+
description: Unique identifier for HTTP entity.
|
76
|
+
required: true
|
77
|
+
responses:
|
78
|
+
200:
|
79
|
+
description: An object containing HTTP entity elements.
|
80
|
+
schema:
|
81
|
+
type: object
|
82
|
+
items:
|
83
|
+
$ref: '#/definitions/Found'
|
84
|
+
|
66
85
|
definitions:
|
67
86
|
Request:
|
68
87
|
type: object
|
@@ -98,7 +117,24 @@ definitions:
|
|
98
117
|
type: object
|
99
118
|
status:
|
100
119
|
type: integer
|
101
|
-
|
120
|
+
Found:
|
121
|
+
type: object
|
122
|
+
properties:
|
123
|
+
response:
|
124
|
+
type: object
|
125
|
+
description: Requested HTTP entity elements.
|
126
|
+
properties:
|
127
|
+
success:
|
128
|
+
type: boolean
|
129
|
+
body:
|
130
|
+
type: string
|
131
|
+
headers:
|
132
|
+
type: object
|
133
|
+
status:
|
134
|
+
type: integer
|
135
|
+
pending:
|
136
|
+
type: boolean
|
137
|
+
|
102
138
|
GatherResponse:
|
103
139
|
type: array
|
104
140
|
items:
|
@@ -112,4 +148,4 @@ definitions:
|
|
112
148
|
description: SHA1 hash of request based on url, query parameters, headers, method [currently this serves no purpose].
|
113
149
|
request:
|
114
150
|
type: object
|
115
|
-
description: Original requested HTTP parameters.
|
151
|
+
description: Original requested HTTP parameters.
|
data/web_fetch.gemspec
CHANGED
@@ -35,6 +35,7 @@ Gem::Specification.new do |s|
|
|
35
35
|
|
36
36
|
s.add_development_dependency 'byebug', '~> 9.0'
|
37
37
|
s.add_development_dependency 'rspec', '~> 3.5'
|
38
|
+
s.add_development_dependency 'rspec-its', '~> 1.2'
|
38
39
|
s.add_development_dependency 'rubocop', '~> 0.59.2'
|
39
40
|
s.add_development_dependency 'webmock', '~> 3.4'
|
40
41
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: web_fetch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Farrell
|
@@ -206,6 +206,20 @@ dependencies:
|
|
206
206
|
- - "~>"
|
207
207
|
- !ruby/object:Gem::Version
|
208
208
|
version: '3.5'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: rspec-its
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '1.2'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '1.2'
|
209
223
|
- !ruby/object:Gem::Dependency
|
210
224
|
name: rubocop
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
@@ -255,18 +269,26 @@ files:
|
|
255
269
|
- bin/web_fetch_control
|
256
270
|
- bin/web_fetch_server
|
257
271
|
- config/locales/en.yml
|
258
|
-
- doc/
|
272
|
+
- doc/examples/blocking_requests.rb
|
273
|
+
- doc/examples/non_blocking_requests.rb
|
274
|
+
- doc/examples/use_uid_for_request.rb
|
259
275
|
- doc/web_fetch_architecture.png
|
276
|
+
- docker/Dockerfile
|
260
277
|
- lib/web_fetch.rb
|
261
278
|
- lib/web_fetch/client.rb
|
279
|
+
- lib/web_fetch/concerns/client_http.rb
|
262
280
|
- lib/web_fetch/concerns/http_helpers.rb
|
263
281
|
- lib/web_fetch/concerns/validatable.rb
|
282
|
+
- lib/web_fetch/errors.rb
|
264
283
|
- lib/web_fetch/event_machine_helpers.rb
|
265
284
|
- lib/web_fetch/gatherer.rb
|
266
285
|
- lib/web_fetch/helpers.rb
|
267
286
|
- lib/web_fetch/http_helpers.rb
|
268
287
|
- lib/web_fetch/logger.rb
|
288
|
+
- lib/web_fetch/promise.rb
|
289
|
+
- lib/web_fetch/request.rb
|
269
290
|
- lib/web_fetch/resources.rb
|
291
|
+
- lib/web_fetch/result.rb
|
270
292
|
- lib/web_fetch/retriever.rb
|
271
293
|
- lib/web_fetch/router.rb
|
272
294
|
- lib/web_fetch/server.rb
|
@@ -278,7 +300,10 @@ files:
|
|
278
300
|
- spec/gatherer_spec.rb
|
279
301
|
- spec/helpers_spec.rb
|
280
302
|
- spec/i18n_spec.rb
|
303
|
+
- spec/promise_spec.rb
|
304
|
+
- spec/request_spec.rb
|
281
305
|
- spec/resources_spec.rb
|
306
|
+
- spec/result_spec.rb
|
282
307
|
- spec/retriever_spec.rb
|
283
308
|
- spec/router_spec.rb
|
284
309
|
- spec/server_spec.rb
|
data/doc/client_example.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Run me with:
|
4
|
-
# bundle exec ruby doc/client_example.rb
|
5
|
-
require 'web_fetch'
|
6
|
-
begin
|
7
|
-
cli = WebFetch::Client.create('localhost', 8077)
|
8
|
-
results = cli.gather([
|
9
|
-
{ url: 'http://localhost:8077/' },
|
10
|
-
{ url: 'http://yahoo.com/' },
|
11
|
-
{ url: 'http://lycos.com/' },
|
12
|
-
{ url: 'http://google.com/' }
|
13
|
-
])
|
14
|
-
results.each do |res|
|
15
|
-
p cli.retrieve_by_uid(res[:uid])
|
16
|
-
end
|
17
|
-
ensure
|
18
|
-
cli.stop
|
19
|
-
end
|