agile-proxy 0.1.22 → 0.1.23

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cdc83345bdd428e0b53171381e809cd739281a32
4
- data.tar.gz: 52dc13eeb368e9d19cb2f3cc1f2248d6320a573c
3
+ metadata.gz: 3bbb90ecd388cd7e950d4a7fe7bf6b2c22a81218
4
+ data.tar.gz: 0d9631df2bce4c44899f1a87e1479eee8ccf5e4a
5
5
  SHA512:
6
- metadata.gz: e10828a0c1eaf12ee379f4b4de473c5a64afd514722897561b21e2a4327a27f7d93836043ee26103eb282840bd9c1a92ff1a0532566c5c9423abe9956f4f29ca
7
- data.tar.gz: f287eb594c2ba7d69e3b19d640bbde4a1beec400cecb40d5c4ee17b5d12532019e7cf32ba767cba245338aa5c41a1d9ad5bd10ec3ca3a2d8734fa07000e74eaa
6
+ metadata.gz: 91e4deda16860bbe0efa661180a0c4dd0926a59b34ef30686fe91bd72f9b87d1fd9ee3d88f693b93651c8252fd713edfc2b01555f93e49bfac0ffc59b7c25128
7
+ data.tar.gz: 87955fdff1298490172056333ddc0dfe8a9f17f50dc77c9db3af60e160e7bae7420bc0d2dcba3226a1cc0d67799d978f1e6071a932b09bf86caa721f2a9ab7b8
data/.gitignore CHANGED
@@ -6,4 +6,5 @@ assets/ui/bower_components
6
6
  .yardoc
7
7
  db/*.db
8
8
  coverage/
9
- Gemfile.lock
9
+ Gemfile.lock
10
+ vendor/gems
data/README.md CHANGED
@@ -124,4 +124,5 @@ v0.1.19 - Recordings now record the request spec id.
124
124
  v0.1.20 - An individual request spec can now be set to 'record_requests' rather than requiring the whole application to be in record mode which slows down every request
125
125
  v0.1.21 - Switched to goliath instead of thin. The gem now installs under jruby as well as other platforms.
126
126
  v0.1.22 - Reverted 0.1.21 - Integration tests worked fine, but failed in real world scenario - never ending responses from stubs
127
+ v0.1.23 - Switched to goliath instead of thin. The gem now installs under jruby as well as other platforms.
127
128
 
@@ -21,11 +21,9 @@ Gem::Specification.new do |gem|
21
21
  gem.add_development_dependency 'faraday', '~> 0.9', '>= 0.9.0'
22
22
  gem.add_development_dependency 'poltergeist', '~> 1.5', '>= 1.5.1'
23
23
  gem.add_development_dependency 'selenium-webdriver', '~> 2.43', '>= 2.43.0'
24
- gem.add_development_dependency 'rack', '~> 1.6', '>= 1.6.0'
25
24
  gem.add_development_dependency 'guard', '~> 2.6', '>= 2.6.1'
26
25
  gem.add_development_dependency 'rb-inotify', '~> 0.9', '>= 0.9.5'
27
26
  gem.add_development_dependency 'cucumber', '~> 1.3', '>= 1.3.17'
28
- gem.add_development_dependency 'airborne', '~> 0.1', '>= 0.1.10'
29
27
  gem.add_development_dependency 'rest-client', '~> 1.7', '>= 1.7.2'
30
28
  gem.add_development_dependency 'require_all', '~> 1.3', '>= 1.3.2'
31
29
  gem.add_development_dependency 'faker', '~> 1.2', '>= 1.2.0'
@@ -35,16 +33,24 @@ Gem::Specification.new do |gem|
35
33
  gem.add_runtime_dependency 'eventmachine', '~> 1.0', '>= 1.0.3'
36
34
  gem.add_runtime_dependency 'em-synchrony', '~> 1.0', '>= 1.0.3'
37
35
  gem.add_runtime_dependency 'em-http-request', '~> 1.1', '>= 1.1.2'
38
- gem.add_runtime_dependency 'eventmachine_httpserver', '~> 0.2', '>= 0.2.1'
39
- gem.add_runtime_dependency 'http_parser.rb', '~> 0.6', '>= 0.6.0'
40
- gem.add_runtime_dependency 'multi_json', '~> 1.10', '>= 1.10.1'
41
- gem.add_runtime_dependency 'thin', '~> 1.6', '>= 1.6.2'
42
36
  gem.add_runtime_dependency 'grape', '~> 0.10', '>= 0.10.1'
43
37
  gem.add_runtime_dependency 'activerecord', '~> 4.2', '>= 4.2.0'
44
- gem.add_runtime_dependency 'sqlite3', '~> 1.3', '>= 1.3.10'
38
+ if RUBY_PLATFORM =~ /java/
39
+ #JVM Only
40
+ gem.add_runtime_dependency 'activerecord-jdbc-adapter'
41
+ gem.add_runtime_dependency 'activerecord-jdbcsqlite3-adapter'
42
+ else
43
+ #Non JVM
44
+ gem.add_runtime_dependency 'sqlite3', '~> 1.3', '>= 1.3.10'
45
+ end
46
+
47
+
48
+
45
49
  gem.add_runtime_dependency 'grape-kaminari', '~> 0.1', '>= 0.1.7'
46
50
  gem.add_runtime_dependency 'shoulda-matchers', '2.8.0.rc2'
47
51
  gem.add_runtime_dependency 'flavour_saver', '~> 0.3', '>= 0.3.4'
48
52
  gem.add_runtime_dependency 'thor', '~> 0.19', '>= 0.19.1'
49
- gem.add_runtime_dependency 'rack-parser', '~> 0.6', '>= 0.6.1'
53
+ gem.add_runtime_dependency 'goliath', '~> 1.0', '>= 1.0.4'
54
+ gem.add_runtime_dependency 'goliath-proxy', '~> 0.0', '>= 0.0.1'
55
+
50
56
  end
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'goliath'
4
+ require 'active_support/core_ext/class/attribute_accessors'
5
+ class Echo < Goliath::API
6
+ cattr_accessor :counter
7
+ def response_code
8
+ ENV['STATUS_CODE'] || 200
9
+ end
10
+ def response(env)
11
+ self.counter = counter || 0
12
+ req_body = env['rack.input'].read
13
+ request_info = "#{env['REQUEST_METHOD']} #{env['PATH_INFO']}"
14
+ res_body = request_info
15
+ res_body += "\n#{req_body}" unless req_body.empty?
16
+ self.counter += 1
17
+ [response_code, { 'HTTP-X-EchoServer' => request_info, 'HTTP-X-EchoCount' => "#{counter}" }, res_body]
18
+ end
19
+ end
@@ -36,8 +36,9 @@ module AgileProxy
36
36
  ]
37
37
  end
38
38
  request_spec = env['agile_proxy.request_spec']
39
+ exclude_headers = ['@env', 'rack.errors', 'rack.logger']
39
40
  if application.record_requests || (request_spec && request_spec.record_requests)
40
- application.recordings.create request_headers: request.headers,
41
+ application.recordings.create request_headers: request.headers.reject {|key, value| exclude_headers.include?(key)},
41
42
  request_body: body,
42
43
  request_url: request.url,
43
44
  request_method: request.request_method,
@@ -2,7 +2,6 @@ require 'agile_proxy/handlers/handler'
2
2
  require 'agile_proxy/model/request_spec'
3
3
  require 'agile_proxy/router'
4
4
  require 'agile_proxy/model/application'
5
- require 'rack/parser'
6
5
  require 'action_dispatch'
7
6
  require 'base64'
8
7
  module AgileProxy
@@ -101,6 +100,7 @@ module AgileProxy
101
100
  Rack::Builder.new do
102
101
  use ActionDispatch::ParamsParser, Mime::TEXT => text_handler
103
102
  use MergePostAndGetParams
103
+ use Rack::ContentLength
104
104
  run route_set
105
105
  end
106
106
  end
@@ -1,4 +1,5 @@
1
1
  require_relative 'application'
2
+ require 'active_record'
2
3
  module AgileProxy
3
4
  #
4
5
  # = The recording model
@@ -44,7 +44,7 @@ module AgileProxy
44
44
  output_content = template.render data
45
45
  end
46
46
  EventMachine::Synchrony.sleep(delay) if delay > 0
47
- [output_status_code, output_headers, output_content]
47
+ [output_status_code, output_headers, [output_content]]
48
48
  end
49
49
  end
50
50
  end
@@ -1,24 +1,27 @@
1
1
  require 'uri'
2
2
  require 'eventmachine'
3
- require 'http/parser'
4
- require 'em-http'
5
- require 'evma_httpserver'
6
- require 'em-synchrony'
7
3
  require 'stringio'
8
4
  require 'rack'
5
+ require 'goliath/request'
6
+ require 'goliath/env'
9
7
 
10
8
  module AgileProxy
11
9
  #
12
10
  # = The Proxy Connection
13
11
  #
14
12
  # This class is the event machine connection used by the proxy. Every request creates a new instance of this
15
- class ProxyConnection < EventMachine::Connection
16
- attr_accessor :handler
13
+ class ProxyConnection < Goliath::Connection
14
+ def logger
15
+ ::AgileProxy.config.logger
16
+ end
17
17
  def post_init
18
- @parser = Http::Parser.new(self)
18
+ super
19
+ #@proxy_parser = Http::Parser.new(self)
20
+ @proxy_parser = Http::Parser.new
19
21
  end
20
22
 
21
23
  def receive_data(data)
24
+ #@proxy_parser << data
22
25
  @parser << data
23
26
  end
24
27
 
@@ -36,24 +39,25 @@ module AgileProxy
36
39
  end
37
40
 
38
41
  def on_message_complete
39
- if @parser.http_method == 'CONNECT'
40
- restart_with_ssl(@parser.request_url)
42
+ if @proxy_parser.http_method == 'CONNECT'
43
+ restart_with_ssl(@proxy_parser.request_url)
41
44
  else
42
45
  if @ssl
43
- uri = URI.parse(@parser.request_url)
46
+ uri = URI.parse(@proxy_parser.request_url)
44
47
  @url = "https://#{@ssl}#{[uri.path, uri.query].compact.join('?')}"
45
48
  else
46
- @url = @parser.request_url
49
+ @url = @proxy_parser.request_url
47
50
  end
48
51
  handle_request
49
52
  end
50
53
  end
51
54
 
55
+
52
56
  protected
53
57
 
54
58
  def restart_with_ssl(url)
55
59
  @ssl = url
56
- @parser = Http::Parser.new(self)
60
+ @proxy_parser = Http::Parser.new(self)
57
61
  @original_headers = @headers.clone
58
62
  send_data("HTTP/1.0 200 Connection established\r\nProxy-agent: Http-Flexible-Proxy/0.0.0\r\n\r\n")
59
63
  start_tls(
@@ -64,11 +68,9 @@ module AgileProxy
64
68
 
65
69
  def handle_request
66
70
  EM.synchrony do
67
- request = ActionDispatch::Request.new(env)
68
- request.params # This will populate action_dispatch.request.parameters
69
- handler.call(env).tap do |response|
70
- send_response(response)
71
- end
71
+ request = ::Goliath::Request.new(handler, self, env)
72
+ request.set_deferred_status :succeeded
73
+ request.process
72
74
  end
73
75
  end
74
76
 
@@ -79,10 +81,11 @@ module AgileProxy
79
81
  fake_input_buffer = StringIO.new(@body)
80
82
  fake_error_buffer = StringIO.new
81
83
  url_parsed = URI.parse(@url)
82
- @__env = {
84
+ @__env = ::Goliath::Env.new
85
+ @__env.merge!({
83
86
  'rack.input' => Rack::Lint::InputWrapper.new(fake_input_buffer),
84
87
  'rack.errors' => Rack::Lint::ErrorWrapper.new(fake_error_buffer),
85
- 'REQUEST_METHOD' => @parser.http_method,
88
+ 'REQUEST_METHOD' => @proxy_parser.http_method,
86
89
  'REQUEST_PATH' => url_parsed.path,
87
90
  'PATH_INFO' => url_parsed.path,
88
91
  'QUERY_STRING' => url_parsed.query || '',
@@ -90,9 +93,11 @@ module AgileProxy
90
93
  'rack.url_scheme' => url_parsed.scheme,
91
94
  'CONTENT_LENGTH' => @body.length,
92
95
  'SERVER_NAME' => url_parsed.host,
93
- 'SERVER_PORT' => url_parsed.port
96
+ 'SERVER_PORT' => url_parsed.port,
97
+ 'rack.logger' => logger
94
98
 
95
- }
99
+
100
+ })
96
101
  @headers.merge(@original_headers || {}).each do |name, value|
97
102
  converted_name = "HTTP_#{name.gsub(/-/, '_').upcase}"
98
103
  @__env[converted_name] = value
@@ -102,12 +107,6 @@ module AgileProxy
102
107
  @__env
103
108
  end
104
109
 
105
- def send_response(response)
106
- res = EM::DelegatedHttpResponse.new(self)
107
- res.status = response[0]
108
- res.headers = response[1]
109
- res.content = response[2]
110
- res.send_response
111
- end
110
+
112
111
  end
113
112
  end
@@ -3,13 +3,27 @@ require 'yaml'
3
3
  require 'cgi'
4
4
  require 'uri'
5
5
  require 'eventmachine'
6
- require 'thin'
7
6
  require 'grape'
8
7
  require 'agile_proxy/api/root'
9
8
  require 'agile_proxy/servers/api'
10
9
  require 'agile_proxy/servers/request_spec'
11
10
  require 'agile_proxy/servers/request_spec_direct'
12
11
  require 'forwardable'
12
+
13
+ require 'goliath/api'
14
+ require 'goliath/runner'
15
+
16
+ # Example demonstrating how to use a custom Goliath runner
17
+ #
18
+
19
+ class Custom < Goliath::API
20
+ def response(env)
21
+ [200, {}, "hello!"]
22
+ end
23
+ end
24
+
25
+
26
+
13
27
  module AgileProxy
14
28
  #
15
29
  # This class is responsible for controlling the underlying proxy and web servers
@@ -1,6 +1,7 @@
1
1
  require 'rack'
2
- require 'thin'
3
2
  require 'grape'
3
+ require 'goliath/api'
4
+ require 'goliath/runner'
4
5
  require 'agile_proxy/api/root'
5
6
 
6
7
  module AgileProxy
@@ -19,21 +20,19 @@ module AgileProxy
19
20
  # @param webserver_host [String] The host for the server to run on
20
21
  # @param webserver_port [Integer] The port for the server to run on
21
22
  def start(webserver_host, webserver_port)
22
- # The sinatra web server
23
- dispatch = Rack::Builder.app do
23
+ #
24
+ # The API runner
25
+ runner = ::Goliath::Runner.new([], nil)
26
+ runner.address = webserver_host
27
+ runner.port = webserver_port
28
+ runner.app = ::Goliath::Rack::Builder.app do
24
29
  use Rack::Static, root: File.join(ROOT, 'assets'), urls: ['/ui'], index: 'index.html'
25
30
  map '/api' do
26
31
  run ::AgileProxy::Api::Root.new
27
32
  end
28
33
  end
29
- # Start the web server.
30
- ::Rack::Server.start(
31
- app: dispatch,
32
- server: 'thin',
33
- Host: webserver_host,
34
- Port: webserver_port,
35
- signals: false
36
- )
34
+ runner.run
35
+
37
36
  end
38
37
  end
39
38
  end
@@ -1,4 +1,6 @@
1
1
  require 'eventmachine'
2
+ require 'goliath/api'
3
+ require 'goliath/proxy'
2
4
  module AgileProxy
3
5
  module Servers
4
6
  #
@@ -6,6 +8,7 @@ module AgileProxy
6
8
  # This server is responsible for handling or passing through a request, depending
7
9
  # on if it has a matching 'Request Specification'
8
10
  class RequestSpec
11
+
9
12
  # Starts the server
10
13
  def self.start
11
14
  new.start
@@ -15,16 +18,23 @@ module AgileProxy
15
18
  end
16
19
  # Starts the server
17
20
  def start
18
- @signature = EM.start_server('127.0.0.1', AgileProxy.config.proxy_port, ProxyConnection) do |p|
19
- p.handler = @request_handler
20
- end
21
+ #
22
+ # The API runner
23
+ runner = ::Goliath::Proxy::Runner.new([], nil)
24
+ runner.address = '127.0.0.1'
25
+ runner.port = AgileProxy.config.proxy_port
26
+ app = @request_handler
27
+ runner.app = app
28
+ runner.run
21
29
  self
30
+
22
31
  end
23
32
  # The port the server is running on
24
33
  # @return [Integer] The port the server is running on
25
34
  def port
26
- Socket.unpack_sockaddr_in(EM.get_sockname(@signature)).first
35
+ return AgileProxy.config.proxy_port
27
36
  end
37
+ private
28
38
  end
29
39
  end
30
40
  end
@@ -1,6 +1,6 @@
1
1
  require 'rack'
2
- require 'thin'
3
-
2
+ require 'goliath/api'
3
+ require 'goliath/runner'
4
4
  module AgileProxy
5
5
  module Servers
6
6
  #
@@ -17,21 +17,17 @@ module AgileProxy
17
17
  # @param server_host [String] The host for the server to run on
18
18
  # @param server_port [Integer] The port for the server to run on
19
19
  def start(server_host, server_port, static_dirs = [])
20
- # The sinatra web server
21
- dispatch = Rack::Builder.app do
20
+
21
+ runner = ::Goliath::Runner.new([], nil)
22
+ runner.address = server_host
23
+ runner.port = server_port
24
+ runner.app = ::Goliath::Rack::Builder.app do
22
25
  use Rack::Static, root: File.join(ROOT, 'assets'), urls: static_dirs, index: 'index.html' unless static_dirs.empty?
23
26
  map '/' do
24
27
  run ::AgileProxy::StubHandler.new
25
28
  end
26
29
  end
27
- # Start the web server.
28
- ::Rack::Server.start(
29
- app: dispatch,
30
- server: 'thin',
31
- Host: server_host,
32
- Port: server_port,
33
- signals: false
34
- )
30
+ runner.run
35
31
  end
36
32
  end
37
33
  end
@@ -2,5 +2,5 @@
2
2
  #
3
3
  # The Agile Proxy module is a common namespace for all classes / sub modules.
4
4
  module AgileProxy
5
- VERSION = '0.1.22'
5
+ VERSION = '0.1.23'
6
6
  end
@@ -56,13 +56,17 @@ shared_examples_for 'a request stub' do |options = {}|
56
56
  stub = find_stub(http, name)
57
57
  {recordings: a_collection_containing_exactly(a_hash_including request_body: '', request_url: "#{http.url_prefix}#{path.gsub(/^\//, '')}", request_method: 'GET', request_spec_id: stub.body[:id])}
58
58
  end
59
+
59
60
  it 'should stub GET requests' do
60
- expect(http.get('/index.html').body).to eql '<html><body>Mocked Content</body></html>'
61
+ response = http.get('/index.html')
62
+ expect(response.body).to eql '<html><body>Mocked Content</body></html>'
63
+ expect(response.headers).to include('content-length' => "40")
61
64
  expect(recordings_for 'index').to include(recordings_matcher_for('index', '/index.html')) if recording
62
65
  end
63
66
 
64
67
  it 'should stub GET response statuses' do
65
- expect(http.get('/index.html').status).to eql 200
68
+ response = http.get('/index.html')
69
+ expect(response.status).to eql 200
66
70
  end
67
71
 
68
72
  #TODO When time allows, work out how to easily test this as the stubs are not recorded for anything but recorded tests
@@ -77,7 +81,7 @@ shared_examples_for 'a request stub' do |options = {}|
77
81
  resp = http.get('/api/forums')
78
82
  expect(ActiveSupport::JSON.decode(resp.body).symbolize_keys).to eql forums: [], total: 0
79
83
  expect(resp.status).to eql 200
80
- expect(resp.headers['Content-Type']).to eql 'application/json'
84
+ expect(resp.headers).to include('content-type' => 'application/json', 'content-length' => resp.body.length.to_s)
81
85
  expect(recordings_for 'api_forums').to include(recordings_matcher_for('api_forums', '/api/forums')) if recording
82
86
  end
83
87
 
@@ -85,43 +89,44 @@ shared_examples_for 'a request stub' do |options = {}|
85
89
  resp = http.get '/api/forums/my_forum/posts'
86
90
  expect(ActiveSupport::JSON.decode(resp.body)).to eql 'posts' => [{ 'forum_id' => 'my_forum', 'subject' => 'My first post' }, { 'forum_id' => 'my_forum', 'subject' => 'My second post' }, { 'forum_id' => 'my_forum', 'subject' => 'My third post' }], 'total' => 3
87
91
  expect(resp.status).to eql 200
88
- expect(resp.headers['Content-Type']).to eql 'application/json'
92
+ expect(resp.headers).to include('content-type' => 'application/json', 'content-length' => resp.body.length.to_s)
89
93
  end
90
94
 
91
95
  it 'Should get the mocked content for api/forums/:forum_id/:post_id with parameter substitution including query parameters' do
92
96
  resp = http.get '/api/forums/my_forum/my_post?sort=id'
93
97
  expect(resp.body).to eql '<html><body><h1>Sorted By: id</h1><h2>my_forum</h2><h3>my_post</h3></body></html>'
94
98
  expect(resp.status).to eql 200
95
- expect(resp.headers['Content-Type']).to eql 'text/html'
99
+ expect(resp.headers).to include('content-type' => 'text/html', 'content-length' => resp.body.length.to_s)
96
100
  end
97
101
  it 'Should get the mocked content for api/forums/:forum_id/:post_id.html with parameter substitution including query parameters' do
98
102
  resp = http.get '/api/forums/my_forum/my_post.html?sort=id'
99
103
  expect(resp.body).to eql '<html><body><h1>Sorted By: id</h1><h2>my_forum</h2><h3>my_post</h3></body></html>'
100
104
  expect(resp.status).to eql 200
101
- expect(resp.headers['Content-Type']).to eql 'text/html'
105
+ expect(resp.headers).to include('content-type' => 'text/html', 'content-length' => resp.body.length.to_s)
102
106
  end
103
107
  it 'Should respond with an error for api/forums/:forum_id/:post_id.html with parameter substitution with a missing query parameter' do
104
108
  resp = http.get '/api/forums/my_forum/my_post.html'
105
109
  expect(resp.body).to eql '<html><body><h1>Sorted By: </h1><h2>my_forum</h2><h3>my_post</h3></body></html>'
110
+ expect(resp.headers).to include('content-type' => 'text/html', 'content-length' => resp.body.length.to_s)
106
111
  expect(resp.status).to eql 200
107
112
  end
108
113
  it 'Should match the route by posted json data and the posted data can be output via the template' do
109
114
  resp = http.post '/api/forums/my_forum', '{"posted_var": "special_value"}', 'Content-Type' => 'application/json'
110
115
  expect(resp.body).to eql '<html><body><h1></h1><h2>special_value</h2><h3>my_forum</h3><p>This should get data from the POSTed data</p></body></html>'
111
116
  expect(resp.status).to eql 200
112
- expect(resp.headers['Content-Type']).to eql 'text/html'
117
+ expect(resp.headers).to include('content-type' => 'text/html', 'content-length' => resp.body.length.to_s)
113
118
  end
114
119
  it 'Should match the route by posted plain text data and the posted data can be output via the template' do
115
120
  resp = http.post '/api/forums/my_forum', "posted_var=special_value\n", 'Content-Type' => 'text/plain'
116
121
  expect(resp.body).to eql '<html><body><h1></h1><h2>special_value</h2><h3>my_forum</h3><p>This should get data from the POSTed data</p></body></html>'
117
122
  expect(resp.status).to eql 200
118
- expect(resp.headers['Content-Type']).to eql 'text/html'
123
+ expect(resp.headers).to include('content-type' => 'text/html', 'content-length' => resp.body.length.to_s)
119
124
  end
120
125
  it 'Should match the route by posted plain text data and the posted data can be output via the template' do
121
126
  resp = http.post '/api/forums/my_forum', "dummy=\nposted_var=special_value\n", 'Content-Type' => 'text/plain'
122
127
  expect(resp.body).to eql '<html><body><h1></h1><h2>special_value</h2><h3>my_forum</h3><p>This should get data from the POSTed data</p></body></html>'
123
128
  expect(resp.status).to eql 200
124
- expect(resp.headers['Content-Type']).to eql 'text/html'
129
+ expect(resp.headers).to include('content-type' => 'text/html', 'content-length' => resp.body.length.to_s)
125
130
  end
126
131
  # it 'Should match the route by posted xml data and the posted data can be output via the template' do
127
132
  # resp = http.post "/api/forums/my_forum", '<posted_var>special_value</posted_var>', {'Content-Type' => 'application/xml'}
@@ -131,31 +136,33 @@ shared_examples_for 'a request stub' do |options = {}|
131
136
  it 'Should match the route by posted url encoded data and the posted data can be output via the template' do
132
137
  resp = http.post '/api/forums/my_forum', 'posted_var=special_value', 'Content-Type' => 'application/x-www-form-urlencoded'
133
138
  expect(resp.body).to eql '<html><body><h1></h1><h2>special_value</h2><h3>my_forum</h3><p>This should get data from the POSTed data</p></body></html>'
139
+ expect(resp.headers).to include('content-type' => 'text/html', 'content-length' => resp.body.length.to_s)
134
140
  expect(resp.status).to eql 200
135
141
  end
136
142
  it 'Should match the route by posted multipart encoded data and the posted data can be output via the template' do
137
143
  resp = http.post '/api/forums/my_forum', 'posted_var=special_value', 'Content-Type' => 'multipart/form-data'
138
144
  expect(resp.body).to eql '<html><body><h1></h1><h2>special_value</h2><h3>my_forum</h3><p>This should get data from the POSTed data</p></body></html>'
145
+ expect(resp.headers).to include('content-type' => 'text/html', 'content-length' => resp.body.length.to_s)
139
146
  expect(resp.status).to eql 200
140
147
  end
141
148
 
142
149
  it 'should stub POST requests' do
143
150
  resp = http.post('/api/forums', foo: :bar)
144
151
  expect(resp.body).to eql '{"created": true}'
145
- expect(resp.headers['Content-Type']).to eql 'application/json'
152
+ expect(resp.headers).to include('content-type' => 'application/json', 'content-length' => resp.body.length.to_s)
146
153
 
147
154
  end
148
155
 
149
156
  it 'should stub PUT requests' do
150
157
  resp = http.put('/api/forums/forum_1/my_post', foo: :bar)
151
158
  expect(resp.body).to eql '{"updated": true}'
152
- expect(resp.headers['Content-Type']).to eql 'application/json'
159
+ expect(resp.headers).to include('content-type' => 'application/json', 'content-length' => resp.body.length.to_s)
153
160
  end
154
161
 
155
162
  it 'should stub DELETE requests' do
156
163
  resp = http.delete('/api/forums/forum_1/my_post')
157
164
  expect(resp.body).to eql '{"deleted": true}'
158
- expect(resp.headers['Content-Type']).to eql 'application/json'
165
+ expect(resp.headers).to include('content-type' => 'application/json', 'content-length' => resp.body.length.to_s)
159
166
  end
160
167
  end
161
168
 
@@ -10,6 +10,7 @@ RSpec.configure do |config|
10
10
  config.before :all, :type => :integration do
11
11
  start_test_servers
12
12
  start_proxy_server
13
+ debug_me = true
13
14
  end
14
15
 
15
16
  end
@@ -1,23 +1,80 @@
1
- require 'eventmachine'
2
- require 'thin'
3
1
  require 'faraday'
4
2
  require 'agile_proxy/cli'
3
+ require 'socket'
4
+
5
+
5
6
 
6
- module Thin
7
- module Backends
8
- class TcpServer
9
- def get_port
10
- # seriously, eventmachine, how hard does getting a port have to be?
11
- Socket.unpack_sockaddr_in(EM.get_sockname(@signature)).first
12
- end
13
- end
14
- end
15
- end
16
7
 
17
8
  module AgileProxy
18
9
  module TestServer
10
+ class DummyApi
11
+ def response(env)
12
+ [200, {}, "hello!"]
13
+ end
14
+ end
15
+ class Server
16
+ attr_accessor :server_port
17
+ def initialize(world)
18
+ @world = world
19
+ at_exit do
20
+ cleanup
21
+ end
22
+ #Thin::Logging.silent = true
23
+ end
24
+ def pids
25
+ @pids ||= []
26
+ end
27
+ def cleanup
28
+ until pids.empty?
29
+ begin
30
+ Process.kill('INT', pids.pop);
31
+ rescue Errno::ESRCH
32
+ #Do nothing
33
+ end
34
+ end
35
+ end
36
+ def available_port(qty = 1)
37
+ # use Addrinfo
38
+ results = []
39
+ sockets_opened = []
40
+ while results.length < qty
41
+ socket = Socket.new(:INET, :STREAM, 0)
42
+ socket.bind(Addrinfo.tcp("127.0.0.1", 0))
43
+ port = socket.local_address.ip_port
44
+ results.push port unless results.include? port
45
+ sockets_opened.push socket
46
+ end
47
+ sockets_opened.each do |socket|
48
+ socket.close
49
+ end
50
+ results
51
+ end
52
+
53
+ def ruby
54
+ RbConfig.ruby
55
+ end
56
+ def start_test_servers
57
+ ports = available_port(3)
58
+ puts "Starting test server on #{ports[0]}"
59
+ pids.push spawn(ruby, "echo_server.rb", '--address', 'localhost', '--port', "#{ports[0]}")
60
+ puts "Starting test server on #{ports[1]}"
61
+ pids.push spawn(ruby, "echo_server.rb", '--address', 'localhost', '--port', "#{ports[1]}", '--ssl')
62
+ puts "Starting test server on #{ports[2]}"
63
+ pids.push spawn({'STATUS_CODE' => '500'}, ruby, "echo_server.rb", '--address', 'localhost', '--port', "#{ports[2]}")
64
+ @world.instance_eval do
65
+ @http_url = "http://localhost:#{ports.shift}"
66
+ @https_url = "https://localhost:#{ports.shift}"
67
+ @error_url = "http://localhost:#{ports.shift}"
68
+ @http_url_no_proxy = "http://localhost:#{server_port}"
69
+ @https_url_no_proxy = "https://localhost:#{server_port}"
70
+ end
71
+ end
72
+
73
+
74
+ end
75
+
19
76
  def initialize(rspecParams=nil)
20
- Thin::Logging.silent = true
77
+
21
78
  end
22
79
  def proxy_port
23
80
  3101
@@ -29,66 +86,20 @@ module AgileProxy
29
86
  3022
30
87
  end
31
88
 
32
- def start_test_servers
33
- q = Queue.new
34
- Thread.new do
35
- EM.run do
36
- echo = echo_app_setup
37
-
38
- http_server = start_server(echo)
39
- q.push http_server.backend.get_port
40
89
 
41
- https_server = start_server(echo, true)
42
- q.push https_server.backend.get_port
43
-
44
- echo_error = echo_app_setup(500)
45
- error_server = start_server(echo_error)
46
- q.push error_server.backend.get_port
47
- end
48
- end
49
-
50
- @http_url = "http://localhost:#{q.pop}"
51
- @https_url = "https://localhost:#{q.pop}"
52
- @error_url = "http://localhost:#{q.pop}"
53
- @http_url_no_proxy = "http://localhost:#{server_port}"
54
- @https_url_no_proxy = "https://localhost:#{server_port}"
90
+ def start_test_servers
91
+ @test_servers = Server.new(self)
92
+ @test_servers.server_port = server_port
93
+ @test_servers.start_test_servers
55
94
  end
56
95
 
57
96
  def start_proxy_server
58
97
  Thread.new do
59
98
  cli = Cli.start(['start', proxy_port.to_s, server_port.to_s, api_port.to_s, '--env', 'test'])
60
99
  end
61
- sleep 1
100
+ sleep 10
62
101
  end
63
102
 
64
- def echo_app_setup(response_code = 200)
65
- counter = 0
66
- proc do |env|
67
- req_body = env['rack.input'].read
68
- request_info = "#{env['REQUEST_METHOD']} #{env['PATH_INFO']}"
69
- res_body = request_info
70
- res_body += "\n#{req_body}" unless req_body.empty?
71
- counter += 1
72
- [
73
- response_code,
74
- { 'HTTP-X-EchoServer' => request_info,
75
- 'HTTP-X-EchoCount' => "#{counter}" },
76
- [res_body]
77
- ]
78
- end
79
- end
80
103
 
81
- def start_server(echo, ssl = false)
82
- http_server = Thin::Server.new '127.0.0.1', 0, echo
83
- if ssl
84
- http_server.ssl = true
85
- http_server.ssl_options = {
86
- private_key_file: File.expand_path('../../fixtures/test-server.key', __FILE__),
87
- cert_chain_file: File.expand_path('../../fixtures/test-server.crt', __FILE__)
88
- }
89
- end
90
- http_server.start
91
- http_server
92
- end
93
104
  end
94
105
  end
@@ -1,6 +1,17 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe AgileProxy::StubHandler do
4
+ #Mock the content length middleware as we are not testing if that works
5
+ let(:rack_content_length_class) do
6
+ Class.new do
7
+ def initialize(app)
8
+ @app = app
9
+ end
10
+ def call(env)
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
4
15
  let(:route_not_found_response) { [404, { 'X-Cascade' => 'pass' }, ['Not Found']] }
5
16
  let(:handler) { AgileProxy::StubHandler.new }
6
17
  let(:request) do
@@ -23,6 +34,7 @@ describe AgileProxy::StubHandler do
23
34
 
24
35
  before :each do
25
36
  stub_const('AgileProxy::Application', application_class)
37
+ stub_const('Rack::ContentLength', rack_content_length_class)
26
38
  allow(application_class).to receive(:where).and_return application_class
27
39
  allow(application_class).to receive(:first).and_return application
28
40
  allow(application).to receive(:request_specs).and_return request_spec_class
@@ -71,8 +83,8 @@ describe AgileProxy::StubHandler do
71
83
  it 'Should match with a get on the same domain but not with a post or a different domain' do
72
84
  expect(handler.call(request_for(url: 'http://example.com').env)).to eql([200, {}, ''])
73
85
  expect(handler.call(request_for(url: 'http://example.com/').env)).to eql([200, {}, ''])
74
- expect(handler.call(request_for(url: 'http://example.com/', method: 'POST').env)).to eql route_not_found_response
75
- expect(handler.call(request_for(url: 'http://subdomain.example.com/').env)).to eql route_not_found_response
86
+ expect(handler.call(request_for(url: 'http://example.com/', method: 'POST').env)).to contain_exactly *route_not_found_response
87
+ expect(handler.call(request_for(url: 'http://subdomain.example.com/').env)).to contain_exactly *route_not_found_response
76
88
  end
77
89
 
78
90
  end
@@ -85,10 +97,10 @@ describe AgileProxy::StubHandler do
85
97
  end
86
98
  it 'Should match with a get on the same domain but not with a post or a different domain' do
87
99
  expect(handler.call(request_for(url: 'http://example.com/index').env)).to eql([200, {}, ''])
88
- expect(handler.call(request_for(method: 'POST', url: 'http://example.com/index').env)).to eql route_not_found_response
89
- expect(handler.call(request_for(url: 'http://subdomain.example.com/index').env)).to eql route_not_found_response
90
- expect(handler.call(request_for(url: 'http://example.com/').env)).to eql route_not_found_response
91
- expect(handler.call(request_for(url: 'http://example.com').env)).to eql route_not_found_response
100
+ expect(handler.call(request_for(method: 'POST', url: 'http://example.com/index').env)).to contain_exactly *route_not_found_response
101
+ expect(handler.call(request_for(url: 'http://subdomain.example.com/index').env)).to contain_exactly *route_not_found_response
102
+ expect(handler.call(request_for(url: 'http://example.com/').env)).to contain_exactly *route_not_found_response
103
+ expect(handler.call(request_for(url: 'http://example.com').env)).to contain_exactly *route_not_found_response
92
104
  end
93
105
 
94
106
  end
@@ -103,8 +115,8 @@ describe AgileProxy::StubHandler do
103
115
  expect(handler.call(request_for(method: 'POST', url: 'http://example.com').env)).to eql([200, {}, ''])
104
116
  expect(handler.call(request_for(method: 'POST', url: 'http://example.com/').env)).to eql([200, {}, ''])
105
117
  expect(handler.call(request_for(method: 'POST', url: 'http://example.com/', headers: {'Content-Type' => 'text/plain'}, body: "a=1\nb=2\nc=3").env)).to eql([200, {}, ''])
106
- expect(handler.call(request_for(url: 'http://example.com/').env)).to eql route_not_found_response
107
- expect(handler.call(request_for(method: 'POST', url: 'http://subdomain.example.com/').env)).to eql route_not_found_response
118
+ expect(handler.call(request_for(url: 'http://example.com/').env)).to contain_exactly *route_not_found_response
119
+ expect(handler.call(request_for(method: 'POST', url: 'http://subdomain.example.com/').env)).to contain_exactly *route_not_found_response
108
120
  end
109
121
 
110
122
  end
@@ -116,10 +128,10 @@ describe AgileProxy::StubHandler do
116
128
  end
117
129
  it 'Should match with a get on the same domain but not with a post or a different domain' do
118
130
  expect(handler.call(request_for(url: 'http://example.com/users/1/index').env)).to eql([200, {}, ''])
119
- expect(handler.call(request_for(url: 'http://example.com/users/2/index').env)).to eql route_not_found_response
120
- expect(handler.call(request_for(method: 'POST', url: 'http://example.com/users/1/index').env)).to eql route_not_found_response
121
- expect(handler.call(request_for(url: 'http://example.com/users/1/').env)).to eql route_not_found_response
122
- expect(handler.call(request_for(url: 'http://example.com/users/1').env)).to eql route_not_found_response
131
+ expect(handler.call(request_for(url: 'http://example.com/users/2/index').env)).to contain_exactly *route_not_found_response
132
+ expect(handler.call(request_for(method: 'POST', url: 'http://example.com/users/1/index').env)).to contain_exactly *route_not_found_response
133
+ expect(handler.call(request_for(url: 'http://example.com/users/1/').env)).to contain_exactly *route_not_found_response
134
+ expect(handler.call(request_for(url: 'http://example.com/users/1').env)).to contain_exactly *route_not_found_response
123
135
  end
124
136
  end
125
137
  describe 'With a more complex route with conditions including query params inside a domain' do
@@ -131,10 +143,10 @@ describe AgileProxy::StubHandler do
131
143
  it 'Should match with a get on the same domain but not with a post or a different domain' do
132
144
  expect(handler.call(request_for(url: 'http://example.com/users/1/index?extra_1=extra_1&extra_2=extra_2').env)).to eql([200, {}, ''])
133
145
  expect(handler.call(request_for(url: 'http://example.com/users/1/index?some_other=2&extra_1=extra_1&extra_2=extra_2').env)).to eql([200, {}, ''])
134
- expect(handler.call(request_for(url: 'http://example.com/users/2/index').env)).to eql route_not_found_response
135
- expect(handler.call(request_for(method: 'POST', url: 'http://example.com/users/1/index').env)).to eql route_not_found_response
136
- expect(handler.call(request_for(url: 'http://example.com/users/1/').env)).to eql route_not_found_response
137
- expect(handler.call(request_for(url: 'http://example.com/users/1').env)).to eql route_not_found_response
146
+ expect(handler.call(request_for(url: 'http://example.com/users/2/index').env)).to contain_exactly *route_not_found_response
147
+ expect(handler.call(request_for(method: 'POST', url: 'http://example.com/users/1/index').env)).to contain_exactly *route_not_found_response
148
+ expect(handler.call(request_for(url: 'http://example.com/users/1/').env)).to contain_exactly *route_not_found_response
149
+ expect(handler.call(request_for(url: 'http://example.com/users/1').env)).to contain_exactly *route_not_found_response
138
150
  end
139
151
  end
140
152
 
@@ -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' }, ['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' }, ['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' }, ["Hello "]])
34
34
  end
35
35
  end
36
36
  end
@@ -2,16 +2,16 @@ require 'spec_helper'
2
2
  describe AgileProxy::Servers::Api do
3
3
  let(:subject) { AgileProxy::Servers::Api }
4
4
  let(:rack_builder_class) { Class.new }
5
- let(:rack_server_class) { Class.new }
5
+ let(:goliath_runner_class) { Class.new }
6
6
  let(:rack_static_class) { Class.new }
7
7
  let(:api_root_class) { Class.new }
8
8
  before :each do
9
- stub_const('Rack::Builder', rack_builder_class)
9
+ stub_const('Goliath::Rack::Builder', rack_builder_class)
10
10
  stub_const('Rack::Static', rack_static_class)
11
- stub_const('Rack::Server', rack_server_class)
11
+ stub_const('Goliath::Runner', goliath_runner_class)
12
12
  stub_const('AgileProxy::Api::Root', api_root_class)
13
13
  end
14
- it 'Should start a rack server when the start method is called' do
14
+ it 'Should start a goliath server when the start method is called' do
15
15
  builder_block = nil
16
16
  expect(rack_builder_class).to receive(:app) do |&blk|
17
17
  builder_block = blk
@@ -24,7 +24,11 @@ describe AgileProxy::Servers::Api do
24
24
  rack_builder_class.new.instance_eval(&blk)
25
25
 
26
26
  end
27
- expect(rack_server_class).to receive(:start)
27
+ expect_any_instance_of(goliath_runner_class).to receive(:run)
28
+ expect_any_instance_of(goliath_runner_class).to receive(:initialize).with([], nil)
29
+ expect_any_instance_of(goliath_runner_class).to receive(:address=).with('localhost')
30
+ expect_any_instance_of(goliath_runner_class).to receive(:port=).with('3020')
31
+ expect_any_instance_of(goliath_runner_class).to receive(:app=)
28
32
  subject.start('localhost', '3020')
29
33
 
30
34
  end
@@ -2,13 +2,13 @@ require 'spec_helper'
2
2
  describe AgileProxy::Servers::RequestSpecDirect do
3
3
  let(:subject) { AgileProxy::Servers::RequestSpecDirect }
4
4
  let(:rack_builder_class) { Class.new }
5
- let(:rack_server_class) { Class.new }
5
+ let(:goliath_runner_class) { Class.new }
6
6
  let(:rack_static_class) { Class.new }
7
7
  let(:stub_handler_class) { Class.new }
8
8
  before :each do
9
- stub_const('Rack::Builder', rack_builder_class)
9
+ stub_const('Goliath::Rack::Builder', rack_builder_class)
10
10
  stub_const('Rack::Static', rack_static_class)
11
- stub_const('Rack::Server', rack_server_class)
11
+ stub_const('Goliath::Runner', goliath_runner_class)
12
12
  stub_const('AgileProxy::StubHandler', stub_handler_class)
13
13
  end
14
14
  it 'Should start a rack server with a static handler when the start method is called' do
@@ -24,7 +24,11 @@ describe AgileProxy::Servers::RequestSpecDirect do
24
24
  rack_builder_class.new.instance_eval(&blk)
25
25
 
26
26
  end
27
- expect(rack_server_class).to receive(:start)
27
+ expect_any_instance_of(goliath_runner_class).to receive(:run)
28
+ expect_any_instance_of(goliath_runner_class).to receive(:initialize).with([], nil)
29
+ expect_any_instance_of(goliath_runner_class).to receive(:address=).with('localhost')
30
+ expect_any_instance_of(goliath_runner_class).to receive(:port=).with('3030')
31
+ expect_any_instance_of(goliath_runner_class).to receive(:app=)
28
32
  subject.start('localhost', '3030', ['/ui', '/images'])
29
33
 
30
34
  end
@@ -40,7 +44,11 @@ describe AgileProxy::Servers::RequestSpecDirect do
40
44
  expect_any_instance_of(rack_builder_class).to receive(:run).with(kind_of(stub_handler_class))
41
45
  rack_builder_class.new.instance_eval(&blk)
42
46
  end
43
- expect(rack_server_class).to receive(:start)
47
+ expect_any_instance_of(goliath_runner_class).to receive(:run)
48
+ expect_any_instance_of(goliath_runner_class).to receive(:initialize).with([], nil)
49
+ expect_any_instance_of(goliath_runner_class).to receive(:address=).with('localhost')
50
+ expect_any_instance_of(goliath_runner_class).to receive(:port=).with('3030')
51
+ expect_any_instance_of(goliath_runner_class).to receive(:app=)
44
52
  subject.start('localhost', '3030')
45
53
 
46
54
  end
@@ -1,30 +1,33 @@
1
1
  require 'spec_helper'
2
2
  describe AgileProxy::Servers::RequestSpec do
3
3
  let(:subject) { AgileProxy::Servers::RequestSpec }
4
- let(:event_machine_class) { Class.new }
5
- let(:socket_class) { Class.new }
6
- let(:proxy_connection_class) { Class.new }
4
+ let(:rack_builder_class) { Class.new }
5
+ let(:goliath_runner_class) { Class.new }
6
+ let(:rack_static_class) { Class.new }
7
7
  let(:request_handler_class) { Class.new }
8
+ let(:config_class) {Class.new}
8
9
  before :each do
9
- stub_const('EM', event_machine_class)
10
- stub_const('Socket', socket_class)
11
- stub_const('AgileProxy::ProxyConnection', proxy_connection_class)
10
+ stub_const('Goliath::Rack::Builder', rack_builder_class)
11
+ stub_const('Rack::Static', rack_static_class)
12
+ stub_const('Goliath::Proxy::Runner', goliath_runner_class)
12
13
  stub_const('AgileProxy::RequestHandler', request_handler_class)
14
+ stub_const('AgileProxy::Config', config_class)
13
15
  end
14
16
  context 'With started server' do
15
17
  before :each do
16
- expect(event_machine_class).to receive(:start_server).with('127.0.0.1', AgileProxy.config.proxy_port, proxy_connection_class) do |_host, _port, _connection_class, &blk|
17
- connection_instance = proxy_connection_class.new
18
- expect(connection_instance).to receive(:handler=).with(kind_of(request_handler_class))
19
- blk.call(connection_instance)
20
- end.and_return 'signature'
18
+ expect_any_instance_of(goliath_runner_class).to receive(:run)
19
+ expect_any_instance_of(goliath_runner_class).to receive(:initialize).with([], nil)
20
+ expect_any_instance_of(goliath_runner_class).to receive(:address=).with('127.0.0.1')
21
+ expect_any_instance_of(goliath_runner_class).to receive(:port=).with('3100')
22
+ expect_any_instance_of(goliath_runner_class).to receive(:app=).with(instance_of(request_handler_class))
23
+ expect(AgileProxy).to receive(:config).at_least(:once).and_return config_class.new
24
+ expect_any_instance_of(config_class).to receive(:proxy_port).at_least(:once).and_return '3100'
25
+ allow_any_instance_of(config_class).to receive(:reset)
21
26
  end
22
27
  it 'Should start the server and return the instance' do
23
28
  expect(subject.start).to be_a_kind_of(subject)
24
29
  end
25
30
  it 'Should return the port it is running on' do
26
- expect(event_machine_class).to receive(:get_sockname).with('signature').and_return 'sockname'
27
- expect(socket_class).to receive(:unpack_sockaddr_in).with('sockname').and_return ['3100']
28
31
  expect(subject.start.port).to eql '3100'
29
32
 
30
33
  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.22
4
+ version: 0.1.23
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-02 00:00:00.000000000 Z
11
+ date: 2015-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -124,26 +124,6 @@ dependencies:
124
124
  - - ">="
125
125
  - !ruby/object:Gem::Version
126
126
  version: 2.43.0
127
- - !ruby/object:Gem::Dependency
128
- name: rack
129
- requirement: !ruby/object:Gem::Requirement
130
- requirements:
131
- - - "~>"
132
- - !ruby/object:Gem::Version
133
- version: '1.6'
134
- - - ">="
135
- - !ruby/object:Gem::Version
136
- version: 1.6.0
137
- type: :development
138
- prerelease: false
139
- version_requirements: !ruby/object:Gem::Requirement
140
- requirements:
141
- - - "~>"
142
- - !ruby/object:Gem::Version
143
- version: '1.6'
144
- - - ">="
145
- - !ruby/object:Gem::Version
146
- version: 1.6.0
147
127
  - !ruby/object:Gem::Dependency
148
128
  name: guard
149
129
  requirement: !ruby/object:Gem::Requirement
@@ -204,26 +184,6 @@ dependencies:
204
184
  - - ">="
205
185
  - !ruby/object:Gem::Version
206
186
  version: 1.3.17
207
- - !ruby/object:Gem::Dependency
208
- name: airborne
209
- requirement: !ruby/object:Gem::Requirement
210
- requirements:
211
- - - "~>"
212
- - !ruby/object:Gem::Version
213
- version: '0.1'
214
- - - ">="
215
- - !ruby/object:Gem::Version
216
- version: 0.1.10
217
- type: :development
218
- prerelease: false
219
- version_requirements: !ruby/object:Gem::Requirement
220
- requirements:
221
- - - "~>"
222
- - !ruby/object:Gem::Version
223
- version: '0.1'
224
- - - ">="
225
- - !ruby/object:Gem::Version
226
- version: 0.1.10
227
187
  - !ruby/object:Gem::Dependency
228
188
  name: rest-client
229
189
  requirement: !ruby/object:Gem::Requirement
@@ -404,86 +364,6 @@ dependencies:
404
364
  - - ">="
405
365
  - !ruby/object:Gem::Version
406
366
  version: 1.1.2
407
- - !ruby/object:Gem::Dependency
408
- name: eventmachine_httpserver
409
- requirement: !ruby/object:Gem::Requirement
410
- requirements:
411
- - - "~>"
412
- - !ruby/object:Gem::Version
413
- version: '0.2'
414
- - - ">="
415
- - !ruby/object:Gem::Version
416
- version: 0.2.1
417
- type: :runtime
418
- prerelease: false
419
- version_requirements: !ruby/object:Gem::Requirement
420
- requirements:
421
- - - "~>"
422
- - !ruby/object:Gem::Version
423
- version: '0.2'
424
- - - ">="
425
- - !ruby/object:Gem::Version
426
- version: 0.2.1
427
- - !ruby/object:Gem::Dependency
428
- name: http_parser.rb
429
- requirement: !ruby/object:Gem::Requirement
430
- requirements:
431
- - - "~>"
432
- - !ruby/object:Gem::Version
433
- version: '0.6'
434
- - - ">="
435
- - !ruby/object:Gem::Version
436
- version: 0.6.0
437
- type: :runtime
438
- prerelease: false
439
- version_requirements: !ruby/object:Gem::Requirement
440
- requirements:
441
- - - "~>"
442
- - !ruby/object:Gem::Version
443
- version: '0.6'
444
- - - ">="
445
- - !ruby/object:Gem::Version
446
- version: 0.6.0
447
- - !ruby/object:Gem::Dependency
448
- name: multi_json
449
- requirement: !ruby/object:Gem::Requirement
450
- requirements:
451
- - - "~>"
452
- - !ruby/object:Gem::Version
453
- version: '1.10'
454
- - - ">="
455
- - !ruby/object:Gem::Version
456
- version: 1.10.1
457
- type: :runtime
458
- prerelease: false
459
- version_requirements: !ruby/object:Gem::Requirement
460
- requirements:
461
- - - "~>"
462
- - !ruby/object:Gem::Version
463
- version: '1.10'
464
- - - ">="
465
- - !ruby/object:Gem::Version
466
- version: 1.10.1
467
- - !ruby/object:Gem::Dependency
468
- name: thin
469
- requirement: !ruby/object:Gem::Requirement
470
- requirements:
471
- - - "~>"
472
- - !ruby/object:Gem::Version
473
- version: '1.6'
474
- - - ">="
475
- - !ruby/object:Gem::Version
476
- version: 1.6.2
477
- type: :runtime
478
- prerelease: false
479
- version_requirements: !ruby/object:Gem::Requirement
480
- requirements:
481
- - - "~>"
482
- - !ruby/object:Gem::Version
483
- version: '1.6'
484
- - - ">="
485
- - !ruby/object:Gem::Version
486
- version: 1.6.2
487
367
  - !ruby/object:Gem::Dependency
488
368
  name: grape
489
369
  requirement: !ruby/object:Gem::Requirement
@@ -619,25 +499,45 @@ dependencies:
619
499
  - !ruby/object:Gem::Version
620
500
  version: 0.19.1
621
501
  - !ruby/object:Gem::Dependency
622
- name: rack-parser
502
+ name: goliath
503
+ requirement: !ruby/object:Gem::Requirement
504
+ requirements:
505
+ - - "~>"
506
+ - !ruby/object:Gem::Version
507
+ version: '1.0'
508
+ - - ">="
509
+ - !ruby/object:Gem::Version
510
+ version: 1.0.4
511
+ type: :runtime
512
+ prerelease: false
513
+ version_requirements: !ruby/object:Gem::Requirement
514
+ requirements:
515
+ - - "~>"
516
+ - !ruby/object:Gem::Version
517
+ version: '1.0'
518
+ - - ">="
519
+ - !ruby/object:Gem::Version
520
+ version: 1.0.4
521
+ - !ruby/object:Gem::Dependency
522
+ name: goliath-proxy
623
523
  requirement: !ruby/object:Gem::Requirement
624
524
  requirements:
625
525
  - - "~>"
626
526
  - !ruby/object:Gem::Version
627
- version: '0.6'
527
+ version: '0.0'
628
528
  - - ">="
629
529
  - !ruby/object:Gem::Version
630
- version: 0.6.1
530
+ version: 0.0.1
631
531
  type: :runtime
632
532
  prerelease: false
633
533
  version_requirements: !ruby/object:Gem::Requirement
634
534
  requirements:
635
535
  - - "~>"
636
536
  - !ruby/object:Gem::Version
637
- version: '0.6'
537
+ version: '0.0'
638
538
  - - ">="
639
539
  - !ruby/object:Gem::Version
640
- version: 0.6.1
540
+ version: 0.0.1
641
541
  description: An agile, programmable, controllable proxy server for use standalone
642
542
  or as part of an integration test suite with clients for many languages
643
543
  email:
@@ -2304,6 +2204,7 @@ files:
2304
2204
  - db/migrations/20150221152500_add_record_requests_to_request_specs.rb
2305
2205
  - db/schema.rb
2306
2206
  - db/seed.rb
2207
+ - echo_server.rb
2307
2208
  - examples/README.md
2308
2209
  - examples/facebook_api.html
2309
2210
  - examples/tumblr_api.html
@@ -2379,7 +2280,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
2379
2280
  version: '0'
2380
2281
  requirements: []
2381
2282
  rubyforge_project:
2382
- rubygems_version: 2.2.2
2283
+ rubygems_version: 2.4.3
2383
2284
  signing_key:
2384
2285
  specification_version: 4
2385
2286
  summary: An agile, programmable, controllable flexible proxy server for development