web_fetch 0.2.1 → 0.3.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 +1 -0
- data/lib/web_fetch.rb +3 -4
- data/lib/web_fetch/client.rb +14 -15
- data/lib/web_fetch/{event_machine_helpers.rb → concerns/event_machine_helpers.rb} +9 -1
- data/lib/web_fetch/concerns/http_helpers.rb +41 -13
- data/lib/web_fetch/promise.rb +4 -1
- data/lib/web_fetch/result.rb +2 -1
- data/lib/web_fetch/retriever.rb +1 -1
- data/lib/web_fetch/server.rb +4 -2
- data/lib/web_fetch/version.rb +1 -1
- data/spec/client_spec.rb +10 -3
- data/spec/gatherer_spec.rb +1 -1
- data/spec/result_spec.rb +3 -1
- data/spec/server_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/swagger.yaml +4 -0
- data/web_fetch.gemspec +1 -1
- metadata +16 -17
- data/lib/web_fetch/http_helpers.rb +0 -90
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aab3d826db4d54d4ecd8f935086af80ee34edf38b80c62cfeaed980a5e045f31
|
4
|
+
data.tar.gz: dd4818dd4dcfb3949b37ae124370871906558e185f573ca6f9f9c0a65e1c33a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f525afda585cc0f785db99477a0f6cda72cca602cc0a84bc6726c72214c76a8074069a9d034c9c050cc4a1815f73ca164104755c8325b86361314d1a9eeb05bf
|
7
|
+
data.tar.gz: 9f5678f845dee9af389ff24b46f96189c06ca6255dd8ba88da1b265a4bad1732736b8a9cfc547500f3c6e157c3250fcf4c84ab93558232149251be9f61ac5fdf
|
data/README.md
CHANGED
@@ -96,6 +96,7 @@ result.headers
|
|
96
96
|
result.status # HTTP status code
|
97
97
|
result.success? # False if a network error (not HTTP error) occurred
|
98
98
|
result.error # Underlying network error if applicable
|
99
|
+
result.response_time
|
99
100
|
```
|
100
101
|
|
101
102
|
Note that `WebFech::Promise#fetch` will block until the result is complete by default. If you want to continue executing other code if the result is not ready (e.g. to see if any other results are ready), you can pass `wait: false`
|
data/lib/web_fetch.rb
CHANGED
@@ -10,7 +10,7 @@ require 'json'
|
|
10
10
|
require 'digest'
|
11
11
|
require 'securerandom'
|
12
12
|
require 'faraday'
|
13
|
-
require '
|
13
|
+
require 'subprocess'
|
14
14
|
require 'active_support/gzip'
|
15
15
|
|
16
16
|
locales_path = File.expand_path('../config/locales/*.yml', __dir__)
|
@@ -26,10 +26,9 @@ end
|
|
26
26
|
|
27
27
|
require 'web_fetch/logger'
|
28
28
|
require 'web_fetch/helpers'
|
29
|
-
require 'web_fetch/event_machine_helpers'
|
30
|
-
require 'web_fetch/http_helpers'
|
31
|
-
require 'web_fetch/concerns/validatable'
|
29
|
+
require 'web_fetch/concerns/event_machine_helpers'
|
32
30
|
require 'web_fetch/concerns/http_helpers'
|
31
|
+
require 'web_fetch/concerns/validatable'
|
33
32
|
require 'web_fetch/concerns/client_http'
|
34
33
|
require 'web_fetch/storage'
|
35
34
|
require 'web_fetch/server'
|
data/lib/web_fetch/client.rb
CHANGED
@@ -16,17 +16,17 @@ module WebFetch
|
|
16
16
|
|
17
17
|
def self.create(host, port, options = {})
|
18
18
|
# Will block until process is responsive
|
19
|
-
process =
|
19
|
+
process = build_process(host, port, options)
|
20
20
|
client = new(host, port, process: process)
|
21
21
|
sleep 0.1 until client.alive?
|
22
22
|
client
|
23
23
|
end
|
24
24
|
|
25
25
|
def stop
|
26
|
-
# Will block until process dies
|
27
26
|
return if @process.nil?
|
28
27
|
|
29
|
-
@process.
|
28
|
+
@process.terminate
|
29
|
+
# Will block until process dies
|
30
30
|
@process.wait
|
31
31
|
end
|
32
32
|
|
@@ -77,22 +77,16 @@ module WebFetch
|
|
77
77
|
end
|
78
78
|
|
79
79
|
class << self
|
80
|
-
def spawn(host, port, options)
|
81
|
-
process = build_process(host, port, options)
|
82
|
-
process.cwd = File.join(File.dirname(__dir__), '..')
|
83
|
-
process.io.inherit!
|
84
|
-
process.start
|
85
|
-
process
|
86
|
-
end
|
87
|
-
|
88
|
-
private
|
89
|
-
|
90
80
|
def build_process(host, port, options)
|
91
81
|
command = options.fetch(:start_command, standard_start_command)
|
92
82
|
args = ['--host', host, '--port', port.to_s]
|
93
83
|
args += ['--log', options[:log]] unless options[:log].nil?
|
94
84
|
args.push('--daemonize') if options[:daemonize]
|
95
|
-
|
85
|
+
Subprocess.popen(command + args, cwd: cwd)
|
86
|
+
end
|
87
|
+
|
88
|
+
def cwd
|
89
|
+
File.join(File.dirname(__dir__), '..')
|
96
90
|
end
|
97
91
|
|
98
92
|
def standard_start_command
|
@@ -112,13 +106,18 @@ module WebFetch
|
|
112
106
|
|
113
107
|
def new_result(outcome)
|
114
108
|
response = outcome[:response]
|
109
|
+
# FIXME: This is sort-of duplicated from `Promise#new_result` but we
|
110
|
+
# build it very slightly differently. This means we have to update in
|
111
|
+
# both places if we change the structure. Not quite sure how to unify
|
112
|
+
# this and ensure the same structure in both places.
|
115
113
|
Result.new(
|
116
114
|
body: response[:body],
|
117
115
|
headers: response[:headers],
|
118
116
|
status: response[:status],
|
119
117
|
success: response[:success],
|
120
118
|
error: response[:error],
|
121
|
-
uid: outcome[:uid]
|
119
|
+
uid: outcome[:uid],
|
120
|
+
response_time: response[:response_time]
|
122
121
|
)
|
123
122
|
end
|
124
123
|
|
@@ -3,7 +3,9 @@
|
|
3
3
|
module WebFetch
|
4
4
|
# EventMachine layer-specific helpers
|
5
5
|
module EventMachineHelpers
|
6
|
-
def request_async(
|
6
|
+
def request_async(target)
|
7
|
+
request = target[:request]
|
8
|
+
target[:start_time] = Time.now.utc
|
7
9
|
async_request = EM::HttpRequest.new(request[:url])
|
8
10
|
method = request.fetch(:method, 'GET').downcase.to_sym
|
9
11
|
async_request.public_send(
|
@@ -17,11 +19,13 @@ module WebFetch
|
|
17
19
|
def apply_callbacks(request)
|
18
20
|
request[:deferred].callback do
|
19
21
|
Logger.debug("HTTP fetch complete for uid: #{request[:uid]}")
|
22
|
+
save_response_time(request)
|
20
23
|
request[:succeeded] = true
|
21
24
|
end
|
22
25
|
|
23
26
|
request[:deferred].errback do
|
24
27
|
Logger.debug("HTTP fetch failed for uid: #{request[:uid]}")
|
28
|
+
save_response_time(request)
|
25
29
|
request[:failed] = true
|
26
30
|
end
|
27
31
|
end
|
@@ -45,5 +49,9 @@ module WebFetch
|
|
45
49
|
end
|
46
50
|
end
|
47
51
|
end
|
52
|
+
|
53
|
+
def save_response_time(request)
|
54
|
+
request[:response_time] = Time.now.utc - request[:start_time]
|
55
|
+
end
|
48
56
|
end
|
49
57
|
end
|
@@ -1,15 +1,34 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module WebFetch
|
4
|
-
|
4
|
+
# Convenience methods for WebFetch HTTP layer
|
5
|
+
module HTTPHelpers
|
6
|
+
def respond_immediately(result, response)
|
7
|
+
response.status = result[:status]
|
8
|
+
response.content = compress(result[:payload].to_json)
|
9
|
+
response.send_response
|
10
|
+
end
|
11
|
+
|
12
|
+
def pending(result, response)
|
13
|
+
respond_immediately({
|
14
|
+
payload: {
|
15
|
+
uid: result[:request][:uid],
|
16
|
+
pending: true,
|
17
|
+
message: I18n.t(:pending)
|
18
|
+
}
|
19
|
+
}, response)
|
20
|
+
end
|
21
|
+
|
5
22
|
def compress(string)
|
23
|
+
return string unless accept_gzip?
|
24
|
+
|
6
25
|
ActiveSupport::Gzip.compress(string)
|
7
26
|
end
|
8
27
|
|
9
28
|
def default_headers(response)
|
10
29
|
response.headers['Content-Type'] = 'application/json; charset=utf-8'
|
11
30
|
response.headers['Cache-Control'] = 'max-age=0, private, must-revalidate'
|
12
|
-
response.headers['Content-Encoding'] = 'gzip'
|
31
|
+
response.headers['Content-Encoding'] = 'gzip' if accept_gzip?
|
13
32
|
response.headers['Vary'] = 'Accept-Encoding'
|
14
33
|
end
|
15
34
|
|
@@ -26,39 +45,48 @@ module WebFetch
|
|
26
45
|
JSON.parse(@http_post_content, symbolize_names: true)
|
27
46
|
end
|
28
47
|
|
29
|
-
def succeed(
|
48
|
+
def succeed(request, response)
|
30
49
|
response.status = 200
|
31
|
-
response.content = compress(JSON.dump(success(
|
50
|
+
response.content = compress(JSON.dump(success(request)))
|
32
51
|
response.send_response
|
52
|
+
storage.delete(request[:uid])
|
33
53
|
end
|
34
54
|
|
35
|
-
def success(
|
36
|
-
result =
|
55
|
+
def success(request)
|
56
|
+
result = request[:deferred]
|
37
57
|
{ response: {
|
38
58
|
success: true,
|
39
59
|
body: result.response,
|
40
60
|
headers: result.headers,
|
41
|
-
status: result.response_header.status
|
61
|
+
status: result.response_header.status,
|
62
|
+
response_time: request[:response_time]
|
42
63
|
},
|
43
|
-
uid:
|
64
|
+
uid: request[:uid] }
|
44
65
|
end
|
45
66
|
|
46
|
-
def fail_(
|
67
|
+
def fail_(request, response)
|
47
68
|
response.status = 200
|
48
|
-
response.content = compress(JSON.dump(failure(
|
69
|
+
response.content = compress(JSON.dump(failure(request)))
|
49
70
|
response.send_response
|
71
|
+
storage.delete(request[:uid])
|
50
72
|
end
|
51
73
|
|
52
|
-
def failure(
|
53
|
-
result =
|
74
|
+
def failure(request)
|
75
|
+
result = request[:deferred]
|
54
76
|
{ response: {
|
55
77
|
success: false,
|
56
78
|
body: result.response,
|
57
79
|
headers: result.headers,
|
58
80
|
status: result.response_header.status,
|
81
|
+
response_time: request[:response_time],
|
59
82
|
error: (result.error&.inspect)
|
60
83
|
},
|
61
|
-
uid:
|
84
|
+
uid: request[:uid] }
|
85
|
+
end
|
86
|
+
|
87
|
+
def accept_gzip?
|
88
|
+
# em-http-request doesn't do us any favours with parsing the HTTP headers
|
89
|
+
@http_headers.downcase.include?('accept-encoding: gzip')
|
62
90
|
end
|
63
91
|
end
|
64
92
|
end
|
data/lib/web_fetch/promise.rb
CHANGED
@@ -62,13 +62,16 @@ module WebFetch
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def new_result(response)
|
65
|
+
# XXX: Any changes to this structure need to be reflected by
|
66
|
+
# `Client#new_result`
|
65
67
|
Result.new(
|
66
68
|
body: response[:body],
|
67
69
|
headers: response[:headers],
|
68
70
|
status: response[:status],
|
69
71
|
success: @raw_result[:response][:success],
|
70
72
|
error: @raw_result[:response][:error],
|
71
|
-
uid: @uid
|
73
|
+
uid: @uid,
|
74
|
+
response_time: @raw_result[:response_time]
|
72
75
|
)
|
73
76
|
end
|
74
77
|
end
|
data/lib/web_fetch/result.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module WebFetch
|
4
4
|
class Result
|
5
|
-
attr_reader :body, :headers, :status, :error, :uid
|
5
|
+
attr_reader :body, :headers, :status, :error, :uid, :response_time
|
6
6
|
|
7
7
|
def initialize(options = {})
|
8
8
|
@pending = options.fetch(:pending, false)
|
@@ -14,6 +14,7 @@ module WebFetch
|
|
14
14
|
@success = options.fetch(:success)
|
15
15
|
@error = options.fetch(:error)
|
16
16
|
@uid = options.fetch(:uid)
|
17
|
+
@response_time = options.fetch(:response_time)
|
17
18
|
end
|
18
19
|
|
19
20
|
def pending?
|
data/lib/web_fetch/retriever.rb
CHANGED
@@ -17,7 +17,6 @@ module WebFetch
|
|
17
17
|
def find
|
18
18
|
request = @server.storage.fetch(@uid)
|
19
19
|
return not_found if request.nil?
|
20
|
-
return not_found if request.nil?
|
21
20
|
return request.merge(pending: true) if pending?(request)
|
22
21
|
|
23
22
|
request
|
@@ -42,6 +41,7 @@ module WebFetch
|
|
42
41
|
def pending?(request)
|
43
42
|
return false if request.nil?
|
44
43
|
return false if request[:succeeded]
|
44
|
+
return false if request[:failed]
|
45
45
|
# User requested blocking operation so we will wait until item is ready
|
46
46
|
# rather than return a `pending` status
|
47
47
|
return false if @block
|
data/lib/web_fetch/server.rb
CHANGED
@@ -29,8 +29,10 @@ module WebFetch
|
|
29
29
|
# #process_http_request and subsequently WebFetch::Router#route
|
30
30
|
def gather(targets)
|
31
31
|
targets.each do |target|
|
32
|
-
http = request_async(target
|
33
|
-
request = { uid: target[:uid],
|
32
|
+
http = request_async(target)
|
33
|
+
request = { uid: target[:uid],
|
34
|
+
start_time: target[:start_time],
|
35
|
+
deferred: http }
|
34
36
|
apply_callbacks(request)
|
35
37
|
@storage.store(target[:uid], request)
|
36
38
|
end
|
data/lib/web_fetch/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
describe WebFetch::Client do
|
4
|
-
let(:client) { described_class.new('localhost',
|
4
|
+
let(:client) { described_class.new('localhost', 60_085, log: File::NULL) }
|
5
5
|
|
6
6
|
before(:each) do
|
7
7
|
stub_request(:any, 'http://blah.blah/success')
|
@@ -63,6 +63,7 @@ describe WebFetch::Client do
|
|
63
63
|
subject { client.fetch(responses.first.uid) }
|
64
64
|
|
65
65
|
it { is_expected.to be_a WebFetch::Result }
|
66
|
+
|
66
67
|
context 'no matching request found' do
|
67
68
|
subject { proc { client.fetch('not-found') } }
|
68
69
|
it { is_expected.to raise_error WebFetch::RequestNotFoundError }
|
@@ -80,6 +81,7 @@ describe WebFetch::Client do
|
|
80
81
|
retrieved = client.retrieve_by_uid(uid)
|
81
82
|
expect(retrieved[:response][:status]).to eql 200
|
82
83
|
expect(retrieved[:response][:body]).to eql 'hello, everybody'
|
84
|
+
expect(retrieved[:response][:response_time]).to be_a Float
|
83
85
|
expect(retrieved[:uid]).to eql uid
|
84
86
|
end
|
85
87
|
|
@@ -111,7 +113,7 @@ describe WebFetch::Client do
|
|
111
113
|
|
112
114
|
describe '#create' do
|
113
115
|
it 'spawns a server and returns a client able to connect' do
|
114
|
-
client = described_class.create('localhost',
|
116
|
+
client = described_class.create('localhost', 60_085, log: File::NULL)
|
115
117
|
expect(client.alive?).to be true
|
116
118
|
client.stop
|
117
119
|
end
|
@@ -119,7 +121,12 @@ describe WebFetch::Client do
|
|
119
121
|
|
120
122
|
describe '#stop' do
|
121
123
|
it 'can spawn a server and stop the process when needed' do
|
122
|
-
|
124
|
+
pending <<-PENDING.gsub(/\s+/, ' ')
|
125
|
+
I can't quite figure out what's going on here but the parent process
|
126
|
+
seems to be holding on to the child process' FDs and keeping the server
|
127
|
+
alive. `Client#stop` definitely works though ..."
|
128
|
+
PENDING
|
129
|
+
client = described_class.create('localhost', 60_085, log: File::NULL)
|
123
130
|
expect(client.alive?).to be true
|
124
131
|
client.stop
|
125
132
|
expect(client.alive?).to be false
|
data/spec/gatherer_spec.rb
CHANGED
data/spec/result_spec.rb
CHANGED
@@ -9,7 +9,8 @@ RSpec.describe WebFetch::Result do
|
|
9
9
|
pending: false,
|
10
10
|
success: false,
|
11
11
|
error: 'foo error happened',
|
12
|
-
uid: 'uid123'
|
12
|
+
uid: 'uid123',
|
13
|
+
response_time: 123.45
|
13
14
|
)
|
14
15
|
end
|
15
16
|
|
@@ -24,4 +25,5 @@ RSpec.describe WebFetch::Result do
|
|
24
25
|
its(:success?) { is_expected.to be false }
|
25
26
|
its(:error) { is_expected.to eql 'foo error happened' }
|
26
27
|
its(:uid) { is_expected.to eql 'uid123' }
|
28
|
+
its(:response_time) { is_expected.to eql 123.45 }
|
27
29
|
end
|
data/spec/server_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
data/swagger.yaml
CHANGED
@@ -117,6 +117,8 @@ definitions:
|
|
117
117
|
type: object
|
118
118
|
status:
|
119
119
|
type: integer
|
120
|
+
response_time:
|
121
|
+
type: float
|
120
122
|
Found:
|
121
123
|
type: object
|
122
124
|
properties:
|
@@ -134,6 +136,8 @@ definitions:
|
|
134
136
|
type: integer
|
135
137
|
pending:
|
136
138
|
type: boolean
|
139
|
+
response_time:
|
140
|
+
type: float
|
137
141
|
|
138
142
|
GatherResponse:
|
139
143
|
type: array
|
data/web_fetch.gemspec
CHANGED
@@ -21,7 +21,6 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.executables << 'web_fetch_control'
|
22
22
|
|
23
23
|
s.add_dependency 'activesupport', '>= 4.0'
|
24
|
-
s.add_dependency 'childprocess', '~> 0.5'
|
25
24
|
s.add_dependency 'daemons', '~> 1.2'
|
26
25
|
s.add_dependency 'em-http-request', '~> 1.1'
|
27
26
|
s.add_dependency 'em-logger', '~> 0.1'
|
@@ -32,6 +31,7 @@ Gem::Specification.new do |s|
|
|
32
31
|
s.add_dependency 'hanami-utils', '~> 1.0'
|
33
32
|
s.add_dependency 'i18n', '>= 0.7'
|
34
33
|
s.add_dependency 'rack', '>= 1.6'
|
34
|
+
s.add_dependency 'subprocess', '~> 1.3'
|
35
35
|
|
36
36
|
s.add_development_dependency 'byebug', '~> 9.0'
|
37
37
|
s.add_development_dependency 'rspec', '~> 3.5'
|
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.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Farrell
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: childprocess
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0.5'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0.5'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: daemons
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -178,6 +164,20 @@ dependencies:
|
|
178
164
|
- - ">="
|
179
165
|
- !ruby/object:Gem::Version
|
180
166
|
version: '1.6'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: subprocess
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '1.3'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '1.3'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: byebug
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -277,13 +277,12 @@ files:
|
|
277
277
|
- lib/web_fetch.rb
|
278
278
|
- lib/web_fetch/client.rb
|
279
279
|
- lib/web_fetch/concerns/client_http.rb
|
280
|
+
- lib/web_fetch/concerns/event_machine_helpers.rb
|
280
281
|
- lib/web_fetch/concerns/http_helpers.rb
|
281
282
|
- lib/web_fetch/concerns/validatable.rb
|
282
283
|
- lib/web_fetch/errors.rb
|
283
|
-
- lib/web_fetch/event_machine_helpers.rb
|
284
284
|
- lib/web_fetch/gatherer.rb
|
285
285
|
- lib/web_fetch/helpers.rb
|
286
|
-
- lib/web_fetch/http_helpers.rb
|
287
286
|
- lib/web_fetch/logger.rb
|
288
287
|
- lib/web_fetch/promise.rb
|
289
288
|
- lib/web_fetch/request.rb
|
@@ -1,90 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module WebFetch
|
4
|
-
# Convenience methods for WebFetch HTTP layer
|
5
|
-
module HTTPHelpers
|
6
|
-
def respond_immediately(result, response)
|
7
|
-
response.status = result[:status]
|
8
|
-
response.content = compress(result[:payload].to_json)
|
9
|
-
response.send_response
|
10
|
-
end
|
11
|
-
|
12
|
-
def pending(result, response)
|
13
|
-
respond_immediately({
|
14
|
-
payload: {
|
15
|
-
uid: result[:request][:uid],
|
16
|
-
pending: true,
|
17
|
-
message: I18n.t(:pending)
|
18
|
-
}
|
19
|
-
}, response)
|
20
|
-
end
|
21
|
-
|
22
|
-
def compress(string)
|
23
|
-
return string unless accept_gzip?
|
24
|
-
|
25
|
-
ActiveSupport::Gzip.compress(string)
|
26
|
-
end
|
27
|
-
|
28
|
-
def default_headers(response)
|
29
|
-
response.headers['Content-Type'] = 'application/json; charset=utf-8'
|
30
|
-
response.headers['Cache-Control'] = 'max-age=0, private, must-revalidate'
|
31
|
-
response.headers['Content-Encoding'] = 'gzip' if accept_gzip?
|
32
|
-
response.headers['Vary'] = 'Accept-Encoding'
|
33
|
-
end
|
34
|
-
|
35
|
-
def request_params
|
36
|
-
{ method: @http_request_method,
|
37
|
-
query_string: @http_query_string,
|
38
|
-
post_data: post_data,
|
39
|
-
server: self }
|
40
|
-
end
|
41
|
-
|
42
|
-
def post_data
|
43
|
-
return nil unless @http_post_content
|
44
|
-
|
45
|
-
JSON.parse(@http_post_content, symbolize_names: true)
|
46
|
-
end
|
47
|
-
|
48
|
-
def succeed(request, response)
|
49
|
-
response.status = 200
|
50
|
-
response.content = compress(JSON.dump(success(request)))
|
51
|
-
response.send_response
|
52
|
-
storage.delete(request[:uid])
|
53
|
-
end
|
54
|
-
|
55
|
-
def success(request)
|
56
|
-
result = request[:deferred]
|
57
|
-
{ response: {
|
58
|
-
success: true,
|
59
|
-
body: result.response,
|
60
|
-
headers: result.headers,
|
61
|
-
status: result.response_header.status
|
62
|
-
},
|
63
|
-
uid: request[:uid] }
|
64
|
-
end
|
65
|
-
|
66
|
-
def fail_(request, response)
|
67
|
-
response.status = 200
|
68
|
-
response.content = compress(JSON.dump(failure(request)))
|
69
|
-
response.send_response
|
70
|
-
storage.delete(request[:uid])
|
71
|
-
end
|
72
|
-
|
73
|
-
def failure(request)
|
74
|
-
result = request[:deferred]
|
75
|
-
{ response: {
|
76
|
-
success: false,
|
77
|
-
body: result.response,
|
78
|
-
headers: result.headers,
|
79
|
-
status: result.response_header.status,
|
80
|
-
error: (result.error&.inspect)
|
81
|
-
},
|
82
|
-
uid: request[:uid] }
|
83
|
-
end
|
84
|
-
|
85
|
-
def accept_gzip?
|
86
|
-
# em-http-request doesn't do us any favours with parsing the HTTP headers
|
87
|
-
@http_headers.downcase.include?('accept-encoding: gzip')
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|