invoker 1.3.2 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ae3892c6b5eb0de5fc95cb6a52f8a0c06721bf0b
4
- data.tar.gz: 790c4b8182ce9df8c6c314965fabd7c56fca0cea
3
+ metadata.gz: d51eb067dec10fd3eefb72b5ddc023b147017a51
4
+ data.tar.gz: ff4b7b25c9558f5e718bf44b29b3e0aa42990579
5
5
  SHA512:
6
- metadata.gz: 04d9b3942cf2d1266b1dd59e457fda2d7bbb8ada95026995db4185d17496661e7944648db982997692cca5ba9a5bf62bac799d8d5c48e725a6f0c5c8f1235765
7
- data.tar.gz: 1c6fc620418949a8ee22e1404838bb1a91573efc12488b46c82356889f825c613265083db6284e58d1580225fc9d926fff27a3be1673f21a02ec6fd62f178d18
6
+ metadata.gz: 92c403e1bba997b4568dd7071c6649a7bce887e5a87d74c60158abb4c73c773362ed8310b6a73a695baf8d459758072b8f63662c3a96b3ec00d9486a5f5fa878
7
+ data.tar.gz: f6ae56c5bcba81cdb85528faa8e8f843fa324c9c08b82b61d14ba4151e9dd88eea2dfab6304925ff1398361e1dc9bef98cdf8453082c8e6d1aa64349626a15fd
data/.gitignore CHANGED
@@ -14,3 +14,4 @@ invoker_profile/
14
14
  .ruby-version
15
15
  Gemfile.lock
16
16
  .overcommit.yml
17
+ Procfile
@@ -0,0 +1,70 @@
1
+ # BASH completion function for Invoker
2
+
3
+ # source it from bashrc
4
+ # dependencies:
5
+ # 1) netcat
6
+ # 2) find
7
+
8
+ check_open_port()
9
+ {
10
+ local port=$1
11
+ if [[ $(which nc) ]]; then
12
+ local open=$(nc -z -w2 localhost $port > /dev/null; echo $?)
13
+ if [[ "$open" == "1" ]]; then
14
+ COMPREPLY=( $(compgen -W "${port}" -- ${cur}) )
15
+ else
16
+ check_open_port $(($port+1))
17
+ fi
18
+ fi
19
+ }
20
+ _invoker()
21
+ {
22
+ local cur prev opts
23
+ COMPREPLY=()
24
+ cur="${COMP_WORDS[COMP_CWORD]}"
25
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
26
+ opts="add add_http help list reload remove setup"
27
+ opts="$opts start stop tail uninstall version"
28
+
29
+ case "${prev}" in
30
+ add | add_http | list | reload | remove | setup | stop | tail \
31
+ | uninstall | version)
32
+ COMPREPLY=()
33
+ ;;
34
+ -d | --daemon | --no-daemon)
35
+ local extra_opts=("--port")
36
+ COMPREPLY=( $(compgen -W "${extra_opts}" -- ${cur}) )
37
+ ;;
38
+ --port)
39
+ # auto-suggest port
40
+ check_open_port 9000
41
+ ;;
42
+ help)
43
+ # Show opts again, but only once; don't infinitely recurse
44
+ local prev2="${COMP_WORDS[COMP_CWORD-2]}"
45
+ if [ "$prev2" == "help" ]; then
46
+ COMPREPLY=()
47
+ else
48
+ COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
49
+ fi
50
+ ;;
51
+ start)
52
+ local filename=$(find . -type f -name "*.ini")
53
+ if [[ $filename ]]; then
54
+ COMPREPLY=( $(compgen -W "${filename}" -- ${cur}) )
55
+ else
56
+ COMPREPLY=()
57
+ fi
58
+ ;;
59
+ *.ini)
60
+ local start_opts="-d --daemon --no-daemon --port"
61
+ COMPREPLY=( $(compgen -W "${start_opts}" -- ${cur}) )
62
+ ;;
63
+ invoker)
64
+ COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
65
+ ;;
66
+ esac
67
+
68
+ return 0
69
+ }
70
+ complete -F _invoker invoker
@@ -28,13 +28,13 @@ module Invoker
28
28
  Invoker::Power::Setup.uninstall
29
29
  end
30
30
 
31
- desc "start CONFIG_FILE", "Start Invoker Server"
31
+ desc "start [CONFIG_FILE]", "Start Invoker Server"
32
32
  option :port, type: :numeric, banner: "Port series to be used for starting rack servers"
33
33
  option :daemon,
34
34
  type: :boolean,
35
35
  banner: "Daemonize the server into the background",
36
36
  aliases: [:d]
37
- def start(file)
37
+ def start(file = nil)
38
38
  Invoker.setup_config_location
39
39
  port = options[:port] || 9000
40
40
  Invoker.daemonize = options[:daemon]
@@ -136,7 +136,7 @@ module Invoker
136
136
 
137
137
  class Process < Base
138
138
  include Serialization
139
- message_attributes :process_name, :shell_command, :dir, :pid
139
+ message_attributes :process_name, :shell_command, :dir, :pid, :port
140
140
  end
141
141
 
142
142
  class Remove < Base
@@ -16,8 +16,10 @@ module Invoker
16
16
  process_array = []
17
17
  Invoker.config.processes.each do |process|
18
18
  worker_attrs = {
19
- :shell_command => process.cmd, :process_name => process.label,
20
- :dir => process.dir
19
+ shell_command: process.cmd,
20
+ process_name: process.label,
21
+ dir: process.dir,
22
+ port: process.port
21
23
  }
22
24
  if worker = workers[process.label]
23
25
  worker_attrs.update(pid: worker.pid)
@@ -4,11 +4,22 @@ module Invoker
4
4
  module Parsers
5
5
  class Config
6
6
  PORT_REGEX = /\$PORT/
7
- attr_accessor :processes, :power_config
8
7
 
8
+ attr_accessor :processes, :power_config
9
+ attr_reader :filename
10
+
11
+ # initialize takes a port form cli and decrements it by 1 and sets the
12
+ # instance variable @port. This port value is used as the environment
13
+ # variable $PORT mentioned inside invoker.ini. When method pick_port gets
14
+ # fired it increments the value of port by 1, subsequently when pick_port
15
+ # again gets fired, for another command, it will again increment port
16
+ # value by 1, that way generating different ports for different commands.
9
17
  def initialize(filename, port)
10
- @filename = filename
11
- @port = port
18
+ @filename = filename || autodetect_config_file
19
+
20
+ print_message_and_abort if invalid_config_file?
21
+
22
+ @port = port - 1
12
23
  @processes = load_config
13
24
  if Invoker.can_run_balancer?
14
25
  @power_config = Invoker::Power::Config.load_config()
@@ -37,14 +48,23 @@ module Invoker
37
48
 
38
49
  private
39
50
 
51
+ def autodetect_config_file
52
+ Dir.glob("{invoker.ini,Procfile}").first
53
+ end
54
+
55
+ def invalid_config_file?
56
+ @filename.nil?
57
+ end
58
+
40
59
  def load_config
60
+ @filename = to_global_file if is_global?
61
+
41
62
  if is_ini?
42
63
  process_ini
43
64
  elsif is_procfile?
44
65
  process_procfile
45
66
  else
46
- Invoker::Logger.puts("\n Invalid config file. Invoker requires an ini or a Procfile.".color(:red))
47
- abort
67
+ print_message_and_abort
48
68
  end
49
69
  end
50
70
 
@@ -65,6 +85,11 @@ module Invoker
65
85
  end
66
86
  end
67
87
 
88
+ def print_message_and_abort
89
+ Invoker::Logger.puts("\n Invalid config file. Invoker requires an ini or a Procfile.".color(:red))
90
+ abort
91
+ end
92
+
68
93
  def process_command_from_section(section)
69
94
  if supports_subdomain?(section)
70
95
  port = pick_port(section)
@@ -128,6 +153,14 @@ module Invoker
128
153
  def is_procfile?
129
154
  @filename =~ /Procfile/
130
155
  end
156
+
157
+ def to_global_file
158
+ File.join(Invoker::Power::Config.config_dir, "#{@filename}.ini")
159
+ end
160
+
161
+ def is_global?
162
+ @filename =~ /^\w+$/ && File.exist?(to_global_file)
163
+ end
131
164
  end
132
165
  end
133
166
  end
@@ -1,6 +1,7 @@
1
1
  require 'em-proxy'
2
2
  require 'http-parser'
3
3
  require "invoker/power/http_parser"
4
+ require "invoker/power/url_rewriter"
4
5
 
5
6
  module Invoker
6
7
  module Power
@@ -22,8 +23,6 @@ module Invoker
22
23
 
23
24
  class Balancer
24
25
  attr_accessor :connection, :http_parser, :session, :protocol
25
- DEV_MATCH_REGEX = /([\w-]+)\.dev(\:\d+)?$/
26
- XIP_IO_MATCH_REGEX = /([\w-]+)\.\d+\.\d+\.\d+\.\d+\.xip\.io(\:\d+)?$/
27
26
 
28
27
  def self.run(options = {})
29
28
  start_http_proxy(InvokerHttpProxy, 'http', options)
@@ -65,7 +64,12 @@ module Invoker
65
64
  return
66
65
  end
67
66
  @session = UUID.generate()
68
- dns_check_response = select_backend_config(headers['Host'])
67
+ if !headers['Host'] || headers['Host'].empty?
68
+ return_error_page(400)
69
+ return
70
+ end
71
+
72
+ dns_check_response = UrlRewriter.new.select_backend_config(headers['Host'])
69
73
  if dns_check_response && dns_check_response.port
70
74
  connection.server(session, host: '0.0.0.0', port: dns_check_response.port)
71
75
  else
@@ -101,28 +105,8 @@ module Invoker
101
105
  connection.close_connection_after_writing if backend == session
102
106
  end
103
107
 
104
- def extract_host_from_domain(host)
105
- host.match(DEV_MATCH_REGEX) || host.match(XIP_IO_MATCH_REGEX)
106
- end
107
-
108
108
  private
109
109
 
110
- def select_backend_config(host)
111
- matching_string = extract_host_from_domain(host)
112
- return nil unless matching_string
113
- if selected_app = matching_string[1]
114
- dns_check(process_name: selected_app)
115
- else
116
- nil
117
- end
118
- end
119
-
120
- def dns_check(dns_args)
121
- Invoker::IPC::UnixClient.send_command("dns_check", dns_args) do |dns_response|
122
- dns_response
123
- end
124
- end
125
-
126
110
  def return_error_page(status)
127
111
  http_response = Invoker::Power::HttpResponse.new()
128
112
  http_response.status = status
@@ -16,6 +16,12 @@ module Invoker
16
16
  when "Archlinux"
17
17
  require "invoker/power/setup/distro/arch"
18
18
  Arch.new
19
+ when "Debian"
20
+ require "invoker/power/setup/distro/debian"
21
+ Debian.new
22
+ when "LinuxMint"
23
+ require "invoker/power/setup/distro/mint"
24
+ Mint.new
19
25
  else
20
26
  raise "Your selected distro is not supported by Invoker"
21
27
  end
@@ -0,0 +1,11 @@
1
+ module Invoker
2
+ module Power
3
+ module Distro
4
+ class Debian < Base
5
+ def install_required_software
6
+ system("apt-get --assume-yes install dnsmasq rinetd")
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ require "invoker/power/setup/distro/ubuntu"
2
+
3
+ module Invoker
4
+ module Power
5
+ module Distro
6
+ class Mint < Ubuntu
7
+ end
8
+ end
9
+ end
10
+ end
@@ -1,10 +1,9 @@
1
+ require "invoker/power/setup/distro/debian"
2
+
1
3
  module Invoker
2
4
  module Power
3
5
  module Distro
4
- class Ubuntu < Base
5
- def install_required_software
6
- system("apt-get --assume-yes install dnsmasq rinetd")
7
- end
6
+ class Ubuntu < Debian
8
7
  end
9
8
  end
10
9
  end
@@ -0,0 +1,40 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Invoker</title>
6
+ <style>
7
+ body {
8
+ margin: 0;
9
+ padding: 0;
10
+ background: #fff;
11
+ line-height: 18px;
12
+ }
13
+ div.page {
14
+ padding: 36px 90px;
15
+ }
16
+ h1, h2, p, li {
17
+ font-family: Helvetica, sans-serif;
18
+ font-size: 13px;
19
+ }
20
+ h1 {
21
+ line-height: 45px;
22
+ font-size: 36px;
23
+ margin: 0;
24
+ }
25
+ h2 {
26
+ line-height: 27px;
27
+ font-size: 18px;
28
+ font-weight: normal;
29
+ margin: 0;
30
+ }
31
+ </style>
32
+ </head>
33
+ <body class="">
34
+ <div class="page">
35
+ <h1>Bad request</h1>
36
+ <hr>
37
+ <h2>Invoker couldn't understand the request</h2>
38
+ </div>
39
+ </body>
40
+ </html>
@@ -0,0 +1,37 @@
1
+ module Invoker
2
+ module Power
3
+ class UrlRewriter
4
+ DEV_MATCH_REGEX = [/([\w.-]+)\.dev(\:\d+)?$/, /([\w-]+)\.dev(\:\d+)?$/]
5
+
6
+ def select_backend_config(complete_path)
7
+ possible_matches = extract_host_from_domain(complete_path)
8
+ exact_match = nil
9
+ possible_matches.each do |match|
10
+ if match
11
+ exact_match = dns_check(process_name: match)
12
+ break if exact_match.port
13
+ end
14
+ end
15
+ exact_match
16
+ end
17
+
18
+ def extract_host_from_domain(complete_path)
19
+ matching_strings = []
20
+ DEV_MATCH_REGEX.map do |regexp|
21
+ if (match_result = complete_path.match(regexp))
22
+ matching_strings << match_result[1]
23
+ end
24
+ end
25
+ matching_strings.uniq
26
+ end
27
+
28
+ private
29
+
30
+ def dns_check(dns_args)
31
+ Invoker::IPC::UnixClient.send_command("dns_check", dns_args) do |dns_response|
32
+ dns_response
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -26,6 +26,7 @@ module Invoker
26
26
 
27
27
  hash_with_colors['dir'] = colored_string(process.dir, color)
28
28
  hash_with_colors['pid'] = colored_string(process.pid || 'Not Running', color)
29
+ hash_with_colors['port'] = colored_string(process.port, color)
29
30
  hash_with_colors['shell_command'] = colored_string(process.shell_command, color)
30
31
  hash_with_colors['process_name'] = colored_string(process.process_name, color)
31
32
  hash_with_colors
@@ -43,5 +43,5 @@ module Invoker
43
43
  Version.new(next_splits.join('.'))
44
44
  end
45
45
  end
46
- VERSION = "1.3.2"
46
+ VERSION = "1.4.0"
47
47
  end
@@ -79,13 +79,13 @@ command = ls
79
79
  config = Invoker::Parsers::Config.new(file.path, 9000)
80
80
  command1 = config.processes.first
81
81
 
82
- expect(command1.port).to eq(9001)
83
- expect(command1.cmd).to match(/9001/)
82
+ expect(command1.port).to eq(9000)
83
+ expect(command1.cmd).to match(/9000/)
84
84
 
85
85
  command2 = config.processes[1]
86
86
 
87
- expect(command2.port).to eq(9002)
88
- expect(command2.cmd).to match(/9002/)
87
+ expect(command2.port).to eq(9001)
88
+ expect(command2.cmd).to match(/9001/)
89
89
 
90
90
  command2 = config.processes[2]
91
91
 
@@ -118,8 +118,8 @@ command = ls
118
118
  config = Invoker::Parsers::Config.new(file.path, 9000)
119
119
  command1 = config.processes.first
120
120
 
121
- expect(command1.port).to eq(9001)
122
- expect(command1.cmd).to match(/9001/)
121
+ expect(command1.port).to eq(9000)
122
+ expect(command1.cmd).to match(/9000/)
123
123
 
124
124
  command2 = config.processes[1]
125
125
 
@@ -162,7 +162,7 @@ web: bundle exec rails s -p $PORT
162
162
  config = Invoker::Parsers::Config.new("/tmp/Procfile", 9000)
163
163
  command1 = config.processes.first
164
164
 
165
- expect(command1.port).to eq(9001)
165
+ expect(command1.port).to eq(9000)
166
166
  expect(command1.cmd).to match(/bundle exec rails/)
167
167
  ensure
168
168
  File.delete("/tmp/Procfile")
@@ -183,7 +183,7 @@ web: bundle exec rails s -p $PORT
183
183
 
184
184
  expect(dns_cache.dns_data).to_not be_empty
185
185
  expect(dns_cache.dns_data['web']).to_not be_empty
186
- expect(dns_cache.dns_data['web']['port']).to eql 9001
186
+ expect(dns_cache.dns_data['web']['port']).to eql 9000
187
187
  ensure
188
188
  File.delete("/tmp/Procfile")
189
189
  end
@@ -223,4 +223,99 @@ command = bundle exec rails s -p $PORT
223
223
  end
224
224
  end
225
225
  end
226
+
227
+ describe "global config file" do
228
+ it "should use global config file if available" do
229
+ begin
230
+ filename = "#{Invoker::Power::Config.config_dir}/foo.ini"
231
+ file = File.open(filename, "w")
232
+ config_data =<<-EOD
233
+ [try_sleep]
234
+ directory = /tmp
235
+ command = ruby try_sleep.rb
236
+ EOD
237
+ file.write(config_data)
238
+ file.close
239
+ config = Invoker::Parsers::Config.new("foo", 9000)
240
+ expect(config.filename).to eql(filename)
241
+ ensure
242
+ File.unlink(filename)
243
+ end
244
+ end
245
+ end
246
+
247
+ describe "config file autodetection" do
248
+ context "no config file given" do
249
+
250
+ def create_invoker_ini
251
+ file = File.open("invoker.ini", "w")
252
+ config_data =<<-EOD
253
+ [some_process]
254
+ command = some_command
255
+ EOD
256
+ file.write(config_data)
257
+ file.close
258
+
259
+ file
260
+ end
261
+
262
+ def create_procfile
263
+ file = File.open("Procfile", "w")
264
+ config_data =<<-EOD
265
+ some_other_process: some_other_command
266
+ EOD
267
+ file.write(config_data)
268
+ file.close
269
+
270
+ file
271
+ end
272
+
273
+ context "directory has invoker.ini" do
274
+ it "autodetects invoker.ini" do
275
+ begin
276
+ file = create_invoker_ini
277
+
278
+ config = Invoker::Parsers::Config.new(nil, 9000)
279
+ expect(config.process("some_process").cmd).to eq("some_command")
280
+ ensure
281
+ File.delete(file)
282
+ end
283
+ end
284
+ end
285
+
286
+ context "directory has Procfile" do
287
+ it "autodetects Procfile" do
288
+ begin
289
+ file = create_procfile
290
+
291
+ config = Invoker::Parsers::Config.new(nil, 9000)
292
+ expect(config.process("some_other_process").cmd).to eq("some_other_command")
293
+ ensure
294
+ File.delete(file)
295
+ end
296
+ end
297
+ end
298
+
299
+ context "directory has both invoker.ini and Procfile" do
300
+ it "prioritizes invoker.ini" do
301
+ begin
302
+ invoker_ini = create_invoker_ini
303
+ procfile = create_procfile
304
+
305
+ config = Invoker::Parsers::Config.new(nil, 9000)
306
+ expect(config.process("some_process").cmd).to eq("some_command")
307
+ ensure
308
+ File.delete(invoker_ini)
309
+ File.delete(procfile)
310
+ end
311
+ end
312
+ end
313
+
314
+ context "directory doesn't have invoker.ini or Procfile" do
315
+ it "aborts" do
316
+ expect { Invoker::Parsers::Config.new(nil, 9000) }.to raise_error(SystemExit)
317
+ end
318
+ end
319
+ end
320
+ end
226
321
  end
@@ -4,8 +4,10 @@ describe MM::ListResponse do
4
4
  context "serializing a response" do
5
5
  let(:process_array) do
6
6
  [
7
- { shell_command: 'foo', process_name: 'foo', dir: '/tmp', pid: 100 },
8
- { shell_command: 'bar', process_name: 'bar', dir: '/tmp', pid: 200 }
7
+ { shell_command: 'foo', process_name: 'foo', dir: '/tmp', pid: 100,
8
+ port: 9000 },
9
+ { shell_command: 'bar', process_name: 'bar', dir: '/tmp', pid: 200,
10
+ port: 9001 }
9
11
  ]
10
12
  end
11
13
 
@@ -19,8 +19,10 @@ describe Invoker::IPC::Message do
19
19
  context "for nested messages" do
20
20
  let(:process_array) do
21
21
  [
22
- { shell_command: 'foo', process_name: 'foo', dir: '/tmp', pid: 100 },
23
- { shell_command: 'bar', process_name: 'bar', dir: '/tmp', pid: 200 }
22
+ { shell_command: 'foo', process_name: 'foo', dir: '/tmp', pid: 100,
23
+ port: 9000 },
24
+ { shell_command: 'bar', process_name: 'bar', dir: '/tmp', pid: 200,
25
+ port: 9001 }
24
26
  ]
25
27
  end
26
28
 
@@ -33,8 +35,10 @@ describe Invoker::IPC::Message do
33
35
 
34
36
  it "should report not equal for different objects" do
35
37
  another_process_array = [
36
- { shell_command: 'baz', process_name: 'foo', dir: '/tmp', pid: 100 },
37
- { shell_command: 'bar', process_name: 'bar', dir: '/tmp', pid: 200 }
38
+ { shell_command: 'baz', process_name: 'foo', dir: '/tmp', pid: 100,
39
+ port: 9000 },
40
+ { shell_command: 'bar', process_name: 'bar', dir: '/tmp', pid: 200,
41
+ port: 9001 }
38
42
  ]
39
43
 
40
44
  m2 = MM::ListResponse.new(processes: another_process_array)
@@ -2,74 +2,21 @@ require 'spec_helper'
2
2
 
3
3
  describe Invoker::Power::Balancer do
4
4
  before do
5
- @balancer = Invoker::Power::Balancer.new(mock("connection"), "http")
5
+ @http_connection = mock("connection")
6
+ @balancer = Invoker::Power::Balancer.new(@http_connection, "http")
6
7
  end
7
8
 
8
- context "matching domain part of incoming request" do
9
- it "should do foo.dev match" do
10
- match = @balancer.extract_host_from_domain("foo.dev")
11
- expect(match).to_not be_nil
12
-
13
- matching_string = match[1]
14
- expect(matching_string).to eq("foo")
15
- end
16
-
17
- it "should match foo.dev:1080" do
18
- match = @balancer.extract_host_from_domain("foo.dev:1080")
19
- expect(match).to_not be_nil
20
-
21
- matching_string = match[1]
22
- expect(matching_string).to eq("foo")
9
+ context "when Host field is missing in the request" do
10
+ it "should return 400 as response when Host is missing" do
11
+ headers = {}
12
+ @http_connection.expects(:send_data).with() { |value| value =~ /400 Bad Request/i }
13
+ @balancer.headers_received(headers)
23
14
  end
24
15
 
25
- it "should match emacs.bar.dev" do
26
- match = @balancer.extract_host_from_domain("emacs.bar.dev")
27
- expect(match).to_not be_nil
28
-
29
- matching_string = match[1]
30
- expect(matching_string).to eq("bar")
31
- end
32
-
33
- it "should match hello-world.dev" do
34
- match = @balancer.extract_host_from_domain("hello-world.dev")
35
- expect(match).to_not be_nil
36
-
37
- matching_string = match[1]
38
- expect(matching_string).to eq("hello-world")
39
- end
40
- end
41
-
42
- context "matching domain part of incoming request using xip.io" do
43
- it "should do foo.10.0.0.1.xip.io match" do
44
- match = @balancer.extract_host_from_domain("foo.10.0.0.1.xip.io")
45
- expect(match).to_not be_nil
46
-
47
- matching_string = match[1]
48
- expect(matching_string).to eq("foo")
49
- end
50
-
51
- it "should match foo.10.0.0.1.xip.io:1080" do
52
- match = @balancer.extract_host_from_domain("foo.10.0.0.1.xip.io:1080")
53
- expect(match).to_not be_nil
54
-
55
- matching_string = match[1]
56
- expect(matching_string).to eq("foo")
57
- end
58
-
59
- it "should match emacs.bar.10.0.0.1.xip.io" do
60
- match = @balancer.extract_host_from_domain("emacs.bar.10.0.0.1.xip.io")
61
- expect(match).to_not be_nil
62
-
63
- matching_string = match[1]
64
- expect(matching_string).to eq("bar")
65
- end
66
-
67
- it "should match hello-world.10.0.0.1.xip.io" do
68
- match = @balancer.extract_host_from_domain("hello-world.10.0.0.1.xip.io")
69
- expect(match).to_not be_nil
70
-
71
- matching_string = match[1]
72
- expect(matching_string).to eq("hello-world")
16
+ it "should return 400 as response when Host is empty" do
17
+ headers = { 'Host' => '' }
18
+ @http_connection.expects(:send_data).with() { |value| value =~ /400 Bad Request/i }
19
+ @balancer.headers_received(headers)
73
20
  end
74
21
  end
75
22
  end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Invoker::Power::UrlRewriter do
4
+ let(:rewriter) { Invoker::Power::UrlRewriter.new }
5
+
6
+ context "matching domain part of incoming request" do
7
+ it "should do foo.dev match" do
8
+ match = rewriter.extract_host_from_domain("foo.dev")
9
+ expect(match).to_not be_empty
10
+
11
+ matching_string = match[0]
12
+ expect(matching_string).to eq("foo")
13
+ end
14
+
15
+ it "should match foo.dev:1080" do
16
+ match = rewriter.extract_host_from_domain("foo.dev:1080")
17
+ expect(match).to_not be_empty
18
+
19
+ matching_string = match[0]
20
+ expect(matching_string).to eq("foo")
21
+ end
22
+
23
+ it "should match emacs.bar.dev" do
24
+ match = rewriter.extract_host_from_domain("emacs.bar.dev")
25
+ expect(match).to_not be_empty
26
+
27
+ expect(match[0]).to eq("emacs.bar")
28
+ expect(match[1]).to eq("bar")
29
+ end
30
+
31
+ it "should match hello-world.dev" do
32
+ match = rewriter.extract_host_from_domain("hello-world.dev")
33
+ expect(match).to_not be_nil
34
+
35
+ expect(match[0]).to eq("hello-world")
36
+ end
37
+ end
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: invoker
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hemant Kumar
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-12-26 00:00:00.000000000 Z
12
+ date: 2015-11-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -224,6 +224,7 @@ files:
224
224
  - Rakefile
225
225
  - TODO
226
226
  - bin/invoker
227
+ - contrib/completion/invoker-completion.bash
227
228
  - contrib/completion/invoker-completion.zsh
228
229
  - invoker.gemspec
229
230
  - lib/invoker.rb
@@ -269,12 +270,16 @@ files:
269
270
  - lib/invoker/power/setup.rb
270
271
  - lib/invoker/power/setup/distro/arch.rb
271
272
  - lib/invoker/power/setup/distro/base.rb
273
+ - lib/invoker/power/setup/distro/debian.rb
274
+ - lib/invoker/power/setup/distro/mint.rb
272
275
  - lib/invoker/power/setup/distro/redhat.rb
273
276
  - lib/invoker/power/setup/distro/ubuntu.rb
274
277
  - lib/invoker/power/setup/linux_setup.rb
275
278
  - lib/invoker/power/setup/osx_setup.rb
279
+ - lib/invoker/power/templates/400.html
276
280
  - lib/invoker/power/templates/404.html
277
281
  - lib/invoker/power/templates/503.html
282
+ - lib/invoker/power/url_rewriter.rb
278
283
  - lib/invoker/process_manager.rb
279
284
  - lib/invoker/process_printer.rb
280
285
  - lib/invoker/reactor.rb
@@ -304,6 +309,7 @@ files:
304
309
  - spec/invoker/power/setup/linux_setup_spec.rb
305
310
  - spec/invoker/power/setup/osx_setup_spec.rb
306
311
  - spec/invoker/power/setup_spec.rb
312
+ - spec/invoker/power/url_rewriter_spec.rb
307
313
  - spec/invoker/process_manager_spec.rb
308
314
  - spec/invoker/reactor_spec.rb
309
315
  - spec/spec_helper.rb
@@ -328,7 +334,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
328
334
  version: '0'
329
335
  requirements: []
330
336
  rubyforge_project:
331
- rubygems_version: 2.2.2
337
+ rubygems_version: 2.4.5.1
332
338
  signing_key:
333
339
  specification_version: 4
334
340
  summary: Something small for Process management
@@ -356,8 +362,8 @@ test_files:
356
362
  - spec/invoker/power/setup/linux_setup_spec.rb
357
363
  - spec/invoker/power/setup/osx_setup_spec.rb
358
364
  - spec/invoker/power/setup_spec.rb
365
+ - spec/invoker/power/url_rewriter_spec.rb
359
366
  - spec/invoker/process_manager_spec.rb
360
367
  - spec/invoker/reactor_spec.rb
361
368
  - spec/spec_helper.rb
362
369
  - spec/support/mock_setup_file.rb
363
- has_rdoc: