agile-proxy 0.1.23 → 0.1.24
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/agile-proxy.gemspec +1 -0
- data/lib/agile_proxy/handlers/proxy_handler.rb +4 -3
- data/lib/agile_proxy/handlers/request_handler.rb +12 -2
- data/lib/agile_proxy/handlers/stub_handler.rb +2 -2
- data/lib/agile_proxy/model/request_spec.rb +1 -1
- data/lib/agile_proxy/model/response.rb +1 -0
- data/lib/agile_proxy/rack/get_only_cache.rb +30 -0
- data/lib/agile_proxy/servers/api.rb +1 -1
- data/lib/agile_proxy/servers/request_spec_direct.rb +1 -1
- data/lib/agile_proxy/version.rb +1 -1
- data/spec/common_helper.rb +2 -2
- data/spec/unit/agile_proxy/handlers/proxy_handler_spec.rb +5 -5
- data/spec/unit/agile_proxy/handlers/request_handler_spec.rb +13 -0
- data/spec/unit/agile_proxy/model/response_spec.rb +3 -3
- metadata +24 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a81e9033ebf71ca85c882e9c74c0903da777920f
|
4
|
+
data.tar.gz: ad910e5bd7f6aa8fbf198ce40f31103dcb48a7c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 901685ec32ead266c8cb50ebd46103e8fbf9e75ce3fb4dd53dd85d142a2d16533254e4ce7492fabffe7cfe3c8adba22cc159f3b86b70bcdca4dc44c85e2994b3
|
7
|
+
data.tar.gz: 972e90191e116c30c0d54c9293b49a548aa2701499ab080c2db9eab4533e801897724346b30a781e3dbddb878076f6ce0dce4a2f682b79b4482998718b025a6c
|
data/agile-proxy.gemspec
CHANGED
@@ -51,6 +51,7 @@ Gem::Specification.new do |gem|
|
|
51
51
|
gem.add_runtime_dependency 'flavour_saver', '~> 0.3', '>= 0.3.4'
|
52
52
|
gem.add_runtime_dependency 'thor', '~> 0.19', '>= 0.19.1'
|
53
53
|
gem.add_runtime_dependency 'goliath', '~> 1.0', '>= 1.0.4'
|
54
|
+
gem.add_runtime_dependency 'rack-cache', '~> 1.2', '>= 1.2'
|
54
55
|
gem.add_runtime_dependency 'goliath-proxy', '~> 0.0', '>= 0.0.1'
|
55
56
|
|
56
57
|
end
|
@@ -33,7 +33,7 @@ module AgileProxy
|
|
33
33
|
req = req.send(method.downcase, build_request_options(request.headers, body))
|
34
34
|
|
35
35
|
if req.error
|
36
|
-
return [500, {}, "Request to #{request.url} failed with error: #{req.error}"]
|
36
|
+
return [500, {}, ["Request to #{request.url} failed with error: #{req.error}"]]
|
37
37
|
end
|
38
38
|
|
39
39
|
if req.response
|
@@ -47,7 +47,7 @@ module AgileProxy
|
|
47
47
|
return [response[:status], response[:headers], response[:content]]
|
48
48
|
end
|
49
49
|
end
|
50
|
-
[404, {}, 'Not proxied']
|
50
|
+
[404, {}, ['Not proxied']]
|
51
51
|
end
|
52
52
|
|
53
53
|
private
|
@@ -74,9 +74,10 @@ module AgileProxy
|
|
74
74
|
response = {
|
75
75
|
status: req.response_header.status,
|
76
76
|
headers: req.response_header.raw,
|
77
|
-
content: req.response.force_encoding('BINARY') }
|
77
|
+
content: [req.response.force_encoding('BINARY')] }
|
78
78
|
response[:headers].merge!('Connection' => 'close')
|
79
79
|
response[:headers].delete('Transfer-Encoding')
|
80
|
+
response[:headers].merge!('Cache-Control' => 'max-age=3600')
|
80
81
|
response
|
81
82
|
end
|
82
83
|
|
@@ -2,6 +2,7 @@ require 'agile_proxy/model/application'
|
|
2
2
|
require 'agile_proxy/model/recording'
|
3
3
|
require 'rack'
|
4
4
|
require 'forwardable'
|
5
|
+
require 'agile_proxy/rack/get_only_cache'
|
5
6
|
module AgileProxy
|
6
7
|
#
|
7
8
|
# =The Central Request Handler
|
@@ -53,9 +54,18 @@ module AgileProxy
|
|
53
54
|
private
|
54
55
|
|
55
56
|
def rack_app
|
56
|
-
|
57
|
-
|
57
|
+
stub_handler = stub_handler_app
|
58
|
+
proxy_handler = proxy_handler_app
|
59
|
+
@__app ||= ::Rack::Builder.new do
|
60
|
+
use Rack::GetOnlyCache
|
61
|
+
run ::Rack::Cascade.new([stub_handler, proxy_handler])
|
58
62
|
end
|
59
63
|
end
|
64
|
+
def stub_handler_app
|
65
|
+
@_stub_handler_app ||= StubHandler.new
|
66
|
+
end
|
67
|
+
def proxy_handler_app
|
68
|
+
@_proxy_handler_app ||= ProxyHandler.new
|
69
|
+
end
|
60
70
|
end
|
61
71
|
end
|
@@ -97,10 +97,10 @@ module AgileProxy
|
|
97
97
|
def rack_app
|
98
98
|
route_set = @route_set
|
99
99
|
text_handler = plain_text_handler
|
100
|
-
Rack::Builder.new do
|
100
|
+
::Rack::Builder.new do
|
101
101
|
use ActionDispatch::ParamsParser, Mime::TEXT => text_handler
|
102
102
|
use MergePostAndGetParams
|
103
|
-
use Rack::ContentLength
|
103
|
+
use ::Rack::ContentLength
|
104
104
|
run route_set
|
105
105
|
end
|
106
106
|
end
|
@@ -42,7 +42,7 @@ module AgileProxy
|
|
42
42
|
# @param body [String] The request body
|
43
43
|
# @return [Array] The rack response
|
44
44
|
def call(params, headers, body)
|
45
|
-
response.nil? ? [204, { 'Content-Type' => 'text/plain'
|
45
|
+
response.nil? ? [204, { 'Content-Type' => 'text/plain'}, ''] : response.to_rack(params, headers, body)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -36,6 +36,7 @@ module AgileProxy
|
|
36
36
|
# @return [Array] A 'rack' response array (status, headers, body)
|
37
37
|
def to_rack(input_params, _input_headers, _input_body)
|
38
38
|
output_headers = headers.clone
|
39
|
+
output_headers.merge! 'Cache-Control' => 'no-store'
|
39
40
|
output_content = content
|
40
41
|
output_status_code = status_code
|
41
42
|
if is_template
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rack-cache'
|
2
|
+
require 'action_dispatch/http/request'
|
3
|
+
module AgileProxy
|
4
|
+
module Rack
|
5
|
+
class GetOnlyCache
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
def call(env)
|
10
|
+
force_caching(env)
|
11
|
+
request = ::ActionDispatch::Request.new(env)
|
12
|
+
if request.request_method_symbol == :get
|
13
|
+
cache_app.call(env)
|
14
|
+
else
|
15
|
+
@app.call(env)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def force_caching(env)
|
21
|
+
env.delete 'HTTP_PRAGMA' if env['HTTP_PRAGMA'] == 'no-cache'
|
22
|
+
env.delete 'HTTP_CACHE_CONTROL' if env['HTTP_CACHE_CONTROL'] == 'no-cache'
|
23
|
+
end
|
24
|
+
def cache_app
|
25
|
+
@cache_app ||= ::Rack::Cache.new(@app)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -26,7 +26,7 @@ module AgileProxy
|
|
26
26
|
runner.address = webserver_host
|
27
27
|
runner.port = webserver_port
|
28
28
|
runner.app = ::Goliath::Rack::Builder.app do
|
29
|
-
use Rack::Static, root: File.join(ROOT, 'assets'), urls: ['/ui'], index: 'index.html'
|
29
|
+
use ::Rack::Static, root: File.join(ROOT, 'assets'), urls: ['/ui'], index: 'index.html'
|
30
30
|
map '/api' do
|
31
31
|
run ::AgileProxy::Api::Root.new
|
32
32
|
end
|
@@ -22,7 +22,7 @@ module AgileProxy
|
|
22
22
|
runner.address = server_host
|
23
23
|
runner.port = server_port
|
24
24
|
runner.app = ::Goliath::Rack::Builder.app do
|
25
|
-
use Rack::Static, root: File.join(ROOT, 'assets'), urls: static_dirs, index: 'index.html' unless static_dirs.empty?
|
25
|
+
use ::Rack::Static, root: File.join(ROOT, 'assets'), urls: static_dirs, index: 'index.html' unless static_dirs.empty?
|
26
26
|
map '/' do
|
27
27
|
run ::AgileProxy::StubHandler.new
|
28
28
|
end
|
data/lib/agile_proxy/version.rb
CHANGED
data/spec/common_helper.rb
CHANGED
@@ -7,8 +7,8 @@ module AgileProxy
|
|
7
7
|
fake_error_buffer = StringIO.new
|
8
8
|
url_parsed = URI.parse(opts[:url])
|
9
9
|
env = {
|
10
|
-
'rack.input' => Rack::Lint::InputWrapper.new(fake_input_buffer),
|
11
|
-
'rack.errors' => Rack::Lint::ErrorWrapper.new(fake_error_buffer),
|
10
|
+
'rack.input' => ::Rack::Lint::InputWrapper.new(fake_input_buffer),
|
11
|
+
'rack.errors' => ::Rack::Lint::ErrorWrapper.new(fake_error_buffer),
|
12
12
|
'REQUEST_METHOD' => (opts[:method] || 'GET').upcase,
|
13
13
|
'REQUEST_PATH' => url_parsed.path,
|
14
14
|
'PATH_INFO' => url_parsed.path,
|
@@ -86,7 +86,7 @@ describe AgileProxy::ProxyHandler do
|
|
86
86
|
describe '#call' do
|
87
87
|
it 'returns nil if it does not handle the request' do
|
88
88
|
expect(subject).to receive(:handles_request?).and_return(false)
|
89
|
-
expect(subject.call(request.env)).to eql [404, {}, 'Not proxied']
|
89
|
+
expect(subject.call(request.env)).to eql [404, {}, ['Not proxied']]
|
90
90
|
end
|
91
91
|
|
92
92
|
context 'with a handled request' do
|
@@ -111,20 +111,20 @@ describe AgileProxy::ProxyHandler do
|
|
111
111
|
|
112
112
|
it 'Should pass through a not allowed response' do
|
113
113
|
allow(response_header).to receive(:status).and_return(503)
|
114
|
-
expect(subject.call(request.env)).to eql [503, { 'Connection' => 'close' }, 'The response body']
|
114
|
+
expect(subject.call(request.env)).to eql [503, { 'Connection' => 'close', 'Cache-Control' => 'max-age=3600' }, ['The response body']]
|
115
115
|
end
|
116
116
|
it 'returns any error in the response' do
|
117
117
|
allow(em_request).to receive(:error).and_return('ERROR!')
|
118
|
-
expect(subject.call(request.env)).to eql([500, {}, "Request to #{request.url} failed with error: ERROR!"])
|
118
|
+
expect(subject.call(request.env)).to eql([500, {}, ["Request to #{request.url} failed with error: ERROR!"]])
|
119
119
|
end
|
120
120
|
|
121
121
|
it 'returns a hashed response if the request succeeds' do
|
122
|
-
expect(subject.call(request.env)).to eql([200, { 'Connection' => 'close' }, 'The response body'])
|
122
|
+
expect(subject.call(request.env)).to eql([200, { 'Connection' => 'close', 'Cache-Control' => 'max-age=3600' }, ['The response body']])
|
123
123
|
end
|
124
124
|
|
125
125
|
it 'returns nil if both the error and response are for some reason nil' do
|
126
126
|
allow(em_request).to receive(:response).and_return(nil)
|
127
|
-
expect(subject.call(request.env)).to eql [404, {}, 'Not proxied']
|
127
|
+
expect(subject.call(request.env)).to eql [404, {}, ['Not proxied']]
|
128
128
|
end
|
129
129
|
|
130
130
|
it 'uses the timeouts defined in configuration' do
|
@@ -13,6 +13,8 @@ describe AgileProxy::RequestHandler do
|
|
13
13
|
let(:proxy_handler) { Class.new }
|
14
14
|
let(:application_class) { Class.new }
|
15
15
|
let(:recordings_class) { Class.new }
|
16
|
+
let(:rack_builder_class) {Class.new}
|
17
|
+
let(:get_only_cache_class) {Class.new}
|
16
18
|
let(:application) { double('Application', record_requests: false, recordings: recordings_class) }
|
17
19
|
let(:mock_request_spec) {double('RequestSpec', id: 8, record_requests: false)}
|
18
20
|
|
@@ -20,7 +22,18 @@ describe AgileProxy::RequestHandler do
|
|
20
22
|
stub_const 'AgileProxy::StubHandler', stub_handler
|
21
23
|
stub_const 'AgileProxy::ProxyHandler', proxy_handler
|
22
24
|
stub_const 'AgileProxy::Application', application_class
|
25
|
+
stub_const '::Rack::Builder', rack_builder_class
|
26
|
+
stub_const 'AgileProxy::Rack::GetOnlyCache', get_only_cache_class
|
23
27
|
allow(application_class).to receive(:where).and_return [application]
|
28
|
+
#Make the rack builder just pass through whatever is passed to 'run' - to avoid the caching middleware etc..
|
29
|
+
rack_builder_instance = rack_builder_class.new
|
30
|
+
allow(rack_builder_class).to receive(:new) do |&blk|
|
31
|
+
rack_builder_instance.instance_eval(&blk)
|
32
|
+
end
|
33
|
+
allow(rack_builder_instance).to receive(:use).with(get_only_cache_class)
|
34
|
+
allow(rack_builder_instance).to receive(:run) do |app|
|
35
|
+
app
|
36
|
+
end
|
24
37
|
end
|
25
38
|
|
26
39
|
describe '#call' do
|
@@ -15,7 +15,7 @@ describe AgileProxy::Response do
|
|
15
15
|
end
|
16
16
|
it 'Should respond with a delay using the Em::Synchrony.sleep method' do
|
17
17
|
expect(EventMachine::Synchrony).to receive(:sleep).with(0.5)
|
18
|
-
expect(subject.to_rack({}, {}, '')).to eql([200, { 'Content-Type' => 'text/plain' }, ['Test']])
|
18
|
+
expect(subject.to_rack({}, {}, '')).to eql([200, { 'Content-Type' => 'text/plain', 'Cache-Control' => 'no-store' }, ['Test']])
|
19
19
|
end
|
20
20
|
|
21
21
|
end
|
@@ -27,10 +27,10 @@ describe AgileProxy::Response do
|
|
27
27
|
subject.content_type = 'text/plain'
|
28
28
|
end
|
29
29
|
it 'Should pass the params to the template and the output should be correct' do
|
30
|
-
expect(subject.to_rack({ name: 'World' }, {}, '')).to eql([200, { 'Content-Type' => 'text/plain' }, ['Hello World']])
|
30
|
+
expect(subject.to_rack({ name: 'World' }, {}, '')).to eql([200, { 'Content-Type' => 'text/plain', 'Cache-Control' => 'no-store' }, ['Hello World']])
|
31
31
|
end
|
32
32
|
it 'Should deal with if a parameter is missing' do
|
33
|
-
expect(subject.to_rack({}, {}, '')).to eql([200, { 'Content-Type' => 'text/plain' }, ["Hello "]])
|
33
|
+
expect(subject.to_rack({}, {}, '')).to eql([200, { 'Content-Type' => 'text/plain', 'Cache-Control' => 'no-store' }, ["Hello "]])
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: agile-proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.24
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gary Taylor
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -518,6 +518,26 @@ dependencies:
|
|
518
518
|
- - ">="
|
519
519
|
- !ruby/object:Gem::Version
|
520
520
|
version: 1.0.4
|
521
|
+
- !ruby/object:Gem::Dependency
|
522
|
+
name: rack-cache
|
523
|
+
requirement: !ruby/object:Gem::Requirement
|
524
|
+
requirements:
|
525
|
+
- - "~>"
|
526
|
+
- !ruby/object:Gem::Version
|
527
|
+
version: '1.2'
|
528
|
+
- - ">="
|
529
|
+
- !ruby/object:Gem::Version
|
530
|
+
version: '1.2'
|
531
|
+
type: :runtime
|
532
|
+
prerelease: false
|
533
|
+
version_requirements: !ruby/object:Gem::Requirement
|
534
|
+
requirements:
|
535
|
+
- - "~>"
|
536
|
+
- !ruby/object:Gem::Version
|
537
|
+
version: '1.2'
|
538
|
+
- - ">="
|
539
|
+
- !ruby/object:Gem::Version
|
540
|
+
version: '1.2'
|
521
541
|
- !ruby/object:Gem::Dependency
|
522
542
|
name: goliath-proxy
|
523
543
|
requirement: !ruby/object:Gem::Requirement
|
@@ -2228,6 +2248,7 @@ files:
|
|
2228
2248
|
- lib/agile_proxy/model/response.rb
|
2229
2249
|
- lib/agile_proxy/model/user.rb
|
2230
2250
|
- lib/agile_proxy/proxy_connection.rb
|
2251
|
+
- lib/agile_proxy/rack/get_only_cache.rb
|
2231
2252
|
- lib/agile_proxy/route.rb
|
2232
2253
|
- lib/agile_proxy/router.rb
|
2233
2254
|
- lib/agile_proxy/server.rb
|
@@ -2280,7 +2301,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
2280
2301
|
version: '0'
|
2281
2302
|
requirements: []
|
2282
2303
|
rubyforge_project:
|
2283
|
-
rubygems_version: 2.
|
2304
|
+
rubygems_version: 2.2.2
|
2284
2305
|
signing_key:
|
2285
2306
|
specification_version: 4
|
2286
2307
|
summary: An agile, programmable, controllable flexible proxy server for development
|