experella-proxy 0.0.6 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/README.md +17 -2
- data/Rakefile +1 -0
- data/bin/experella-proxy +8 -0
- data/config/default/config.rb +2 -2
- data/dev/experella-proxy +8 -0
- data/experella-proxy.gemspec +2 -0
- data/lib/experella-proxy/backend.rb +1 -1
- data/lib/experella-proxy/backend_server.rb +11 -12
- data/lib/experella-proxy/connection.rb +23 -15
- data/lib/experella-proxy/proxy.rb +0 -1
- data/lib/experella-proxy/response.rb +22 -5
- data/lib/experella-proxy/version.rb +11 -1
- data/spec/experella-proxy/backend_server_spec.rb +33 -25
- data/spec/experella-proxy/configuration_spec.rb +0 -4
- data/spec/experella-proxy/experella-proxy_spec.rb +19 -2
- data/spec/fixtures/test_config.rb +1 -1
- data/spec/spec_helper.rb +9 -0
- metadata +20 -4
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
#Experella-Proxy
|
2
2
|
|
3
|
-
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/experella-proxy.png)](http://badge.fury.io/rb/experella-proxy)
|
4
|
+
|
5
|
+
A balancing EventMachine reverse proxy based on [em-proxy](https://github.com/igrigorik/em-proxy).
|
6
|
+
See our [presentation](http://experteer.github.io/experella-proxy/index.html) for a more detailed overview.
|
4
7
|
|
5
8
|
Configurable in pure ruby!
|
6
9
|
|
@@ -17,7 +20,7 @@ Supports:
|
|
17
20
|
Proxy uses [http_parser](https://github.com/tmm1/http_parser.rb) to parse http data and is thereby subject to the parsers restrictions
|
18
21
|
|
19
22
|
The proxy is build for low proxy to server latency and does not support persistent connections to servers. Keep that in mind
|
20
|
-
as
|
23
|
+
as it can severely influence proxy performance overhead.
|
21
24
|
|
22
25
|
It balances for every single http-request and not per client/connection.
|
23
26
|
|
@@ -205,6 +208,18 @@ Override server's run function
|
|
205
208
|
end
|
206
209
|
```
|
207
210
|
|
211
|
+
## Development
|
212
|
+
|
213
|
+
In the dev folder a development binary is provided which allows execution without installation as gem.
|
214
|
+
|
215
|
+
The test folder provides simple sinatra servers for testing/debugging which can be run with rake tasks.
|
216
|
+
|
217
|
+
Additionally you can activate simplecov code coverage analysis for specs by setting COVERAGE=true
|
218
|
+
|
219
|
+
```
|
220
|
+
$> COVERAGE=true rake spec
|
221
|
+
```
|
222
|
+
|
208
223
|
## Additional Information
|
209
224
|
|
210
225
|
+ [em-proxy](https://github.com/igrigorik/em-proxy)
|
data/Rakefile
CHANGED
data/bin/experella-proxy
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
if ENV["COVERAGE"]
|
4
|
+
#simplecov support for integration specs
|
5
|
+
require 'simplecov'
|
6
|
+
SimpleCov.start do
|
7
|
+
command_name ENV["TESTNAME"] || "integration-test"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
3
11
|
lib = File.expand_path(File.join(File.dirname(__FILE__), '../lib/'))
|
4
12
|
|
5
13
|
require 'fileutils'
|
data/config/default/config.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#Backend Server
|
2
|
-
base_backend_port=(ENV["BASE_PORT"]
|
2
|
+
base_backend_port=(ENV["BASE_PORT"] || 4000).to_i
|
3
3
|
backend1_port=base_backend_port+1
|
4
4
|
backend2_port=base_backend_port+2
|
5
5
|
|
@@ -47,7 +47,7 @@ logger.level = Logger::WARN
|
|
47
47
|
# you can add one pair per call to set_proxy(hsh)
|
48
48
|
# additionally you can activate ssl with provided private_key and cert_chain files
|
49
49
|
set_proxy(:host => "localhost", :port => base_backend_port)
|
50
|
-
set_proxy(:host => "localhost", :port => 443,
|
50
|
+
set_proxy(:host => "localhost", :port => base_backend_port + 443,
|
51
51
|
:options => {:tls => true,
|
52
52
|
:private_key_file => 'ssl/private/experella-proxy.key',
|
53
53
|
:cert_chain_file => 'ssl/certs/experella-proxy.pem'}
|
data/dev/experella-proxy
CHANGED
@@ -7,6 +7,14 @@ Bundler.setup
|
|
7
7
|
|
8
8
|
#NOTE: This is exactly the same as /bin/experella-proxy from here
|
9
9
|
|
10
|
+
if ENV["COVERAGE"]
|
11
|
+
#simplecov support for integration specs
|
12
|
+
require 'simplecov'
|
13
|
+
SimpleCov.start do
|
14
|
+
command_name ENV["TESTNAME"] || "integration-test"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
10
18
|
lib = File.expand_path(File.join(File.dirname(__FILE__), '../lib/'))
|
11
19
|
|
12
20
|
require 'fileutils'
|
data/experella-proxy.gemspec
CHANGED
@@ -28,6 +28,8 @@ Gem::Specification.new do |spec|
|
|
28
28
|
# documentation tool
|
29
29
|
spec.add_development_dependency "yard", "~> 0.8.7.3"
|
30
30
|
spec.add_development_dependency "redcarpet", "~> 2.3.0"
|
31
|
+
#code coverage
|
32
|
+
spec.add_development_dependency "simplecov", "~> 0.7.1"
|
31
33
|
|
32
34
|
spec.files = Dir["bin/*"] + Dir["dev/*"] + Dir["lib/**/*"] + Dir["config/default/**/*"]
|
33
35
|
spec.files += Dir["spec/**/*"] + Dir["test/sinatra/*"]
|
@@ -2,13 +2,13 @@ module ExperellaProxy
|
|
2
2
|
|
3
3
|
# BackendServer objects contain information on available BackendServers
|
4
4
|
#
|
5
|
-
# Accepts Requests based on Request header information
|
5
|
+
# Accepts Requests based on Request header information and it's message_matcher
|
6
6
|
#
|
7
7
|
# See {#initialize}
|
8
8
|
class BackendServer
|
9
9
|
|
10
10
|
attr_accessor :host, :port, :concurrency, :workload, :name
|
11
|
-
attr_reader :
|
11
|
+
attr_reader :message_matcher, :mangle
|
12
12
|
|
13
13
|
# Constructor of the BackendServer
|
14
14
|
#
|
@@ -39,8 +39,8 @@ module ExperellaProxy
|
|
39
39
|
# @param [Hash] options
|
40
40
|
# @option options [String] :name name used in logs and for storage. will use Host:Port if no name is specified
|
41
41
|
# @option options [String] :concurrency concurrency. will use 1 as default
|
42
|
-
# @option options [Hash|Proc] :accepts message_pattern
|
43
|
-
#
|
42
|
+
# @option options [Hash|Proc] :accepts message_pattern that will be converted to a message_matcher or an arbitrary message_matcher as proc
|
43
|
+
# Empty Hash is default
|
44
44
|
# @option options [Hash] :mangle Hash which can modify request headers. Keys get symbolized. nil is default
|
45
45
|
def initialize(host, port, options = {})
|
46
46
|
@host = host #host URL as string
|
@@ -53,7 +53,7 @@ module ExperellaProxy
|
|
53
53
|
end
|
54
54
|
@workload = 0
|
55
55
|
|
56
|
-
|
56
|
+
make_message_matcher(options[:accepts])
|
57
57
|
|
58
58
|
#mangle can be nil
|
59
59
|
@mangle = options[:mangle]
|
@@ -61,22 +61,21 @@ module ExperellaProxy
|
|
61
61
|
@mangle = @mangle.inject({}) { |memo, (k, v)| memo[k.to_sym] = v; memo } unless @mangle.nil?
|
62
62
|
end
|
63
63
|
|
64
|
-
# compares Backend servers
|
64
|
+
# compares Backend servers message_matcher to request object
|
65
65
|
#
|
66
66
|
# @param request [Request] a request object
|
67
67
|
# @return [Boolean] true if BackendServer accepts the Request, false otherwise
|
68
68
|
def accept?(request)
|
69
|
-
res=@
|
69
|
+
res=@message_matcher.call(request)
|
70
70
|
#puts "#{name} #{request.header['request_url']} #{res}"
|
71
71
|
res
|
72
72
|
end
|
73
73
|
|
74
|
-
#
|
74
|
+
# Makes a message matching block from the message_pattern.
|
75
75
|
#
|
76
|
-
# @param
|
77
|
-
|
78
|
-
|
79
|
-
@message_pattern =if obj.respond_to?(:call)
|
76
|
+
# @param obj [Hash|Proc] hash containing a message_pattern that will be converted to a message_matcher proc or an arbitrary own message_matcher
|
77
|
+
def make_message_matcher(obj)
|
78
|
+
@message_matcher =if obj.respond_to?(:call)
|
80
79
|
obj
|
81
80
|
else
|
82
81
|
#precompile message pattern keys to symbols and values to regexp objects
|
@@ -105,20 +105,10 @@ module ExperellaProxy
|
|
105
105
|
def connect_backendserver(backend)
|
106
106
|
@backend = backend
|
107
107
|
connection_manager.free_connection(self)
|
108
|
-
#mangle http
|
109
|
-
|
110
|
-
@backend.mangle.each do |k, v|
|
111
|
-
if v.respond_to?(:call)
|
112
|
-
get_request.update_header({k => v.call(get_request.header[k])})
|
113
|
-
else
|
114
|
-
get_request.update_header({k => v})
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
108
|
+
#mangle http headers
|
109
|
+
mangle
|
119
110
|
# reconstruct the request header
|
120
111
|
get_request.reconstruct_header
|
121
|
-
|
122
112
|
#special web support for unknown hosts
|
123
113
|
if @backend.name.eql?("web")
|
124
114
|
xport = get_request.header[:Host].match(/:[0-9]+/)
|
@@ -197,7 +187,7 @@ module ExperellaProxy
|
|
197
187
|
# @param data [String] opaque response data
|
198
188
|
def relay_from_backend(name, data)
|
199
189
|
log.info msec + 'on_response'.ljust(12) + " @" + @signature.to_s + " from #{name}"
|
200
|
-
log.debug msec
|
190
|
+
log.debug [msec, "#{name.inspect}", data]
|
201
191
|
@got_response = true
|
202
192
|
data = @on_response.call(name, data) if @on_response
|
203
193
|
get_request.response << data
|
@@ -449,8 +439,12 @@ module ExperellaProxy
|
|
449
439
|
|
450
440
|
# remove all hop-by-hop header fields
|
451
441
|
unless h["Connection"].nil?
|
452
|
-
h["Connection"].
|
453
|
-
h.delete(
|
442
|
+
if h["Connection"].is_a?(String)
|
443
|
+
h.delete(h["Connection"])
|
444
|
+
else
|
445
|
+
h["Connection"].each do |s|
|
446
|
+
h.delete(s)
|
447
|
+
end
|
454
448
|
end
|
455
449
|
end
|
456
450
|
HOP_HEADERS.each do |s|
|
@@ -514,6 +508,20 @@ module ExperellaProxy
|
|
514
508
|
|
515
509
|
end
|
516
510
|
|
511
|
+
# Mangles http headers based on backend specific mangle configuration
|
512
|
+
#
|
513
|
+
def mangle
|
514
|
+
unless @backend.mangle.nil?
|
515
|
+
@backend.mangle.each do |k, v|
|
516
|
+
if v.respond_to?(:call)
|
517
|
+
get_request.update_header({k => v.call(get_request.header[k])})
|
518
|
+
else
|
519
|
+
get_request.update_header({k => v})
|
520
|
+
end
|
521
|
+
end
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
517
525
|
# This method sends the first requests send_buffer to the backend server, if
|
518
526
|
# any backend is set and there is request data to dispatch
|
519
527
|
#
|
@@ -18,6 +18,8 @@ module ExperellaProxy
|
|
18
18
|
@conn = request.conn
|
19
19
|
@header = {}
|
20
20
|
@status_code = 500
|
21
|
+
@no_length = false #set true if no content-length or transfer-encoding given
|
22
|
+
@keep_parsing = true #used for special no length case
|
21
23
|
@chunked = false # if true the parsed body will be chunked
|
22
24
|
@buffer = false # default is false, so incoming data will be streamed,
|
23
25
|
# used for http1.0 clients and transfer-encoding chunked backend responses
|
@@ -35,7 +37,15 @@ module ExperellaProxy
|
|
35
37
|
# @param str [String] data as string
|
36
38
|
def <<(str)
|
37
39
|
begin
|
38
|
-
@
|
40
|
+
if @keep_parsing
|
41
|
+
offset = @response_parser << str
|
42
|
+
|
43
|
+
#edge case for message without content-length and transfer encoding
|
44
|
+
@conn.send_data str[offset..-1] unless @keep_parsing
|
45
|
+
else
|
46
|
+
@conn.send_data str
|
47
|
+
end
|
48
|
+
|
39
49
|
rescue Http::Parser::Error
|
40
50
|
log.warn ["Parser error caused by invalid response data", "@#{@conn.signature}"]
|
41
51
|
# on error unbind response_parser object, so additional data doesn't get parsed anymore
|
@@ -128,6 +138,7 @@ module ExperellaProxy
|
|
128
138
|
# if no transfer-encoding and no content-length is present, set Connection: close
|
129
139
|
if h["Content-Length"].nil?
|
130
140
|
@request.keep_alive = false
|
141
|
+
@no_length = true
|
131
142
|
@header[:Connection] = "close"
|
132
143
|
end
|
133
144
|
#chunked encoded
|
@@ -144,8 +155,12 @@ module ExperellaProxy
|
|
144
155
|
|
145
156
|
# remove all hop-by-hop header fields
|
146
157
|
unless h["Connection"].nil?
|
147
|
-
h["Connection"].
|
148
|
-
h.delete(
|
158
|
+
if h["Connection"].is_a?(String)
|
159
|
+
h.delete(h["Connection"])
|
160
|
+
else
|
161
|
+
h["Connection"].each do |s|
|
162
|
+
h.delete(s)
|
163
|
+
end
|
149
164
|
end
|
150
165
|
end
|
151
166
|
HOP_HEADERS.each do |s|
|
@@ -161,7 +176,6 @@ module ExperellaProxy
|
|
161
176
|
end
|
162
177
|
@header[:Via] = via
|
163
178
|
|
164
|
-
|
165
179
|
update_header(h)
|
166
180
|
unless @buffer
|
167
181
|
# called before any data is put into send_buffer
|
@@ -197,8 +211,11 @@ module ExperellaProxy
|
|
197
211
|
@send_buffer << body
|
198
212
|
@conn.send_data flush
|
199
213
|
end
|
200
|
-
end
|
201
214
|
|
215
|
+
if @no_length
|
216
|
+
@keep_parsing = false
|
217
|
+
end
|
218
|
+
end
|
202
219
|
end
|
203
220
|
end
|
204
221
|
end
|
@@ -1,5 +1,15 @@
|
|
1
1
|
module ExperellaProxy
|
2
2
|
# ExperellaProxy Gemversion
|
3
|
+
# 0.0.9
|
4
|
+
# * added simplecov code coverage support.
|
5
|
+
# * removed an unescaped duplicate debug log output
|
6
|
+
# 0.0.8
|
7
|
+
# * fixed a parsing bug where no data was send when backend used connection close to indicate message end
|
8
|
+
# 0.0.7
|
9
|
+
# * fixed minor issues with ruby 2.0
|
10
|
+
# * fixed a typo in default config
|
11
|
+
# * refactored mangling in own method
|
12
|
+
# * refactored message pattern and matching
|
3
13
|
# 0.0.6
|
4
14
|
# * updated homepage
|
5
15
|
# 0.0.5
|
@@ -11,5 +21,5 @@ module ExperellaProxy
|
|
11
21
|
# * added self-signed SSL certificate for TLS/HTTPS
|
12
22
|
# * added config template init functionality
|
13
23
|
#
|
14
|
-
VERSION = "0.0.
|
24
|
+
VERSION = "0.0.9"
|
15
25
|
end
|
@@ -4,15 +4,15 @@ describe ExperellaProxy::BackendServer do
|
|
4
4
|
|
5
5
|
let(:backend) {
|
6
6
|
ExperellaProxy::BackendServer.new("host", "port", {:concurrency => "2", :name => "name",
|
7
|
-
:accepts => {"Host" => "experella"},
|
7
|
+
:accepts => {"Host" => "experella", :path => "ella"},
|
8
8
|
:mangle => {"Connection" => "close"}
|
9
9
|
})
|
10
10
|
}
|
11
11
|
let(:min_backend) {
|
12
12
|
ExperellaProxy::BackendServer.new("host", "port")
|
13
13
|
}
|
14
|
-
let(:
|
15
|
-
backend.
|
14
|
+
let(:matcher) {
|
15
|
+
backend.message_matcher
|
16
16
|
}
|
17
17
|
|
18
18
|
describe "#new" do
|
@@ -39,9 +39,9 @@ describe ExperellaProxy::BackendServer do
|
|
39
39
|
min_backend.concurrency.should eql 1
|
40
40
|
end
|
41
41
|
|
42
|
-
it "has a message
|
43
|
-
backend.
|
44
|
-
min_backend.
|
42
|
+
it "has a message matcher" do
|
43
|
+
backend.message_matcher.should_not be_nil
|
44
|
+
min_backend.message_matcher.should_not be_nil
|
45
45
|
end
|
46
46
|
|
47
47
|
it "mangle should be nil" do
|
@@ -54,45 +54,53 @@ describe ExperellaProxy::BackendServer do
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
shared_examples "the message
|
57
|
+
shared_examples "the message matcher" do
|
58
58
|
|
59
59
|
it "returns a proc" do
|
60
|
-
|
60
|
+
matcher.should be_an_instance_of Proc
|
61
61
|
end
|
62
62
|
|
63
63
|
end
|
64
64
|
|
65
|
-
|
66
|
-
describe "#update_message_pattern" do
|
67
|
-
|
68
|
-
#it "adds the hash parameter to the message_pattern and overwrites values of duplicate keys" do
|
69
|
-
# backend.update_message_pattern({"Host" => "experella.de", "Connection" => "keep-alive"})
|
70
|
-
# pattern = backend.message_pattern
|
71
|
-
# pattern[:Host].should eql Regexp.new("experella.de")
|
72
|
-
# pattern[:Connection].should eql Regexp.new("keep-alive")
|
73
|
-
#end
|
74
|
-
|
75
|
-
it_should_behave_like "the message pattern"
|
76
|
-
end
|
77
|
-
|
78
65
|
describe "#accept?" do
|
79
66
|
|
80
67
|
|
81
|
-
it "returns false if request header
|
68
|
+
it "returns false if desired request header missing" do
|
82
69
|
request = ExperellaProxy::Request.new("")
|
83
70
|
request.update_header(:request_url => "/docs")
|
84
71
|
backend.accept?(request).should be_false
|
85
72
|
end
|
86
73
|
|
87
|
-
|
74
|
+
|
75
|
+
it "returns false if request headers doesn't match the message_matcher" do
|
88
76
|
request = ExperellaProxy::Request.new("")
|
89
|
-
request.update_header(:Host => "
|
77
|
+
request.update_header(:Host => "experella.com", :request_url => "/docs")
|
78
|
+
backend.accept?(request).should be_false
|
79
|
+
request.uri.update(:path => "godzilla")
|
90
80
|
backend.accept?(request).should be_false
|
91
81
|
end
|
92
82
|
|
93
|
-
it "
|
83
|
+
it "accepts a block as message matcher" do
|
84
|
+
lambdaBackend = ExperellaProxy::BackendServer.new("host", "port", {:concurrency => "2", :name => "name",
|
85
|
+
:accepts => lambda { |req|
|
86
|
+
if req.header[:Host] == "google.com"
|
87
|
+
true
|
88
|
+
else
|
89
|
+
false
|
90
|
+
end
|
91
|
+
}
|
92
|
+
})
|
94
93
|
request = ExperellaProxy::Request.new("")
|
94
|
+
request.update_header(:Host => "google.com", :request_url => "/docs")
|
95
|
+
lambdaBackend.accept?(request).should be_true
|
95
96
|
request.update_header(:Host => "experella.com", :request_url => "/docs")
|
97
|
+
lambdaBackend.accept?(request).should be_false
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns true if full message_matcher finds matches in request headers" do
|
101
|
+
request = ExperellaProxy::Request.new("")
|
102
|
+
request.update_header(:Host => "experella.com")
|
103
|
+
request.uri.update(:path => "experella")
|
96
104
|
backend.accept?(request).should be_true
|
97
105
|
end
|
98
106
|
|
@@ -16,7 +16,20 @@ describe ExperellaProxy do
|
|
16
16
|
File.expand_path("../../../bin/experella-proxy", __FILE__)
|
17
17
|
}
|
18
18
|
|
19
|
-
|
19
|
+
# static testnames send to spawned experella for simplecov
|
20
|
+
ENV_TESTNAMES = {
|
21
|
+
"should get response from the echoserver via the proxy" => "response",
|
22
|
+
"should respond with 404" => "404",
|
23
|
+
"should respond with 400 on malformed request" => "400",
|
24
|
+
"should respond with 503" => "503",
|
25
|
+
"should reuse keep-alive connections" => "keep-alive",
|
26
|
+
"should handle chunked post requests and strip invalid Content-Length" => "chunked-request",
|
27
|
+
"should rechunk and stream Transfer-Encoding chunked responses" => "chunked-response",
|
28
|
+
"should timeout inactive connections after config.timeout" => "timeout",
|
29
|
+
"should handle pipelined requests correctly" => "pipelined",
|
30
|
+
"should accept requests on all set proxy domains" => "multiproxy",
|
31
|
+
"should be able to handle post requests" => "post"
|
32
|
+
}
|
20
33
|
|
21
34
|
describe "EchoServer" do
|
22
35
|
before :each do
|
@@ -46,7 +59,10 @@ describe ExperellaProxy do
|
|
46
59
|
end
|
47
60
|
|
48
61
|
describe "Proxy" do
|
49
|
-
before :each do
|
62
|
+
before :each do |test|
|
63
|
+
if ENV["COVERAGE"]
|
64
|
+
ENV["TESTNAME"] = ENV_TESTNAMES[test.example.description]
|
65
|
+
end
|
50
66
|
@pid = spawn("ruby", "#{echo_server}", "127.0.0.10", "7654")
|
51
67
|
@pid2 = spawn("#{experella_proxy}", "run", "--", "--config=#{File.join(File.dirname(__FILE__),"/../fixtures/test_config.rb")}")
|
52
68
|
sleep(0.8) #let the server startup, specs may fail if this is set to low
|
@@ -335,6 +351,7 @@ describe ExperellaProxy do
|
|
335
351
|
req1 = conn.get({:connect_timeout => 1, :inactivity_timeout => config.timeout + 5,
|
336
352
|
:keepalive => true, :head => {"Host" => "experella.com"}})
|
337
353
|
req1.errback {
|
354
|
+
#this shouldnt happen, but when it does it should at least be because of a timeout
|
338
355
|
time = Time.now - time
|
339
356
|
time.should >= config.timeout
|
340
357
|
time.should < config.timeout + 5
|
@@ -14,7 +14,7 @@ backend( :name => "exp proxy", :host => "127.0.0.11", :port => "7655", :concurre
|
|
14
14
|
:accepts => {"Host" => "experella", "request_url" => "/(#{request_part})($|/)"}
|
15
15
|
)
|
16
16
|
|
17
|
-
backend( :name => "web", :
|
17
|
+
backend( :name => "web", :host_port => "0.0.0.0:80", :concurrency => "1000",
|
18
18
|
:accepts => {"Host" => "^((?!(experella|127)).)*$"}
|
19
19
|
)
|
20
20
|
|
data/spec/spec_helper.rb
CHANGED
@@ -8,6 +8,15 @@ require 'rubygems'
|
|
8
8
|
require 'bundler'
|
9
9
|
Bundler.setup
|
10
10
|
|
11
|
+
if ENV["COVERAGE"]
|
12
|
+
require "simplecov"
|
13
|
+
SimpleCov.start do
|
14
|
+
add_group "Proxy", "lib"
|
15
|
+
add_group "Specs", "spec"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
11
20
|
require 'pathname'
|
12
21
|
|
13
22
|
LIB_ROOT= Pathname.new(File.dirname(__FILE__) +"/../")
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: experella-proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 9
|
10
|
+
version: 0.0.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dennis-Florian Herr
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2014-
|
18
|
+
date: 2014-04-07 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -191,6 +191,22 @@ dependencies:
|
|
191
191
|
version: 2.3.0
|
192
192
|
type: :development
|
193
193
|
version_requirements: *id011
|
194
|
+
- !ruby/object:Gem::Dependency
|
195
|
+
name: simplecov
|
196
|
+
prerelease: false
|
197
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
198
|
+
none: false
|
199
|
+
requirements:
|
200
|
+
- - ~>
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
hash: 1
|
203
|
+
segments:
|
204
|
+
- 0
|
205
|
+
- 7
|
206
|
+
- 1
|
207
|
+
version: 0.7.1
|
208
|
+
type: :development
|
209
|
+
version_requirements: *id012
|
194
210
|
description: a balancing & routing proxy, see README for more details
|
195
211
|
email:
|
196
212
|
- dennis.herr@experteer.com
|